Kod Objaśnienie Formater

32

Udane zgłoszenia do gry w golfa są z natury pełne szalonych symboli w każdym miejscu. Aby ułatwić ich złożenie, wielu golfistów decyduje się na wyjaśnienie swojego kodu. W ich wyjaśnieniu linia kodu jest przekształcana w schemat rozłożony pionowo.

Na przykład, gdyby to był mój kod:

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

Jeden z wielu możliwych diagramów, które mógłbym stworzyć, mógłby wyglądać następująco:

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

Cel

W tym wyzwaniu napiszesz narzędzie do automatycznego formatowania objaśnień, które pobiera wiersz kodu i tworzy diagram, do którego można łatwo dodać tekst objaśniający.

Aby uczynić to bardziej użytecznym wyzwaniem, użytkownik będzie mógł określić zawartość każdego wiersza, podając ciąg formatujący. Łańcuch formatujący będzie drugim wierszem zawierającym tylko litery A-Za-zo tej samej długości co program. Litery pokazują kolejność, w jakiej znaki programu powinny być drukowane w objaśnieniu.

Oto przykład operacji we / wy bez formatowania przypominającego nawiasy :

123423
AabcBC

1     
    2 
     3
 2    
  3   
   4  

Wsporniki

Jeśli więcej niż jeden znak w programie ma ten sam poziom priorytetu, wówczas ten zestaw znaków działa jak pojedynczy blok kodu (jeśli tworzą grupę) lub zestaw nawiasów (jeśli zawierają inne znaki pomiędzy nimi). Ogólne zasady są proste:

  1. Znaki nie pojawiają się w linii na schemacie, dopóki wszystkie inne znaki o wyższym priorytecie nie pojawią się już w liniach nad nim na schemacie.

  2. Znaki o równym priorytecie są zawsze drukowane w tych samych wierszach. Jeśli określony znak pojawia się w linii, wszystkie inne znaki o równym priorytecie pojawiają się w linii.

  3. Zestaw znaków o jednakowym priorytecie nadal pojawia się w każdej linii, dopóki wszystkie inne znaki w nim zawarte nie pojawią się przynajmniej raz. Pozwala to na konstrukcje „podobne do wsporników”. Jeśli bceabsą to priorytety, to bpostacie pojawią się w drugiej linii (są drugim najwyższym priorytetem) i będą się pojawiać, dopóki nie pojawią się wszystkie ceapostacie. Jeśli ciąg priorytetowy jest abcadeafga, to wszystkie bcdefgsą uważane za zawarte w nim, wszystkie 4 as będą pojawiać się, dopóki nie pojawi gsię.

Więcej wymagań dotyczących formatowania

Wszystkie linie wyjściowe powinny być tej samej długości (długości linii wejściowych), w razie potrzeby wypełnione spacjami. Wiersz programu wejściowego może zawierać spacje, chociaż spacje te również otrzymają literę priorytetową. Końcowe znaki nowej linii na wyjściu / wejściu są opcjonalne.

Punktacja

To jest kod golfowy, wygrywa najmniej bajtów.


Przykłady

Oto skomentowany przykład fragmentu kodu o bardziej złożonym formatowaniu.

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

Przykład w Perlu:

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

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

Oto kilka przykładów w CJam, dzięki uprzejmości Martina Büttnera:

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$}*}/

Oto szalony przykład, aby z tobą zadzierać:

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

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

Oto bardziej wyraźny przykład tego, co się dzieje, gdy nawiasy się pokrywają abab. (Zwykle nie jest to sposób, w jaki zdecydowałbyś się sformatować wyjaśnienie).

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.
PhiNotPi
źródło

Odpowiedzi:

14

Pyth, 33 40 bajtów

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

Wypróbuj online: Pyth Compiler / Executor

Wyjaśnienie:

Wygenerowano z ciągiem znaków 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

Więc pierwsza linia wejściowa to zdruga linia wejściowa J.

Pętla iteruje wszystkie znaki Jw posortowanej kolejności i bez duplikatów. Obecny znak jest nazywany H.

