Annuler la minification d'une chaîne de type Python

13

Pyth est peut-être le langage de golf polyvalent le plus réussi. Bien qu'il soit quelque peu en déclin en raison des nouveaux langages, de 2014 à 2016, la syntaxe concise de Pyth, les mises à jour constantes, la surcharge et (pour son époque) de nombreux modules intégrés en ont fait un favori pour la majorité des questions.

Le code Pyth est souvent difficile à lire. Même la sortie du mode de débogage (Python transpilé) consiste souvent en une longue ligne, parfois avec des parenthèses imbriquées à dix profondeurs. Cependant, Pyth correctement formaté est très lisible.

Voici un morceau de code Pyth, écrit par @isaacg dans Play the Word Chain .

.MlZfqhMtTeMPT+Lzs.pMyQ

C'est beaucoup plus lisible comme ça.

.M                     Filter by gives-maximal-value of
   l Z                   lambda Z:length(Z) over
   f                     filter by (lambda T:
     q                     equal
       hM t T                head-map tail T
       eM P T                end-map Pop T)
     +L                    Append z to each element in
        z                        
        s .pM y Q            flattened permutations of each subset of Q

Pour ce défi, nous éliminons l' aspect de kolmogorov de la catégorisation des caractères Pyth et nous nous concentrons sur le formatage. Au lieu d'être du code Pyth, l'entrée sera composée de caractères 0123456789M. Le chiffre nreprésente une fonction de l'aritén et Mreprésente un opérateur. Par exemple, le code ci-dessus est représenté par 210221M101M102M011M10. Voici les étapes pour minimiser:

Séparez la chaîne en jetons.

Un jeton correspond [0-9]M*.0Mne se produira pas en entrée.

Ajoutez des 0 de fin.

Lorsqu'il n'y a pas assez d'arguments, Pyth ajoute autant de variables implicites (variables lambda ou Qs) au code que nécessaire pour remplir les arguments du programme; ceux-ci devraient être représentés par l' 0art.

Regroupez les jetons en lignes.

