Elixir Array Syntactic Sugar

17

In Elixir haben (verknüpfte) Listen das Format, [head | tail]bei dem head alles sein kann und tail eine Liste des Restes der Liste ist. []Die leere Liste ist die einzige Ausnahme.

Listen können auch so geschrieben werden, wie [1, 2, 3]es äquivalent zu ist[1 | [2 | [3 | []]]]

Ihre Aufgabe ist es, eine Liste wie beschrieben zu konvertieren. Die Eingabe ist immer eine gültige Liste (in Elixir), die nur Zahlen enthält, die dem regulären Ausdruck entsprechen \[(\d+(, ?\d+)*)?\]. Sie können die Eingabe mit (ein Leerzeichen nach jedem Komma) oder ohne Leerzeichen vornehmen. Die Ausgabe kann mit (jeweils ein Leerzeichen vor und nach |) oder ohne Leerzeichen erfolgen.

Bei Eingaben mit führenden Nullen können Sie entweder ohne Nullen oder mit ausgeben.

Die Eingabe muss wie die Ausgabe als Zeichenfolge interpretiert werden (wenn eine Funktion geschrieben wird).

Beispiele

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

verwandt , kein Duplikat, da dies zum Teil das Hinzufügen von Modus ]zum Ende beinhaltet. Außerdem unterscheidet sich die Antwort von Haskell von der hier.

Okx
quelle
5
-1 von mir. Von umständlichen E / A-Formaten wird abgeraten. Wenn es sich bei der Eingabe um eine Liste handelt, nehmen wir sie als Liste, anstatt 90% unseres Codes nur zum Parsen der Eingabe zu verwenden
Jo King,
2
Müssen wir führende Nullen unterstützen? Sie passen zum Regex.
Jo King
2
Mögliches Duplikat der
zuckerfreien
5
@JoKing Ich würde argumentieren, dass es bei der Herausforderung selbst darum geht, zwischen zwei bestimmten Formaten zu konvertieren. Daher ist das Parsen der Eingabe ein grundlegender Teil der Herausforderung und kein zusätzliches Element. PS Ich habe erst jetzt gemerkt, was dein Spitzname wirklich ist xD
Leo
2
@ MuhammadSalman: Die Herausforderung ist als "Parsing" gekennzeichnet, daher ist das Konvertieren von / in eine Zeichenfolge ein wesentlicher Teil davon mit Absicht.
nimi

Antworten:

9

Haskell, 50 Bytes

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

Probieren Sie es online!

Das +0läßt die Know Haskell Typ - Checker , dass wir mit Listen von Zahlen zu tun hat , so readwird die Eingabezeichenfolge für uns analysiert.

nimi
quelle
1
+1, ich liebe den +0 Trick!
B. Mehta
4

Retina , 39 33 32 20 Bytes

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

Dank H.PWiz, ovs, nur ASCII und Neil 13 Bytes gespart.
Probieren Sie es online!

Erläuterung

\b]
,]

Wenn wir keine leere Liste haben, fügen Sie ein nachstehendes Komma hinzu.

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

Während es Kommas gibt, wickeln Sie die Dinge mit |[ thing ].


quelle
@ovs 24?
Nur ASCII
auch 24?
Nur ASCII
@ ASCII-only Sie können durch das Ersetzen weitere 4 Bytes speichern \b]mit ,]. (Ansonsten hatte ich unabhängig die gleiche Lösung entdeckt.)
Neil
Oh, das stimmt. Ich habe vergessen, \bdass aus irgendeinem Grund> _> 20 Bytes @Mnemonic
ASCII
4

Perl 5 -pl , 31 28 Bytes

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

Probieren Sie es online!

Wie?

-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 "|["
Xcali
quelle
3

Elixier , 111 85 Bytes

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

Probieren Sie es online!

Ich habe Elixir noch nie benutzt. Definiert eine Funktion, die eine Zeichenfolge und einen Verweis auf sich selbst nimmt und eine Zeichenfolge zurückgibt.

Scherzen
quelle
3

Ceylon , 113 Bytes

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

Probieren Sie es online!

Hier ist es ausgeschrieben:

// 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

Probieren Sie es online!