Następnie dla każdego Yz Jnich drukuję odpowiedni znak zlub biały znak, w zależności od tego, czy spełnione są oba następujące warunki:

  • Y <= H(znak pojawia się po raz pierwszy w linii H)
  • istnieje znak d >= H, który pojawia się w bloku rozpoczynającym się i kończącym na Y(nawiasy).

Przykłady

To pokazuje, jak linia dalej od wejścia abcdaeb, abcdaebjest drukowana. Czwarta linia to dobra reprezentacja, ponieważ zdarza się większość możliwych przypadków:

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

I inny przykład oparty na przypadku testowym, @Optimizer dał mi. (co zniszczyło moje 33 rozwiązanie).

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

Stara wersja: 58 57 52 bajtów

JwKNFHS{J=K.e?eS>_>[email protected]?@zknYNdK=KXKHN

Wypróbuj online: Pyth Compiler / Executor

To tworzy maskę, którą zmodyfikuję przed i po wydrukowaniu każdej linii. Aby uzyskać więcej informacji, zobacz historię edycji.

Jakube
źródło
8

CJam, 82 bajty

Obecnie dość długo i myślę, że mogę zgolić jeszcze kilka bajtów.

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

Algorytm

Podstawowy algorytm wygląda następująco:

  • leel:F]z::+ : Zgrupuj kod, formatowanie i indeks każdego znaku razem
  • F$_&\f{{W=1$=},\;}: Zgrupuj powyższe trojaczki według priorytetu drukowania za pomocą ciągu formatującego. Ten kod zapewnia również sortowanie priorytetów.
  • ]_{0f=_W=),\0=>Lf&Ra#)},: Dla każdej grupy priorytetowej trojaczki uzyskaj zakres indeksu granicznego i sprawdź, czy jakikolwiek indeks nie jest jeszcze wydrukowany. Jeśli istnieje niezadrukowany indeks, włącz tę grupę priorytetów do grupy „do wydrukowania w tym kroku”.
  • F,S*\:+{~;1$L+:L;t}%oNo~}%: Po otrzymaniu wszystkich grup do wydrukowania w tym kroku, wpisz kod do właściwego indeksu pustego ciągu znaków, a następnie wydrukuj ten ciąg. Zaktualizuj także tablicę zawierającą listę wydrukowanych indeksów.

Wyjaśnienie kodu, którego należy przestrzegać, gdy skończę grać w golfa.

Przykład

Oto kod uruchamiany na samym kodzie:

Wkład:

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

Wydajność:

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~}%];

Wypróbuj online tutaj

Optymalizator
źródło
oNomożna zastąpić nw TIO .
Esolanging Fruit
8

CJam, 48 bajtów

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

Wyjaśnienie

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.
jimmy23013
źródło
6

IDL 8.4, 316 318 304 bajtów

Nowa wersja, wciąż za długa, ale krótsza! I, w prawdziwym duchu IDL, całkowicie wektoryzowany, co oznacza (ponieważ nie ma pętli for), że mogę teraz zrobić to jako jedną linię i uruchomić go na sobie, gdy tylko moja wersja zostanie całkowicie zaktualizowana do wersji 8.4. To będzie edytowane później.

Wersja jednoliniowa:

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

Z podziałem wierszy (ta sama liczba bajtów, napisy \ n vs i) i komentowany:

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

Oto podział algorytmiczny dla linii 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)

... i 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

Wiersze 9 i 10 wykonują prawdziwą pracę, reszta ustawia zmienne potrzebne do końca. Wydaje mi się, że jest to tak gra w golfa, jak to możliwe, nie mogę znaleźć nigdzie indziej, aby zrobić to lepiej.

Stara wersja (wszystko poniżej jest nieaktualne):

Nie jest to wystarczająco krótkie, aby wygrać, ponieważ jest to okropny język golfa, ale nikt nigdy nie odpowiada w IDL, więc po prostu pójdę po niego.

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

Nie jestem pewien, czy jest jakiś sposób, żeby to jeszcze bardziej zmniejszyć ... Mógłbym wywołać strmid na obu A i B w tym samym czasie, ale potem spędzam więcej bajtów na indeksowaniu D i to działa tak samo. Nadal będę nad tym pracować! (A jutro będę edytować wyjaśnienie algorytmu.)

sirpercival
źródło