L'arité d'un jeton est la valeur de son chiffre.

  • Un jeton arity-0 (c'est-à-dire un 0) termine une ligne.

  • Pour un jeton arity-1, le jeton suivant doit aller sur la même ligne, séparé par un espace.

  • Pour un jeton arity> = 2, ses arguments vont sur des lignes distinctes, dans l'ordre où ils apparaissent dans le code, chacun suivi de ses propres sous-arguments, etc. Les arguments d'un jeton sont mis en retrait à la fin de ce jeton plus un espace.

Contribution

Une chaîne non vide (ou un tableau de caractères, un tableau de chaînes de longueur 1, etc., comme le permettent les méthodes d'E / S standard) 0123456789M, qui ne contiendra pas la sous-chaîne0M .

Production

La chaîne formatée selon les règles ci-dessus.

Cas de test

210221M101M102M011M10

2
  1 0
  2
    2
      1M 1 0
      1M 1 0
    2M
       0
       1 1M 1 0


123M4M

1 2
    3M
       4M
          0
          0
          0
          0
       0
       0
    0


2MM

2MM
    0
    0


11011100

1 1 0
1 1 1 0
0


9000000

9
  0
  0
  0
  0
  0
  0
  0
  0
  0
lirtosiast
la source
Question connexe: codegolf.stackexchange.com/questions/47798/…
lirtosiast
Puis-je prendre l'entrée comme un tableau de chiffres / chaîne? L'exemple 210221M101M102M011M10serait[2,1,0,2,2,1,'M',1,0,1,'M',1,0,2,'M',0,1,1,'M',1,0]
Luis felipe De jesus Munoz
@LuisfelipeDejesusMunoz Non, à moins que les règles d'E / S standard n'exigent que vous soyez autorisé (ce que je ne pense pas.) IMO, cela changerait légèrement le défi si les Ms pouvaient être un type de données différent des entiers.
lirtosiast
@lirtosiast Donc, un tableau de caractères / chaînes de caractères uniques est très bien, mais n'utilise pas de types de données différents entre les chiffres et M?
Kamil Drakari
1
@LeakyNun La chaîne vide est désormais un comportement indéfini.
lirtosiast

Réponses:

1

JavaScript (ES8), 160 159 octets

f=(s,a=[d=0,p=[1]])=>s.replace(/(.)M*/g,(s,c)=>(g=_=>a[d]?s+(P=p[d]-=c--&&~s.length,c?`
`.padEnd(P):' '):g(d--))(a[d]--,a[++d]=+c,p[d]=p[d-1]))+(d?f('0',a):'')

Essayez-le en ligne!

Commenté

f = (                          // f = recursive function taking:
  s,                           //   s   = input string
  a = [                        //   a[] = array holding the number of expected arguments
    d = 0,                     //   d   = current depth, initialized to 0
    p = [1]                    //   p[] = array holding the padding values
  ]                            //
) =>                           //
  s.replace(                   // search in s all substrings
    RegExp('(.)M*', 'g'),      // consisting of a digit followed by 0 to N 'M' characters
    (s, c) =>                  // for each substring s beginning with the digit c:
      ( g = _ =>               //   g = recursive function
          a[d] ?               //     if we're still expecting at least one argument at
                               //     this depth:
            s + (              //       append s
              P = p[d] -=      //       update the padding value P = p[d] for this depth:
                c-- &&         //         decrement c; unless c was equal to 0,
                ~s.length,     //         add the length of s + 1 to p[d]
              c ?              //       if c is not equal to 0 (i.e. was not equal to 1):
                `\n`.padEnd(P) //         append a linefeed followed by P - 1 spaces
              :                //       else:
                ' '            //         append a single space
            )                  //
          :                    //     else (all arguments have been processed):
            g(d--)             //       decrement the depth and call g again
      )(                       //   before the initial call to g:
        a[d]--,                //     decrement the number of arguments at depth d
        a[++d] = +c,           //     set the number of arguments for the next depth
        p[d] = p[d - 1]        //     set the padding value for the next depth,
      )                        //     using a copy of the previous depth
  ) + (                        // end of replace()
    d ?                        // if we're not back at depth 0:
      f('0', a)                //   do a recursive call to f with an extra '0'
    :                          // else:
      ''                       //   stop recursion
  )                            //
Arnauld
la source
1

Haskell , 192 190 187 octets

unlines.snd.f
f(n:r)|(m,t)<-span(>'9')r,(s,l)<-n#t=(s,n?((n:m):map((' '<$(n:n:m))++)l))
f e=(e,["0"])
'1'?(a:b:r)=(a++drop(length a)b):r
_?s=s
'0'#s=(s,[])
n#s|(r,l)<-f s=(l++)<$>pred n#r

Essayez-le en ligne!

Il doit y avoir un meilleur moyen de gérer le cas arity-1, il prend actuellement 45 octets.

Modifications:

  • -2 octets en passant à une méthode différente de traitement 1, bien que la méthode précédente ait probablement plus de potentiel d'optimisation.
  • -3 octets en ne convertissant pas les chiffres des caractères en nombres et en utilisant predau lieu de n-1.
unlines.snd.f
f(n:r)|(m,t)<-span(>'9')r,(s,l)<-read[n]#t,w<-map((' '<$(n:n:m))++)=(s,last$((n:m):w l):[(n:m++' ':h):w t|n<'2',h:t<-[l]])
f e=(e,["0"])
0#s=(s,[])
n#s|(r,l)<-f s=(l++)<$>(n-1)#r

Essayez-le en ligne!

Laikoni
la source
1

Fusain , 75 octets

FS⊞υ⎇⁼ιM⁺⊟υιι≔⮌υυ≔⟦⟧θ≔⟦⟧ηW∨υη«≔⎇υ⊟υ0ιι¿⊖Σι↘→⊞θι⊞ηΣιW∧η¬§η±¹«⊟ηM⊕L⊟θ←¿η⊞η⊖⊟η

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

FS⊞υ⎇⁼ιM⁺⊟υιι

Parcourez les caractères saisis et transformez-les en une liste de chiffres avec des Msuffixes facultatifs .

≔⮌υυ

Inversez cette liste afin que nous puissions l'utiliser Poppour la consommer.

≔⟦⟧θ

Cette variable est une pile de jetons dont l'arité n'est pas encore remplie.

≔⟦⟧η

Cette variable est une pile de l'arité restante des jetons non remplis.

W∨υη«

Répétez jusqu'à ce que nous ayons consommé tous les jetons et vidé la pile.

     ≔⎇υ⊟υ0ι

Obtenez le prochain jeton ou 0sinon.

     ι¿⊖Σι↘→

Imprimez le jeton, puis déplacez le curseur horizontalement s'il commence par une 1autre diagonale.

     ⊞θι⊞ηΣι

Ajoutez le jeton et son arité aux variables appropriées.

     W∧η¬§η±¹«

Répétez l'opération pendant que la pile d'arités n'est pas vide mais l'arité supérieure est nulle.

              ⊟η

Jeter l'arité zéro.

              M⊕L⊟θ←

Retirez son jeton et déplacez autant de personnages qu'il reste.

              ¿η⊞η⊖⊟η

S'il reste des arités, décrémentez l'arité supérieure.

Neil
la source