Wie von ovs in einem (jetzt gelöschten) Kommentar vermerkt: Wenn man die in der Frage angegebenen Optionen "ohne Leerzeichen" für Ein- und Ausgabe auswählt, kann man 3 weitere Bytes speichern (die offensichtlichen mit Leerzeichen).

Wenn wir die Eingabe nicht analysieren müssen, sondern nur eine Sequenz als Eingabe erhalten können, wird sie viel kürzer (69 Byte).

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

Probieren Sie es online!

Paŭlo Ebermann
quelle
2

SNOBOL4 (CSNOBOL4) , 114 Bytes

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

Probieren Sie es 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
Giuseppe
quelle
2

Befunge-98 (PyFunge) , 22 21 Bytes

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

Probieren Sie es online!

Wenn es keine seltsamen Einschränkungen für die Ausgabe gäbe, könnten wir dies in 18 tun:

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

Unterhaltsame Tatsache, dies ist technisch gesehen ein Programm, das in Python nichts macht.

Scherzen
quelle
2

R , 84 71 69 Bytes

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

Probieren Sie es online!

  • -15 Bytes dank @KirillL.
digEmAll
quelle
1
71 Bytes mit einer einzigen Ersetzung basierend auf meiner Ruby-Antwort.
Kirill L.
@KirillL. : danke, ich war mir sicher, dass es einen kürzeren regulären
Ausdruck
-2 mehr , ich habe einen kürzeren \KLookbehind total vergessen
Kirill L.
1

Jelly , 18 Bytes

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

Ein vollständiges Programm, das das Ergebnis druckt (als monadischer Link akzeptiert es eine Liste von Zeichen, gibt aber eine Liste von Zeichen und ganzen Zahlen zurück).

Probieren Sie es online!

Wie?

Œ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|[]]]
Jonathan Allan
quelle
1

Java 10, 107 Bytes

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

Probieren Sie es online aus.

Erläuterung:

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
Kevin Cruijssen
quelle
1

Standard ML , 71 Bytes

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

Probieren Sie es online! Verwendet das Format ohne Leerzeichen. ZB it "[10,333,4]"ergibt "[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 *)

Probieren Sie es online!

Laikoni
quelle
1

R , 140 136 Bytes

4 Bytes nach Giuseppes guter Empfehlung runter.

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

Probieren Sie es online!

JayCe
quelle
substrist kürzer und die erste paste0kann sein paste, dies auf 136 Bytes zu bekommen.
Giuseppe
1
Unter Verwendung eval, parseund substatt unlist, strsplitund substrich auch 136 Bytes nur geschaffen (ich dachte , es kürzer sein könnte , aber es war nicht)
Giuseppe
@ Giuseppe Danke für die -4 Bytes! Ich wünschte wir hätten etwas kürzeres. Rekursive Lösung vielleicht?
JayCe
1

R , 108 Bytes

function(l)Reduce(function(x,y)paste0("[",x,"|",y,"]"),eval(parse(t=sub("]",")",sub("\\[","c(",l)))),"[]",T)

Probieren Sie es online!

Es hat fast ein Jahr gedauert, um eine bessere R-Lösung zu finden als vorher ... hätte wissen müssen, Reducedass dies die Lösung ist ! Ausgaben ohne Leerzeichen, Eingaben können mit oder ohne Leerzeichen erfolgen.

Giuseppe
quelle
0

sed + -E, 46 Bytes

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

Ein ziemlich einfacher Ansatz. Die zweite Zeile nimmt [\d+, ...]und ändert es auf [\d | [...]]. Die dritte Zeile springt zurück zur ersten Zeile, wenn die Ersetzung erfolgreich war. Die Ersetzung wiederholt sich, bis sie fehlschlägt und das Programm dann beendet wird. Laufen Sie mit sed -E -f filename.sedund übergeben Sie die Eingabe über stdin.

Silvio Mayolo
quelle
0

Rot , 110 Bytes

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

Probieren Sie es online!

Erklärung der ungolfed version:

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

Rot ist so gut lesbar, dass ich bezweifle, dass ich die obigen Kommentare hinzufügen musste :)

Galen Ivanov
quelle