Formateur d'explication de code


32

Les soumissions réussies de golf de code sont, par nature, remplies de symboles fous partout. Pour rendre leur soumission plus facile à comprendre, de nombreux golfeurs de code choisissent d'inclure une explication de leur code. Dans leur explication, la ligne de code est transformée en un diagramme éclaté verticalement.

Par exemple, si c'était mon code:

1_'[3:~2@+]`

L'un des nombreux diagrammes possibles que je pourrais créer ressemblerait à ceci:

1           
 _'         
   [      ] 
   [3:    ] 
   [  ~   ] 
   [   2@ ] 
   [     +] 
           `

Le but

Dans ce défi, vous allez écrire un outil de mise en forme automatique d'explication qui prend une ligne de code et crée un diagramme auquel du texte explicatif peut être facilement ajouté.

Afin d'en faire un défi plus utile , l'utilisateur pourra spécifier le contenu de chaque ligne, en fournissant une chaîne de formatage. La chaîne de formatage sera une deuxième ligne, contenant uniquement des lettres A-Za-z, de la même longueur que le programme. Les lettres indiquent l'ordre dans lequel les caractères du programme doivent être imprimés dans l'explication.

Voici un exemple d'E / S sans formatage de type crochet :

123423
AabcBC

1     
    2 
     3
 2    
  3   
   4  

Supports

Si plusieurs caractères dans le programme ont le même niveau de priorité, alors cet ensemble de caractères agit comme un seul bloc de code (s'ils forment un groupe) ou un ensemble de crochets (s'ils contiennent d'autres caractères entre les deux). Les règles générales sont simples:

  1. Les caractères n'apparaissent sur une ligne du diagramme que lorsque tous les autres caractères de priorité supérieure sont déjà apparus sur les lignes au-dessus du diagramme.

  2. Les caractères de priorité égale sont toujours imprimés sur les mêmes lignes. Si un certain caractère apparaît sur une ligne, tous les autres caractères de priorité égale apparaissent sur la ligne.

  3. Un ensemble de caractères de priorité égale continue d'apparaître sur chaque ligne jusqu'à ce que tous les autres caractères qu'il contient soient apparus au moins une fois. Cela permet des constructions de type "support". Si ce bceabsont les priorités, les bcaractères apparaîtront sur la deuxième ligne (ils sont la deuxième priorité) et continueront à apparaître jusqu'à ce que tous les ceacaractères soient apparus. Si la chaîne prioritaire est abcadeafga, alors tous bcdefgsont considérés comme contenus dans celle-ci, un all 4 as continuera à apparaître jusqu'à ce que le gsoit apparu.

Plus d'exigences de formatage

Toutes les lignes de sortie doivent avoir la même longueur (la longueur des lignes d'entrée), avec des espaces si nécessaire. La ligne de programme d'entrée peut contenir des espaces, bien que ces espaces reçoivent également une lettre de priorité. Les retours à la ligne en fin de sortie / entrée sont facultatifs.

Notation

C'est le golf de code, le moins d'octets gagne.


Exemples

Voici un exemple commenté d'un morceau de code avec une mise en forme plus complexe.

1_'[3:~2@+]`
abbcddeffgch

1            #highest priority is denoted by the lowercase letter a
 _'          #priority b
   [      ]  #all characters with priority c
   [3:    ]  #priority d, but priority c still printed because it encloses more
   [  ~   ]  #priority e
   [   2@ ]  #priority f
   [     +]  #priority g, last line of c because all enclosed characters have appeared
           ` #priority h

Un exemple en Perl:

$_=<>;s/[^aeiou\W]/$&o$&/gi;print
aaaaaabbccccccccccbdddddbbbbeeeee

$_=<>;                           
      s/          /     /gi;     
      s/[^aeiou\W]/     /gi;     
      s/          /$&o$&/gi;     
                            print

Voici quelques exemples dans CJam, gracieuseté de Martin Büttner:

l~2*{_2%{3*)}{2/}?_p_(}g;
aabbcdddefffeeggeehhiiccj

l~                       
  2*                     
    {                 }g 
    {_2%              }g 
    {   {   }{  }?    }g 
    {   {3*)}{  }?    }g 
    {   {   }{2/}?    }g 
    {             _p  }g 
    {               _(}g 
                        ;

q{_eu'[,66>"EIOU"-#)g{'o1$}*}/
abcccddddddeeeeeeefgghiijjhhbb

q                             
 {                          }/
 {_eu                       }/
 {   '[,66>                 }/
 {         "EIOU"-          }/
 {                #         }/
 {                 )g       }/
 {                   {    }*}/
 {                   {'o  }*}/
 {                   {  1$}*}/

Voici un exemple fou juste pour jouer avec vous:

1_'[3:~2@+]`
azTABACBDCAT

   [ :    ] 
   [3: 2  ] 
   [3:~2 +] 
   [ :~ @+] 
  '        `
