Zucchero sintattico di elisir array


17

In Elisir, gli elenchi (collegati) sono nel formato in [head | tail]cui head può essere qualsiasi cosa e tail è un elenco del resto dell'elenco e []- l'elenco vuoto - è l'unica eccezione a questo.

Gli elenchi possono anche essere scritti in modo [1, 2, 3]equivalente a[1 | [2 | [3 | []]]]

Il tuo compito è convertire un elenco come descritto. L'input sarà sempre un elenco valido (in elisir) contenente solo numeri corrispondenti alla regex \[(\d+(, ?\d+)*)?\]. Puoi prendere l'input con (uno spazio dopo ogni virgola) o senza spazi. L'output può essere con (uno spazio prima e dopo ciascuno |) o senza spazi.

Per gli ingressi con zeri iniziali è possibile emettere o senza gli zeri o con.

L'input deve essere considerato come una stringa (se si scrive una funzione), così come l'output.

Esempi

[] -> []
[5] -> [5 | []]
[1, 7] -> [1 | [7 | []]]
[4, 4, 4] -> [4 | [4 | [4 | []]]]
[10, 333] -> [10 | [333 | []]]

correlati , non un duplicato in quanto ciò comporta in parte l'aggiunta della modalità ]alla fine. Inoltre, la risposta di Haskell qui è abbastanza diversa da quella lì.


5
-1 da me. I formati I / O ingombranti sono scoraggiati. Se l'input è un elenco, prendiamolo come elenco invece di avere il 90% del nostro codice semplicemente analizzando l'input
Jo King

2
Dobbiamo supportare i primi 0? Si adattano alla regex.
Jo King,

2
Possibile duplicato della sintassi senza zucchero
NoOneIsHere

5
@JoKing Direi che qui la sfida in sé consiste nel convertire tra due formati specifici, quindi analizzare l'input è una parte fondamentale della sfida e non qualcosa in più aggiunto ad essa. PS: ho capito solo ora qual è il tuo nickname xD
Leo,

2
@MuhammadSalman: la sfida è taggata come "analisi", quindi la conversione da / a una stringa è una parte sostanziale di essa con intento.
nimi,

Risposte:


9

Haskell, 50 byte

f.read
f(a:b)='[':show(a+0)++'|':f b++"]"
f _="[]"

Provalo online!

La +0lascia Haskell tipo correttore sapere che si tratta di elenchi di numeri, quindi readanalizzerà la stringa di input per noi.


1
+1, adoro il trucco +0!
B. Mehta,



4

Retina , 39 33 32 20 byte

\b]
,]
+`,(.*)
|[$1]

Salvato 13 byte grazie a H.PWiz, ovs, solo ASCII e Neil.
Provalo online!

Spiegazione

\b]
,]

Se non abbiamo un elenco vuoto, aggiungi una virgola finale.

+`,(.*)
|[$1]

Mentre ci sono virgole, avvolgi le cose |[ thing ].




@ Solo ASCII È possibile salvare altri 4 byte sostituendoli \b]con ,]. (Altrimenti avevo scoperto indipendentemente la stessa soluzione.)
Neil

Oh questo è vero. Ho dimenticato \buna cosa per qualche ragione> _> 20 byte @Mnemonic
ASCII-solo

4

Perl 5 -pl , 31 28 byte

