Crea un convertitore di elenchi numerici


20

Non odiarlo quando vuoi copiare e incollare un elenco di numeri (vettore, array ...), da un programma a un altro, ma il formato in cui hai i numeri non corrisponde al formato in cui ti serve ?

Ad esempio, in MATLAB potresti avere un elenco separato da spazi come questo:

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

In Python dovresti inserire delle virgole per rendere quell'elenco un input valido, quindi dovresti convertirlo in

[1, 2, 3, 4, 5]

per farlo funzionare. In C ++ potresti voler qualcosa di simile:

{16,2,77,29}

e così via.

Per semplificare la vita di tutti, creiamo un convertitore di elenchi, che prende un elenco in qualsiasi formato * e genera un elenco in un altro formato specificato.

Le parentesi valide sono:

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

I delimitatori validi sono:

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, l'input può avere qualsiasi numero di spazi tra i numeri, ma l'output può scegliere di avere zero spazi (se ,o ;è usato come delimitatore) o un singolo spazio (se è delimitato da spazi).

Oltre all'elenco di input, ci sarà una stringa (o due caratteri) che definisce il formato di output. La stringa di formato sarà inizialmente il tipo parentesi di apertura (solo), [, (, <, {o (l'ultimo è un singolo spazio utilizzato quando non c'è staffa circostante). Il tipo di parentesi sarà seguito dal tipo di delimitatore ,, ;oppure (l'ultimo è un singolo spazio). I due caratteri del formato di input devono essere considerati come un singolo argomento (stringa o due caratteri consecutivi) nell'ordine sopra descritto.

Alcuni esempi di stringhe di formato:

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

Regole:

  • L'output non può avere spazi iniziali
  • L'output può avere spazi finali e una nuova riga
    • L'output dovrebbe essere solo l'elenco di numeri, non ans =simili
  • L'input sarà un elenco di numeri interi o decimali (sia positivi che negativi (e zero)) e una stringa di due caratteri
    • Se l'input è costituito solo da numeri interi, l'elenco di output deve contenere solo numeri interi. Se l'elenco di input è composto da numeri interi e decimali, tutti i numeri di output possono essere numeri decimali. (È facoltativo mantenere gli interi come numeri interi)
    • Il numero massimo di cifre dopo il punto decimale che deve essere supportato è 3.
    • L'input sarà di due argomenti. Vale a dire i numeri sono in un argomento e la stringa di formato è un singolo argomento.
  • Il codice può essere un programma o una funzione
  • L'input può essere argomento della funzione o STDIN

Qualche esempio:

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]

Vince il codice più breve in byte. Come sempre, il vincitore verrà selezionato una settimana dal giorno in cui è stata pubblicata la sfida. Le risposte postate successivamente possono comunque vincere se sono più brevi del vincitore attuale.


Classifica

Lo snippet di stack nella parte inferiore di questo post genera il catalogo dalle risposte a) come elenco della soluzione più breve per lingua eb) come classifica generale.

Per assicurarti che la tua risposta venga visualizzata, ti preghiamo di iniziare la risposta con un titolo, utilizzando il seguente modello Markdown:

## Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

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

Se si desidera includere più numeri nell'intestazione (ad es. Perché il punteggio è la somma di due file o si desidera elencare separatamente le penalità del flag dell'interprete), assicurarsi che il punteggio effettivo sia l' ultimo numero nell'intestazione:

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

Puoi anche rendere il nome della lingua un collegamento che verrà quindi visualizzato nello snippet:

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


Il trailing e i primi spazi bianchi sono ammessi?
overactor

@overactor, vedi le prime due regole. Lo spazio bianco iniziale non è OK, il trailing è OK.
Stewie Griffin,

Possiamo prendere input nell'ordine opposto? (delimitatori prima, lista seconda)
Martin Ender l'

@ MartinBüttner, sì. Non è specificato che debba essere prima elencato, quindi puoi scegliere.
Stewie Griffin,