1           
 _          

Voici un exemple plus explicite de ce qui se passe lorsque les crochets se chevauchent comme abab. (Normalement, ce n'est pas la façon dont vous choisissez de formater votre explication.)

aabbccddaaeebb
aabbccddaaeebb

aa      aa    
aabb    aa  bb
aabbcc  aa  bb
aabb  ddaa  bb
  bb      eebb #"aa" no longer appears because all of "bbccdd" have already appeared.

Réponses:


14

Pyth, 33 40 octets

JwFHS{Js.e?@zk&gHYsm&gdH}d>_>JxJYx_JYJdJ

Essayez-le en ligne: Pyth Compiler / Executor

Explication:

Généré avec la chaîne aabbbbbzccdeeegfffqhjiiikkpnmmllloooohec:

                                          implicit: z = first input line
Jw                                        J = second input line
  FHS{J                                   for H in sorted(set(J)):
        .e                             J    map each k,Y of enumerate(J) to:
        .e?                            J      .... if ... else ...
        .e @zk                        dJ      z[k] if ... else " "
                                              condition: 
        .e @zk gHY                    dJ        H >= Y
        .e @zk&                       dJ        and
        .e @zk     m                 JdJ        map each d of J to:
        .e @zk     m gdH             JdJ          d >= H
        .e @zk     m&                JdJ          and
        .e @zk     m    }d           JdJ          d in ...
        .e @zk     m          xJY    JdJ          index of Y in J
        .e @zk     m        >J       JdJ          substring of J (from index to end)
        .e @zk     m       _         JdJ          reverse substring
        .e @zk     m             x_JYJdJ          index of Y in reversed J
        .e @zk     m      >          JdJ          substring of reversed (from index to end)
        .e @zk    s                   dJ       sum up the booleans (acts as any)
       s                                    sum up the chars and print

Ainsi, la première ligne d'entrée est z, la deuxième ligne d'entrée est J.

La boucle itère sur tous les caractères de Jdans l'ordre trié et sans doublons. Le caractère actuel est appelé H.

Ensuite , pour chaque Yde Jj'imprimer le char correspondant de zou espaces blancs, selon si les deux conditions suivantes sont remplies:

  • Y <= H(un caractère apparaît d'abord dans la ligne H)
  • il y a un caractère d >= H, qui apparaît dans un bloc commençant et finissant par Y(crochets).

Exemples

Cela montre comment la ligne en avant de l'entrée abcdaeb, abcdaebest imprimée. La quatrième ligne est une bonne représentation, car la plupart des cas possibles se produisent:

code input:  "abcdaeb"
order input: "abcdaeb"

printing the fourth line, H = "d":

   "a" is printed, because "a" <= "d" and ("d" >= "d" and "d" is in "abcda")
   "b" is printed, because "b" <= "d" and ("d" >= "d" and "d" is in "bcdaeb")
   "c" are not printed, because neither "d" nor "e" (chars >= "d") are not in "c"
   "d" is printed, because "d" <= "d" and ("d" >= "d" and "d" is in "d")
   "a" is printed, because "a" <= "d" and ("d" >= "d" and "d" is in "abcda")
   "e" is not printed, because "e" > "d"
   "b" is printed, because "b" <= "d" and ("d" >= "d" and "d" is in "bcdaeb")

therefore the fourth line is: aabb__ddaa__bb

Et un autre exemple basé sur un cas de test, @Optimizer m'a donné. (qui a détruit ma 33 solution).

code input:  "acab"
order input: "acab"

printing the second line, H = "b":

   "a" is printed, because "a" <= "b" and ("c" >= "b" and "c" is in "aca")
   "c" is not printed, because "c" > "b"
   "a" is printed, because "a" <= "b" and ("c" >= "b" and "c" is in "aca")
   "b" is printed, because "b" <= "b" and ("b" >= "b" and "b" is in "b")

therefore the second line is: a_ab

Ancienne version: 58 57 52 octets

JwKNFHS{J=K.e?eS>_>JxJHx_JHqYH@KkJs.e?@zknYNdK=KXKHN

Essayez-le en ligne: Pyth Compiler / Executor

Cela crée un masque, que je modifierai avant et après l'impression de chaque ligne. Pour plus d'informations, consultez l'historique des modifications.


8

CJam, 82 octets

Assez long actuellement et je pense que je peux raser quelques octets de plus.

leel:F]z::+F$_&\f{{W=1$=},\;}{]_{0f=_W=),\0=>Lf&Ra#)},F,S*\:+{~;1$L+:L;t}%oNo~}%];

Algorithme

L'algorithme de base est le suivant:

  • leel:F]z::+ : Regrouper le code, la mise en forme et l'index de chaque caractère
  • F$_&\f{{W=1$=},\;}: Groupez les triplets ci-dessus en priorité d'impression à l'aide de la chaîne de formatage. Ce code garantit également que les priorités sont triées.
  • ]_{0f=_W=),\0=>Lf&Ra#)},: Pour chaque groupe prioritaire de triplets, obtenez la plage d'index de délimitation et voyez si aucun index n'est encore imprimé. S'il existe un index non imprimé, incluez ce groupe de priorité dans le groupe "à imprimer dans cette étape".
  • F,S*\:+{~;1$L+:L;t}%oNo~}%: Après avoir obtenu tous les groupes à imprimer dans cette étape, remplissez le code dans l'index correct d'une chaîne d'espace vide, puis imprimez cette chaîne. Mettez également à jour le tableau contenant la liste des index imprimés.

