Elixir Array Syntactic Sugar

17

Dans Elixir, les listes (liées) sont au format [head | tail]tête peut être n'importe quoi et queue est une liste du reste de la liste, et []- la liste vide - est la seule exception à cela.

Les listes peuvent également être écrites comme [1, 2, 3]ce qui équivaut à[1 | [2 | [3 | []]]]

Votre tâche consiste à convertir une liste comme décrit. L'entrée sera toujours une liste valide (dans Elixir) contenant uniquement des nombres correspondant à l'expression régulière \[(\d+(, ?\d+)*)?\]. Vous pouvez prendre l'entrée avec (un espace après chaque virgule) ou sans espaces. La sortie peut être avec (un espace avant et après chacun |) ou sans espaces.

Pour les entrées avec des zéros non significatifs, vous pouvez sortir sans les zéros ou avec.

L'entrée doit être considérée comme une chaîne (si vous écrivez une fonction), tout comme la sortie.

Exemples

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

liés , pas un doublon car cela implique en partie l'ajout de mode ]à la fin. De plus, la réponse Haskell ici est très différente de celle là-bas.

Okx
la source
5
-1 de moi. Les formats d'E / S encombrants sont déconseillés. Si l'entrée est une liste, prenons-la comme une liste au lieu d'avoir 90% de notre code analysant simplement l'entrée
Jo King
2
Faut-il prendre en charge les 0 en tête? Ils correspondent à l'expression régulière.
Jo King
2
Copie
5
@JoKing Je dirais qu'ici le défi lui-même consiste à convertir entre deux formats spécifiques, donc l'analyse de l'entrée est une partie fondamentale du défi et non quelque chose de supplémentaire. PS Je n'ai réalisé que maintenant quel est vraiment votre surnom xD
Leo
2
@MuhammadSalman: le défi est étiqueté comme "analyse", donc la conversion de / vers une chaîne en est une partie substantielle avec intention.
nimi

Réponses:

9

Haskell, 50 octets

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

Essayez-le en ligne!

Le +0permet au vérificateur de type Haskell de savoir que nous avons affaire à des listes de nombres, il readanalysera donc la chaîne d'entrée pour nous.

nimi
la source
1
+1, j'adore le truc +0!
B. Mehta
4

Rétine , 39 33 32 20 octets

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

13 octets enregistrés grâce à H.PWiz, ovs, ASCII-only et Neil.
Essayez-le en ligne!

Explication

\b]
,]

Si nous n'avons pas de liste vide, ajoutez une virgule de fin.

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

Bien qu'il y ait des virgules, enveloppez les choses avec |[ thing ].


la source
@ovs 24?
ASCII uniquement
aussi 24?
ASCII uniquement
@ ASCII uniquement Vous pouvez enregistrer 4 autres octets en les remplaçant \b]par ,]. (Sinon, j'avais découvert indépendamment la même solution.)
Neil
Oh c'est vrai. J'ai oublié que \bc'était une chose pour une raison quelconque> _> 20 octets @Mnemonic
ASCII uniquement
4

Perl 5 -pl , 31 28 octets

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

Essayez-le en ligne!

Comment?

-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
la source
3

Elixir , 111 85 octets

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

Essayez-le en ligne!

Je n'ai jamais utilisé Elixir auparavant. Définit une fonction qui prend une chaîne et une référence pour elle-même et renvoie une chaîne.

Jo King
la source
3

Ceylan , 113 octets

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

Essayez-le en ligne!

Voici écrit:

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

Essayez-le en ligne!

Comme indiqué par les ovs dans un commentaire (maintenant supprimé): Si l'on sélectionne les options "sans espaces" pour l'entrée et la sortie indiquées dans la question, on peut sauvegarder 3 octets de plus (les plus évidents avec des espaces).

Si nous n'avons pas besoin d'analyser l'entrée, mais que nous pouvons simplement obtenir une séquence en entrée, elle devient beaucoup plus courte (69 octets).

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

Essayez-le en ligne!

Paŭlo Ebermann
la source
2

Python 3 , 65 octets

lambda k:"["+''.join(f"{u}|["for u in eval(k))+-~len(eval(k))*"]"

Essayez-le en ligne!

Si l'entrée peut être une liste à la place, alors:

Python 3 , 53 octets

lambda k:"["+''.join(f"{u}|["for u in k)+-~len(k)*"]"

Essayez-le en ligne!

M. Xcoder
la source
2

SNOBOL4 (CSNOBOL4) , 114 octets

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

Essayez-le en ligne!

	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
la source
2

Stax , 19 octets

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

Exécuter et déboguer

Mon premier post Stax, donc probablement pas optimal.

Déballé et commenté:

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

Exécutez et déboguez celui-ci

wastl
la source
2

Befunge-98 (PyFunge) , 22 21 octets

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

Essayez-le en ligne!

S'il n'y avait pas de restrictions étranges sur la sortie, nous pourrions le faire en 18:

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

Fait amusant, il s'agit techniquement d'un programme qui ne fait rien en Python.

Jo King
la source
2

R , 84 71 69 octets

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

Essayez-le en ligne!

  • -15 octets grâce à @KirillL.
digEmAll
la source
1
71 octets avec une seule substitution basée sur ma réponse Ruby.
Kirill L.
@KirillL. : merci, j'étais sûr qu'il y avait une expression rationnelle plus courte pour le faire, mais je me trompe toujours avec les contournements: D
digEmAll
-2 plus , j'ai totalement oublié un plus court\K lookbehind
Kirill L.
1

Gelée , 18 octets

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

Un programme complet imprimant le résultat (en tant que lien monadique, il accepte une liste de caractères mais renvoie une liste de caractères et d'entiers).

Essayez-le en ligne!

Comment?

Œ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
la source
1

Java 10, 107 octets

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

Essayez-le en ligne.

Explication:

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
la source
1

ML standard , 71 octets

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

Essayez-le en ligne! Utilise le format sans espaces. Par exemple, les it "[10,333,4]"rendements"[10|[333|[4]|[]]]]" .

non golfé

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 *)

Essayez-le en ligne!

Laikoni
la source
1

R , 140 136 octets

Down 4 octets selon les bons conseils de Giuseppe.

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

Essayez-le en ligne!

JayCe
la source
substrest plus court et le premier paste0peut être pasted'obtenir ceci à 136 octets.
Giuseppe
1
L' utilisation eval, parseet au sublieu de unlist, strsplitet substr, j'ai aussi réussi seulement 136 octets (je pensais que ce serait peut - être plus courte , mais ce ne fut pas)
Giuseppe
@Giuseppe Merci pour les -4 octets! Je souhaite que nous ayons quelque chose de plus court. Solution récursive peut-être?
JayCe
1

R , 108 octets

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

Essayez-le en ligne!

Il a fallu près d'un an pour trouver une meilleure solution R que la précédente ... aurait dû savoir que Reduceserait la réponse! Sorties sans espaces, les entrées peuvent être avec ou sans espaces.

Giuseppe
la source
0

sed + -E, 46 octets

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

Une approche assez simple. La deuxième ligne prend [\d+, ...]et change en [\d | [...]]. La troisième ligne revient à la première ligne si la substitution a réussi. La substitution se répète jusqu'à ce qu'elle échoue, puis le programme se termine. Exécutez avec sed -E -f filename.sed, en passant l'entrée via stdin.

Silvio Mayolo
la source
0

Rouge , 110 octets

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

Essayez-le en ligne!

Explication de la version non golfée:

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

Le rouge est si facilement lisible, que je doute que j'avais besoin d'ajouter les commentaires ci-dessus :)

Galen Ivanov
la source