J usa _per indicare elementi negativi. :(
Zgarb,

Risposte:


1

CJam, 27 byte

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

Provalo qui.

Spiegazione

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.

8

JavaScript (ES6), 75 82

Come una funzione anonima

Modifica: 2 byte salvati thx @ user81655 (e altri 5 solo rivedendolo)

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

Test snippet

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>


6

CJam, 35 34 byte

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

Provalo qui.

Si aspetta il formato sulla prima riga e l'elenco sulla seconda.

Spiegazione

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.

5

Pyth, 33 byte

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

Provalo online: dimostrazione o suite di test

Spiegazione:

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

Puoi aggiungere una spiegazione di come funziona?
Shelvacu,

1
@Shel Eccoti.
Jakube,

5

PowerShell, 108 100 95 85 byte

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

(vedi cronologia delle revisioni per le versioni precedenti)

Golfato altri 15 byte rimuovendolo $b e $svariabili e cambiando parentesi sulla stringa interna.

Questo richiede input come due stringhe e li memorizza in $ie $z, quindi si costruisce una nuova stringa di output. Le parentesi interne -splits $icon una regex di selezionare solo cifre numeriche, poi -joins indietro insieme con il delimitatore richiesto. Lo concateniamo con il primo carattere dell'input del delimitatore (ad es. [) E lo chiudiamo con l'indicizzazione in una stringa in base al valore ASCII del primo carattere e qualche trucco di formulazione. L'esterno .Trim()rimuove eventuali spazi iniziali o finali.


Penso che potresti sostituire la tua parentesi chiusa "]})>"["[{(< ".IndexOf($b[0])]con qualcosa del genere ' }) >]'[($b[0]-32)%6]. La ($b[0]-32)%6si dà 0,2,4,5,1per l'apertura di caratteri di parentesi, che è possibile utilizzare per indice nella stringa di parentesi di chiusura ' }) >]'. Potrebbe esserci una "formula" più breve, ma questo sembra abbastanza buono.
Danko Durbić,

@ DankoDurbić Eccellente! Stavo cercando di trovare un po 'di matematica per selezionare il carattere di output corretto in base ai valori ASCII, ma non sono riuscito a trovare la formula giusta. Continuavo a inciampare ()stando uno accanto all'altro, ma le altre parentesi hanno un carattere in mezzo, quindi sono andato con l'indicizzazione. Grazie!
AdmBorkBork,

Usando String.Replace()invece l' -replaceoperatore ti compreresti altri 2 byte (non c'è bisogno di scappare o definire una classe di caratteri con [])
Mathias R. Jessen

@ MathiasR.Jessen A meno che non mi manchi qualcosa qui, .Replace('[]{}()<>;,',' ')non cattureranno singoli personaggi ma cercheranno invece di abbinare il tutto simbolico, che non esiste. Dovremmo usare Regex.Replace , che comporta una [regex]::chiamata .NET e allungherebbe invece il codice.
AdmBorkBork,

@TessellatingHeckler Grazie! Ho usato un altro byte usando -ne''invece di |?{$_}.
AdmBorkBork,

4

Python 2, 96 byte

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

Chiama come:

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

Produzione:

[-1.3,3.4,4,5.55555555]

2

JavaScript (ES6), 82 92 116 92 byte

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

Una funzione anonima, eseguila in questo modo

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

Probabilmente questo può essere ulteriormente giocato a golf ..

Ungolfed

(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] -> ">"
)

Penso che devi prendere un come stringa, non un elenco.
overactor

Totalmente frainteso questo: The input will be a list of integer or decimal numbers (both positive and negative (and zero)), and a string of two characters. Risolto, grazie
Bassdrop Cumberwubwubwub l'

2

Mathematica, 108 byte

Mathematica è generalmente maldestra con gli input di stringa a meno che la stringa non debba essere interpretata come un testo.

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

Spiegazione

StringCases[t,NumberString]restituisce l'elenco delle stringhe numeriche.

Riffleinserisce i separatori tra i numeri.

/.Thread[c@"[ {<(" -> c@"] }>)"]) sostituisce la "parentesi" sinistra con la parentesi destra.

<>è la forma infissa di StringJoin. Incolla insieme le sottostringhe.


2

Matlab, 85 byte

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

Esempio di utilizzo:

>> @(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]

1

Julia, 95 byte

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)

Questa è una funzione f che accetta due stringhe e restituisce una stringa.

Ungolfed:

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

1

Bash + GNU Utilities, 90

b=${2:0:1}
echo $b`sed "s/[][{}()<>]//g;s/[,; ]\+/${2:1}/g"<<<"$1"``tr '[{(<' ']})>'<<<$b`
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.