Explication du code à suivre lorsque j'aurai fini de jouer au golf.

Exemple

Voici le code exécuté sur le code lui-même:

Contribution:

leel:F]z::+F$_&\f{{W=1$=},\;}{]_{0f=_W=),\0=>Lf&Ra#)},F,S*\:+{~;1$L+:L;t}%oNo~}%];
aaabbbcccccdddddeefgghhiffggejkklmmmnoooopppqrrrssssllttttuuuvwwxxxxxxxyvvzzzzjjjj

Sortie:

lee                                                                               
   l:F                                                                            
      ]z::+                                                                       
           F$_&\                                                                  
                f{          }                                                     
                f{{     },  }                                                     
                f{{W=   },\;}                                                     
                f{{W=1$ },\;}                                                     
                f{{W=  =},\;}                                                     
                             {                                                }%];
                             {]_                                              }%];
                             {  {                   },                        }%];
                             {  {0f=                },                        }%];
                             {  {   _               },                        }%];
                             {  {    W=),           },                        }%];
                             {  {        \0=        },                        }%];
                             {  {           >       },                        }%];
                             {  {            Lf&    },                        }%];
                             {  {               Ra#)},                        }%];
                             {                        F,S*                    }%];
                             {                            \:+                 }%];
                             {                               {          }%    }%];
                             {                               {~;        }%    }%];
                             {                               {  1$L+:L; }%    }%];
                             {                               {         t}%    }%];
                             {                                            oNo~}%];

Essayez-le en ligne ici


oNopeut être remplacé par ndans TIO .
Esolanging Fruit

8

CJam, 48 octets