s/\d\K]/,]/;$\=']'x s/,/|[/g

Provalo online!

Come?

-p                    # (command line) Implicit input/output via $_ and $\
s/\d\K]/,]/;          # insert a comma at the end if the list is not empty
$\=']'x s/,/|[/g      # At the end of the run, output as many ']' as there are
                      # commas in the input.  Replace the commas with "|["

3

Elisir , 111 85 byte

f=fn[h|t],f->"[#{h}|#{f.(t,f)}]"
[],_->"[]"
h,f->f.(elem(Code.eval_string(h),0),f)end

Provalo online!

Non ho mai usato Elisir prima. Definisce una funzione che accetta una stringa e un riferimento a se stessa e restituisce una stringa.


3

Ceylon , 113 byte

String p(String s)=>s.split(" ,[]".contains).select((x)=>!x.empty).reversed.fold("[]")((t,h)=>"[``h`` | ``t``]");

Provalo online!

Ecco scritto:

// define a function p mapping Strings to Strings.
String p(String s) =>
    // we split the string at all characters which are brackets, comma or space.
    s.split(" ,[]".contains)    // → {String+}, e.g.  { "", "1", "7", "" }
    // That iterable contains empty strings, so let's remove them.
    // Using `select` instead of `filter` makes the result a sequential instead of
    // an Iterable.
     .select((x)=>!x.empty)    // → [String*], e.g.   [1, 7]
    // now invert the order.
    // (This needs a Sequential (or at least a List) instead of an Iterable.)
     .reversed                 // → [String*], e.g.   [7, 1]
    // Now iterate over the list, starting with "[]", and apply a function
    // to each element with the intermediate result.
     .fold("[]")                       // → String(String(String, String))
    //    This function takes the intermediate result `t` (for tail) and an element
    //    `h` (for head), and puts them together into brackets, with a " | " in the
    //    middle. This uses String interpolation, I could have used `"+` and `+"`
    //    instead for the same length.
          ((t,h)=>"[``h`` | ``t``]");  // → String

Provalo online!

Come notato da ovs in un commento (ora eliminato): se si selezionano le opzioni "senza spazi" per l'input e l'output indicati nella domanda, si possono salvare altri 3 byte (quelli ovvi con spazi).

Se non è necessario analizzare l'input, ma è possibile ottenere una sequenza come input, diventa molto più breve (69 byte).

String p(Object[]s)=>s.reversed.fold("[]")((t,h)=>"[``h`` | ``t``]");

Provalo online!



2

SNOBOL4 (CSNOBOL4) , 114 byte

	I =INPUT
S	N =N + 1	
	I SPAN(1234567890) . L REM . I	:F(O)
	O =O '[' L ' | '	:(S)
O	OUTPUT =O '[' DUPL(']',N)
END

Provalo online!

	I =INPUT				;* read input
S	N =N + 1				;* counter for number of elements (including empty list)
	I SPAN(1234567890) . L REM . I	:F(O)	;* get value matching \d until none left
	O =O '[' L ' | '	:(S)		;* build output string
O	OUTPUT =O '[' DUPL(']',N)		;* print O concatenated with a '[' and N copies of ']'
END

2

Stax , 19 byte

É▲²:WlÖ└%ï╪☺╒▓"We↨Φ

Esegui ed esegui il debug

Il mio primo post Stax, quindi probabilmente non ottimale.

Spacchettato e commentato:

U,                      Put -1 under input
  {                     Block
   i                      Push loop index, needed later
    '[a$'|++              Wrap the element in "[...|"
            m           Map
             '[+        Add another "["
                s2+     Get the latest loop index + 2
                   ']*+ Add that many "]"

Esegui ed esegui il debug di questo



2

Befunge-98 (PyFunge) , 22 21 byte

'[,1;@j,]';#$&." |",,

Provalo online!

Se non ci fossero strane restrizioni sull'output, potremmo farlo in 18:

'[,1;@j,]';#$&.'|,

Fatto curioso, questo è tecnicamente un programma che non fa nulla in Python.



2

R , 84 71 69 byte

function(x){while(x<(x=sub('(,|\\d\\K(?=]))(.+)','|[\\2]',x,,T)))1;x}

Provalo online!

  • -15 byte grazie a @KirillL.

1
71 byte con una singola sostituzione basata sulla mia risposta di Ruby.
Kirill L.

@KirillL. : grazie, ero sicuro che ci fosse una regex più breve per farlo, ma ho sempre fatto confusione con le soluzioni: D
digEmAll

-2 in più , mi ero completamente dimenticato di uno \Ksguardo più corto
Kirill L.




1

Gelatina , 18 byte

ŒVµ⁾[]jj⁾|[ṫ3;”]ṁ$

Un programma completo che stampa il risultato (come collegamento monadico accetta un elenco di caratteri ma restituisce un elenco di caratteri e numeri interi).

Provalo online!

Come?

ŒVµ⁾[]jj⁾|[ṫ3;”]ṁ$ - Main link: list of characters  e.g. "[10,333]"
ŒV                 - evaluate as Python code              [10,333]
  µ                - start a new monadic chain, call that X
   ⁾[]             - list of characters                   ['[',']']
      j            - join with X                          ['[',10,333,']']
        ⁾|[        - list of characters                   ['|','[']
       j           - join                                 ['[','|','[',10,'|','[',333,'|','[',']']
           ṫ3      - tail from index three                ['[',10,'|','[',333,'|','[',']']
                 $ - last two links as a monad (f(X)):
              ”]   -   character                          ']'
                ṁ  -   mould like X                       [']',']'] (here 2 because X is 2 long)
             ;     - concatenate                          ['[',10,'|','[',333,'|','[',']',']',']']
                   - implicit (and smashing) print        [10|[333|[]]]

1

Java 10, 107 byte

s->{var r="[]";for(var i:s.replaceAll("[\\[\\]]","").split(","))r="["+i+"|"+r+"]";return s.length()<3?s:r;}

Provalo online.

Spiegazione:

s->{                       // Method with String as both parameter and return-type
  var r="[]";              //  Result-String, starting at "[]"
  for(var i:s.replaceAll("[\\[\\]]","") 
                           //  Removing trailing "[" and leading "]"
             .split(","))  //  Loop over the items
    r="["+i+"|"+r+"]";     //   Create the result-String `r`
  return s.length()<3?     //  If the input was "[]"
          s                //   Return the input as result
         :                 //  Else:
          r;}              //   Return `r` as result

1

ML standard , 71 byte

fun p[_]="]|[]]"|p(#","::r)="|["^p r^"]"|p(d::r)=str d^p r;p o explode;

Provalo online! Utilizza il formato senza spazi. Ad esempio it "[10,333,4]"rese "[10|[333|[4]|[]]]]".

ungolfed

fun p [_]       = "]|[]]"          (* if there is only one char left we are at the end *)
  | p (#","::r) = "|[" ^ p r ^ "]" (* a ',' in the input is replaced by "|[" and an closing "]" is added to the end *)
  | p (d::r)    = str d ^ p r      (* all other chars (the digits and the initial '[') are converted to a string and concatenated to recursive result *)

val f = p o explode  (* convert string into list of chars and apply function p *)

Provalo online!


1

R , 140 136 byte

Giù 4 byte secondo i solidi consigli di Giuseppe.

function(l,x=unlist(strsplit(substr(l,2,nchar(l)-1),", ")))paste(c("[",paste0(c(x,"]"),collapse=" | ["),rep("]",length(x))),collapse="")

Provalo online!


substrè più breve e il primo paste0può essere pastequello di ottenere questo a 136 byte.
Giuseppe,

1
Utilizzando eval, parsee subinvece di unlist, strsplite substr, sono anche riuscito solo 136 byte (ho pensato che potrebbe essere più breve, ma non lo era)
Giuseppe

@Giuseppe Grazie per i -4 byte! Vorrei che avessimo qualcosa di più corto. Soluzione ricorsiva forse?
JayCe,



0

sed + -E, 46 byte

:
s/\[([0-9]+)(, ?([^]]*)|())\]/[\1 | [\3]]/
t

Un approccio abbastanza semplice. La seconda riga prende [\d+, ...]e la modifica in [\d | [...]]. La terza riga torna alla prima riga, se la sostituzione ha avuto esito positivo. La sostituzione si ripete fino a quando non riesce e quindi il programma termina. Esegui con sed -E -f filename.sed, passando input tramite stdin.


0

Rosso , 110 byte

func[s][if s ="[]"[return s]replace append/dup replace/all b: copy s",""|[""]"(length? b)- length? s"]""|[]]"]

Provalo online!

Spiegazione della versione non golfata:

f: func[s][                      
    if s = "[]" [return s]                    ; if the list is empty, return it    
    b: copy s                                 ; save a copy of the input in b 
    replace/all b "," "|["                    ; replace every "," with "|["  
    append/dup b "]" (length? b) - length? s  ; append as many "]" as there were ","
    replace b "]" "|[]]"                      ; replace the first "]" with "|[]]"     
]                                             ; the last value is returned implicitly

Il rosso è così facilmente leggibile, che dubito di aver bisogno di aggiungere i commenti sopra :)


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.