Hacer un convertidor de lista numérica

20

No odies cuando quieras copiar y pegar una lista de números (vector, matriz ...), de un programa a otro, pero el formato en el que tienes los números no coincide con el formato en el que lo necesitas ?

Por ejemplo, en MATLAB puede tener una lista separada por espacios como esta:

[1 2 3 4 5]    (you can also have it comma separated, but that's not the point)

En Python, necesitaría insertar comas para hacer que esa lista sea una entrada válida, por lo que tendría que convertirla a

[1, 2, 3, 4, 5]

para que funcione En C ++ es posible que desee algo como:

{16,2,77,29}

y así.

Para simplificar la vida de todos, creemos un convertidor de listas, que tome una lista en cualquier formato * y genere una lista en otro formato especificado.

Los corchetes válidos son:

[list]
{list}
(list)
<list>
list      (no surrounding brackets)

Los delimitadores válidos son:

a,b,c
a;b;c
a b c
a,  b,  c       <-- Several spaces. Must only be supported as input.
a;     b; c     <-- Several spaces. Must only be supported as input.
a   b   c       <-- Several spaces. Must only be supported as input. 

Nota, la entrada puede tener cualquier número de espacios entre los números, pero la salida puede optar por tener cero espacios (si ,o ;se utiliza como delimitador), o un solo espacio (si es el espacio delimitado).

Además de la lista de entrada, habrá una cadena (o dos caracteres) que define el formato de salida. La cadena de formato será primero ser el tipo corchete de apertura (solamente), [, (, <, {o (el último es un único espacio utiliza cuando no hay soporte circundante). El tipo de paréntesis será seguido por el tipo de delimitador ,, ;o (el último es un espacio único). Los dos caracteres de formato de entrada deben tomarse como un solo argumento (cadena o dos caracteres consecutivos) en el orden descrito anteriormente.

Algunos ejemplos de cadenas de formato:

[,    <-- Output format:   [a,b,c]
{;    <-- Output format:   {a;b;c}
      <-- Two spaces, output list has format:   a b c   

Reglas:

  • La salida no puede tener espacios iniciales
  • La salida puede tener espacios finales y una nueva línea
    • La salida solo debe ser la lista de números, no ans =similar
  • La entrada será una lista de números enteros o decimales (tanto positivos como negativos (y cero)), y una cadena de dos caracteres
    • Si la entrada consta de solo enteros, la lista de salida debe tener solo enteros. Si la lista de entrada consta de números enteros y decimales, todos los números de salida pueden ser números decimales. (Es opcional mantener los enteros como enteros)
    • El número máximo de dígitos después del punto decimal que debe admitirse es 3.
    • La entrada será dos argumentos. Es decir, los números están en un argumento, y la cadena de formato es un argumento único.
  • El código puede ser un programa o función
  • La entrada puede ser argumento de función o STDIN

Algunos ejemplos:

1 2 3 4
[,
[1,2,3,4]

<1;  2;  3>
 ;    <-- Space + semicolon
1;2;3
not valid:  1.000;2.000;3.000   (Input is only integers => Output must be integers)

{-1.3, 3.4, 4, 5.55555555}
[,
[-1.300,3.400,4.000,5.556]  (5.555 is also valid. Rounding is optional)
also valid: [-1.3,3.4,4,5.55555555]

El código más corto en bytes gana. Como siempre, el ganador será seleccionado una semana a partir del día en que se publicó el desafío. Las respuestas que se publican más tarde aún pueden ganar si son más cortas que el ganador actual.


Tabla de clasificación

El Fragmento de pila al final de esta publicación genera el catálogo a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.

Para asegurarse de que su respuesta se muestre, comience con un título, utilizando la siguiente plantilla de Markdown:

## Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

## Perl, 43 + 2 (-p flag) = 45 bytes

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

Stewie Griffin
fuente
¿Se permiten los espacios en blanco iniciales y finales?
overactor
@overactor, mira las dos primeras reglas. El espacio en blanco inicial no está bien, el final está bien.
Stewie Griffin
¿Podemos tomar la entrada en el orden opuesto? (delimitadores primero, lista segunda)
Martin Ender
@ MartinBüttner, sí. No se especifica que debe ser la lista primero, por lo que puede elegir.
Stewie Griffin
J usa _para denotar elementos negativos. :(
Zgarb

Respuestas:

1

CJam, 27 bytes

l)l_5ms`-SerS%*\S-_o_'(#(f-

Pruébalo aquí

Explicación

l      e# Read the format string.
)      e# Extract the separator.
l_     e# Read the list.
5ms`   e# Get a string that contains -.0123456789.
-      e# Get the characters in the list that are not in the string.
Ser    e# Replace those characters with spaces.
S%     e# Split by those characters, with duplicates removed.
*      e# Join with the separator.
\S-    e# Remove spaces (if any) from the left bracket.
_o     e# Output a copy of that character before the stack.
_'(#   e# Find '( in the left bracket string.
(      e# Get -1 if '( is the first character, and -2 if it doesn't exist.
f-     e# Subtract the number from every character in the left bracket string,
          making a right bracket.
jimmy23013
fuente
8

JavaScript (ES6), 75 82

Como una función anónima

Editar: 2 bytes guardados thx @ user81655 (y 5 más solo revisándolo)

(l,[a,b])=>a.trim()+l.match(/[-\d.]+/g).join(b)+']})> '['[{(< '.indexOf(a)]

Fragmento de prueba

F=(l,[a,b])=>a.trim()+l.match(/[-\d.]+/g).join(b)+']})> '['[{(< '.indexOf(a)]

// Test
console.log=x=>O.innerHTML+=x+'\n'
// default test suite
t=[['1 2 3 4','[,'],['<1;  2;  3>',' ;'],['{-1.3, 3.4, 4, 5.55555555}','[,']]
t.forEach(t=>console.log(t[0]+' *'+t[1]+'* '+F(t[0],t[1])))
function test() { console.log(P1.value+' *'+P2.value+'* '+F(P1.value,P2.value)) }
#P1 { width: 10em }
#P2 { width: 2em }
P1<input id=P1>
P2<input id=P2>
<button onclick="test()">-></button>
<pre id=O></pre>

edc65
fuente
6

CJam, 35 34 bytes

l(S-l"{[<(,}]>);":BSerS%@*1$B5/~er

Pruébalo aquí.

Espera el formato en la primera línea y la lista en la segunda.

Explicación

l   e# Read the format line.
(   e# Pull off the first character, which is the opening bracket.
S-  e# Set complement with a space, which leaves brackets unchanged and turns a space
    e# into an empty string.
l   e# Read the list.
"{[<(,}]>);":B
    e# Push this string which contains all the characters in the list we want to ignore.
Ser e# Replace each occurrence of one of them with a space.
S%  e# Split the string around runs of spaces, to get the numbers.
@   e# Pull up the the delimiter string.
*   e# Join the numbers in the list with that character.
1$  e# Copy the opening bracket (which may be an empty string).
B5/ e# Push B again and split it into chunks of 5: ["{[<(," "}]>);"]
~   e# Unwrap the array to leave both chunks on the stack.
er  e# Use them for transliteration, to turn the opening bracket into a closing one.
Martin Ender
fuente
5

Pyth, 33 bytes

rjjezrXwJ"<>[]  {}(),;"d7@c6JChz6

Pruébelo en línea: Demostración o conjunto de pruebas

Explicación:

J"<>[]  {}(),;"  assign this string to J

rjjezrXwJd7@c6JChz6   implicit: z = first input string, e.g. "[;"
       w              read another string from input (the list of numbers)
      X Jd            replace every char of ^ that appears in J with a space
     r    7           parse ^ (the string of numbers and spaces) into a list
  jez                 put z[1] (the separator symbol) between the numbers
            c6J       split J into 6 pieces ["<>", "[]", "  ", "{}", "()", ",;"]
               Chz    ASCII-value of z[0] (opening bracket symbol)
           @          take the correspondent (mod 6) brackets from the list
 j                    and put the numbers between these brackets
r                 7   remove leading and trailing spaces
Jakube
fuente
¿Puedes agregar una explicación de cómo funciona?
Shelvacu
1
@Shel Aquí estás.
Jakube
5

PowerShell, 108 100 95 85 Bytes

$i,$z=$args;($z[0]+($i-split'[^\d.-]+'-ne''-join$z[1])+' }) >]'[($z[0]-32)%6]).Trim()

(ver historial de revisiones para versiones anteriores)

Golfed otros 15 bytes mediante la eliminación $by $slas variables y cambiando parens en la cadena interior.

Esto toma la entrada como dos cadenas y las almacena en , $iy $zluego construimos una nueva cadena de salida. El parente interno -splits $icon una expresión regular para seleccionar solo dígitos numéricos, luego se -joinvuelve a juntar con el delimitador solicitado. Concatenamos eso con el primer carácter de la entrada del delimitador (por ejemplo, [) y lo cerramos con indexación en una cadena basada en el valor ASCII del primer carácter y algunos trucos de formulación. El exterior .Trim()elimina los espacios iniciales o finales.

AdmBorkBork
fuente
Creo que podría reemplazar su expresión de corchete de cierre "]})>"["[{(< ".IndexOf($b[0])]con algo así ' }) >]'[($b[0]-32)%6]. El ($b[0]-32)%6le da 0,2,4,5,1para abrir caracteres de corchetes, que puede usar para indexar en la cadena de corchetes de cierre ' }) >]'. Puede haber una "fórmula" más corta, pero esto parece lo suficientemente bueno.
Danko Durbić
@ DankoDurbić Excelente! Estaba tratando de encontrar algunas matemáticas para seleccionar el carácter de salida correcto basado en los valores ASCII, pero no pude encontrar la fórmula correcta. Seguí tropezando al ()estar uno al lado del otro, pero los otros paréntesis tienen un carácter intermedio, así que seguí con la indexación. ¡Gracias!
AdmBorkBork
Usar en String.Replace()lugar del -replaceoperador le compraría otros 2 bytes (no es necesario escapar o definir una clase de caracteres con [])
Mathias R. Jessen
@ MathiasR.Jessen A menos que me falte algo aquí, .Replace('[]{}()<>;,',' ')no capturará caracteres individuales sino que intentará hacer coincidir el todo simbólico, que no existe. Necesitaríamos usar Regex.Replace , que implica una [regex]::llamada .NET y, en cambio, alargaría el código.
AdmBorkBork
@TessellatingHeckler ¡Gracias! Golfé otro byte usando en -ne''lugar de |?{$_}.
AdmBorkBork
4

Python 2, 96 bytes

import re
lambda(a,(b,c)):(b+c.join(re.findall('[-\d\.]+',a))+'])>} '['[(<{ '.index(b)]).strip()

Llamar como:

f(('{-1.3, 3.4, ,4, 5.55555555}','[,'))

Salida:

[-1.3,3.4,4,5.55555555]
TFeld
fuente
2

JavaScript (ES6), 82 92 116 92 bytes

(a,b)=>(c=a.match(/-?\d+(\.\d+)?/g).join(b[1]),d=b[0],d<"'"?c:d+c+"]}>)"["[{<(".indexOf(d)])

Una función anónima, ejecútela así

((a,b)=>(c=a.match(/-?\d+(\.\d+)?/g).join(b[1]),d=b[0],d<"'"?c:d+c+"]}>)"["[{<(".indexOf(d)]))("{1;  2;3;   4}","<;")

Esto probablemente se puede jugar mucho más golf ..

Sin golf

(a,b)=>(                             // "{1;  2;3;   4}", "<;"
    c=a.match(/-?\d+(\.\d+)?/g)      // regex to match decimals
    .join(b[1]),                     // c -> "1;2;3;4"
    d=b[0],                          // d -> "<"
    d<"'" ?                          // if d is smaller than ' then ...
        c :                          // return just "1;2;3;4"
        d + c +                      // "<" + "1;2;3;4" + ...
        "]}>)" [ "[{<(".indexOf(d) ] // "]}>)"[2] -> ">"
)
Bassdrop Cumberwubwubwub
fuente
Creo que tienes que tomar un como una cadena, no una lista.
overactor
Totalmente mal entendido esto: The input will be a list of integer or decimal numbers (both positive and negative (and zero)), and a string of two characters. Solucionado, gracias
Bassdrop Cumberwubwubwub
2

Mathematica, 108 bytes

Mathematica es generalmente torpe con las entradas de cadena a menos que la cadena se interprete como un texto.

c=Characters;t_~f~p_:=({b,s}=c@p;b<>Riffle[StringCases[t,NumberString],s]<>(b/.Thread[c@"[ {<(" -> c@"] }>)"]))

Explicación

StringCases[t,NumberString]devuelve la lista de cadenas de números.

Riffleinserta los separadores entre los números.

/.Thread[c@"[ {<(" -> c@"] }>)"]) reemplaza el "soporte" izquierdo con el soporte derecho.

<>es la forma infija de StringJoin. Pega las subcadenas juntas.

DavidC
fuente
2

Matlab, 85 bytes

@(s,x)[x(1) strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)) x(1)+(x(1)~=32)+(x(1)~=40)]

Ejemplo de uso:

>> @(s,x)[x(1) strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)) x(1)+(x(1)~=32)+(x(1)~=40)]
ans = 
    @(s,x)[x(1),strjoin(regexp(s,'-?\d+\.?\d*','match'),x(2)),x(1)+(x(1)~=32)+(x(1)~=40)]

>> ans('1 2.4 -3 -444.555 5', '[,')
ans =
[1,2.4,-3,-444.555,5]
Luis Mendo
fuente
1

Julia, 95 bytes

f(l,s)=(x=s[1]<33?"":s[1:1])*join(matchall(r"[\d.-]+",l),s[2])*string(x>""?s[1]+(s[1]<41?1:2):x)

Esta es una función fque acepta dos cadenas y devuelve una cadena.

Sin golf:

function f{T<:AbstractString}(l::T, s::T)
    # Extract the numbers from the input list
    n = matchall(r"[\d.-]+", l)

    # Join them back into a string separated by given separator
    j = join(n, s[2])

    # Set the opening bracket type as the empty string unless
    # the given bracket type is not a space
    x = s[1] < 33 ? "" : s[1:1]

    # Get the closing bracket type by adding 1 or 2 to the ASCII
    # value of the opening bracket unless it's an empty string
    c = string(x > "" ? s[1] + (s[1] < 41 ? 1 : 2) : x)

    # Put it all together and return
    return x * j * c
end
Alex A.
fuente
1

Bash + GNU Utilities, 90

b=${2:0:1}
echo $b`sed "s/[][{}()<>]//g;s/[,; ]\+/${2:1}/g"<<<"$1"``tr '[{(<' ']})>'<<<$b`
Trauma digital
fuente