ll:i:T.{___T#TW%@#~T<>+:e>)1$-@*123Se]m>}z_|(;N*

Explication

l                                                Code.
 l                                               Priority.
  :i                                             Convert priority to integer.
    :T                                           Save to T.
      .{                                }        For corresponding items:
      .{___                             }        Copy the current priority 3 times.
      .{   T#                           }        First position with this priority.
      .{     TW%                        }        Reverse T.
      .{        @#                      }        First (last) position with this priority.
      .{          ~T<                   }        Cut T at the end of this priority.
      .{             >                  }        Cut at the beginning of this priority.
      .{              +                 }        Insert the current priority to
                                                 prevent the array being empty.
      .{               :e>              }        Array maximum.
      .{                  )1$-          }        Count of integers between the current
                                                 priority and the maximum, inclusive.
      .{                      @*        }        That number of the current character.
      .{                        123Se]  }        Fill irrelevant priorities with spaces.
      .{                              m>}        Rotate the array to make non-spaces
                                                 starting at the current priority.
                                                 Returns a column containing 123 items.
                                         z       Zip to get the rows from columns.
                                          _|     Remove duplicate rows, including
                                                 unused priorities and all-space rows.
                                            (;   Remove the first row (an all-space row).
                                              N* Insert newlines.

6

IDL 8.4, 316 318 304 octets

Nouvelle version, encore trop longue, mais plus courte! Et, dans le véritable esprit d'IDL, complètement vectorisé, ce qui signifie (puisqu'il n'y a pas de boucle) que je peux maintenant le faire en une seule ligne et l'exécuter sur lui-même, une fois que ma version est complètement mise à niveau vers 8.4. Cela sera édité plus tard.

Version une ligne:

c=(f='')&read,c,f&l=[0:strlen(f)-1]&c=strmid(c,l,1)&s=strmid(f,l,1)&u=s.uniq()&k=value_locate(u,s)&n=[0:max(k)]&d=hash(n,u.map(lambda(x,y,z:max(z[(r=stregex(y,'('+x+'(.*))?'+x,len=w)):r+w-1])),f,k))&print,n.map(lambda(n,l,c,d,i:i.reduce(lambda(x,i,l,c,d,n:x+(d[l[i]]ge n?c[i]:' ')),l,c,d,n)),k,c,d,l)&end

Avec des sauts de ligne (même nombre d'octets, sous-traitance \ n vs &), et commenté:

c=(f='') ;initialize code and format as strings
read,c,f ;read two lines of input from the prompt
l=[0:strlen(f)-1] ;index array for the strings
c=strmid(c,l,1) ;split the code string into an array, via substrings of length 1
s=strmid(f,l,1) ;same for the format string, saving f for regex later
u=s.uniq() ;get the sorted unique values in the format string (sorts A->a)
k=value_locate(u,s) ;assign layer values to the format characters
n=[0:max(k)] ;index array for the unique format characters
d=hash(n,u.map(lambda(x,y,z:max(z[(r=stregex(y,'('+x+'(.*))?'+x,len=w)):r+w-1])),f,k))
print,n.map(lambda(n,l,c,d,i:i.reduce(lambda(x,i,l,c,d,n:x+(d[l[i]]ge n?c[i]:' ')),l,c,d,n)),k,c,d,l)
end ;end the script

Voici une ventilation algorithmique pour la ligne 9:

r=stregex(y,'('+x+'(.*))?'+x,len=w) ; r, w = starting position & length of substring in y {format string} bracketed by x {character} (inclusive)
z[(r=...):r+w-1] ; grab a slice of z {layer array} from r to r+w-1 -> layer values for each character in the substring
max(z[...]) ; max layer (depth) of any characters in that slice
u.map(lambda(x,y,z:max(...)),f,k) ;map an inline function of the above to every element of the unique-formatting-character array
d=hash(n,u.map(...)) ; create a hash using the unique indices, the result is a hash of (character:max_substring_depth)

... et 10:

x+(d[l[i]]ge n?c[i]:' ')) ; ternary concatenation: if maxdepth for this character >= current depth, add the character, otherwise add ' '
i.reduce(lambda(x,i,c,d,l,n:...)),,l,c,d,n) ;accumulate elements of i {code/format index array} by passing them through the inline ternary concatenation function
print,n.map(lambda(n,l,c,d,i:i.reduce(...)),k,c,d,l) ;map the depth index through the reduction, ending up with a string for each depth layer, then print it

Les lignes 9 et 10 font le vrai travail, le reste définit les variables dont vous avez besoin pour la fin. Je pense que c'est à peu près aussi golfé que ça va devenir, je ne peux pas trouver d'autre endroit pour le faire mieux.

Ancienne version (tout ce qui suit ici est obsolète):

C'est loin d'être assez court pour gagner, car c'est un langage de golf terrible, mais personne ne répond jamais en IDL, donc je vais juste y aller.

a=(b='')
read,a,b
c=[0:strlen(b)-1]
d=strmid(b,c,1)
a=strmid(a,c,1)
e=d[uniq(d,sort(d))]
f=list(value_locate(e,d),/e)
s=hash()
for i=0,max(f)do begin
g=stregex(b,'('+e[i]+'(.*))?'+e[i],l=l)
s[i]=max(f[g:g+l-1])
print,f.reduce(lambda(x,y,z:x+(s.haskey(y)?z[y]:' '),s,a)
s=s.filter(lambda(x,y:x[1]gt y),i)
endfor
end

Je ne sais pas s'il y a un moyen de le réduire davantage ... Je pourrais appeler strmid à la fois sur a et b en même temps, mais je passe plus d'octets à indexer d et cela fonctionne de la même manière. Mais je continuerai à y travailler! (Et demain je vais éditer une explication de l'algorithme.)

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.