Przetwarzaj komentarze z mojego ezoterycznego kodu


30

Na początku tego tygodnia dowiedzieliśmy się, jak formatować ezoteryczne języki do komentowania. Dzisiaj zrobimy coś odwrotnego. Potrzebuję napisać program lub funkcję, która analizuje dobrze skomentowany ezoteryczny kod i analizuje komentarze, zwracając tylko kod. Korzystając z przykładów z poprzedniego wyzwania, oto jak wygląda dobrze skomentowany kod:

a                #Explanation of what 'a' does
 bc              #Bc
   d             #d
    e            #Explanation of e
     fgh         #foobar
        ij       #hello world
          k      #etc.
           l     #so on
            mn   #and
              op #so forth

Oto, co musisz zrobić, aby wyodrębnić kod. Najpierw usuń znak komentarza ( #), spację przed nim i wszystko po znaku komentarza.

a               
 bc             
   d            
    e           
     fgh        
        ij      
          k     
           l    
            mn  
              op

Następnie zwinąć każdą linię w górę w jedną linię. Na przykład, ponieważ bznajduje się w drugiej kolumnie na drugiej linii, raz my zwinąć ją w górę, to będzie w drugiej kolumnie na linii jednego . Podobnie czostanie umieszczony w trzeciej kolumnie pierwszego wiersza i dumieszczony w czwartej. Powtórz to dla każdej postaci, a otrzymasz:

abcdefghijklmnop

Ważna uwaga: wydaje się, że trywialnym rozwiązaniem jest po prostu usunięcie komentarzy, usunięcie każdej spacji i dołączenie do każdej linii. To nie jest prawidłowe podejście! Ponieważ oryginalny kod może zawierać spacje, zostaną one usunięte dzięki temu podejściu. Na przykład jest to całkowicie poprawne wejście:

hello         #Line one
              #Line two
       world! #Line three

Odpowiednim wyjściem powinno być:

hello  world!

Wyzwanie:

Napisz program lub funkcję, która pobiera skomentowany kod jako dane wejściowe i wysyła lub zwraca kod ze wszystkimi parsowanymi komentarzami. Powinieneś wypisać kod bez spacji końcowych, chociaż dozwolony jest jeden znak nowej linii. Komentarz zawsze będzie #i zawsze będzie jedno dodatkowe miejsce przed rozpoczęciem komentarzy. #będzie nie pojawiają się w sekcji komentarzy na wejściu. Aby uprościć wyzwanie, oto niektóre dane wejściowe, z którymi nie musisz sobie poradzić:

  • Możesz założyć, że kod nie będzie zawierał dwóch znaków w tej samej kolumnie. Na przykład jest to dane wejściowe, które naruszają tę zasadę:

    a  #A character in column one
    bc #Characters in columns one and two
    
  • Możesz również założyć, że wszystkie znaki komentarza pojawiają się w tej samej kolumnie. Na przykład to wejście:

    short       #this is a short line
          long        #This is a long line
    

    narusza tę zasadę. Oznacza to również, że #nie będzie go w sekcji kodu.

  • I na koniec, nie musisz obsługiwać sekcji kodu ze spacjami wiodącymi lub końcowymi. Na przykład,

      Hello,          #
             World!   #
    

Możesz również założyć, że dane wejściowe zawierają tylko drukowalne znaki ASCII.

Przykłady:

Input:
hello         #Line one
              #Line two
       world! #Line three

Output:
hello  world!

Input:
E                                                   #This comment intentionally left blank
 ac                                                 #
   h s                                              #
      ecti                                          #
          on is                                     #
                one c                               #
                     haracte                        #
                            r longer                #
                                     than the       #
                                              last! #

Output:
Each section is one character longer than the last!

Input:
4          #This number is 7
 8         #
  15       #That last comment is wrong.
    16     #
      23   #
        42 #

Output:
4815162342

Input:
Hello                     #Comment 1
      world               #Comment 2
           ,              #Comment 3
             how          #Comment 4
                 are      #Comment 5
                     you? #Comment 6

Output:
Hello world, how are you?

Input:
Prepare                               #
        for...                        #
                        extra spaces! #

Output:
Prepare for...          extra spaces!

Możesz wprowadzić dane w dowolnym rozsądnym formacie, na przykład, lista ciągów, pojedynczy ciąg znaków z nowymi liniami, 2d lista znaków itp. Wygrywa najkrótsza odpowiedź w bajtach!


Czy będziemy musieli zaakceptować kod ze znakami niższymi niż następny?
wizzwizz4

Czy możesz dodać przypadek testowy z pustą linią z tylko dwiema spacjami (jak hello world!pokazałeś)? Ponadto stwierdzasz: „ #nie pojawi się w sekcji komentarza na wejściu. ”, Ale czy może wystąpić w samym fragmencie kodu?
Kevin Cruijssen

@KevinCruijssen Zobacz moje zmiany
DJMcMayhem

@ wizzwizz4 Nie jestem pewien, czy rozumiem twoje pytanie
DJMcMayhem

@DJMcMayhem przykład: do {stuff} while (condition);z wyjaśnieniami w celu do while (condition); #Explainythingpotem {stuff} #Explainything.
wizzwizz4

Odpowiedzi:


18

Galaretka , 8 7 bajtów

»/ṣ”#ḢṖ

Wypróbuj online!

Jak to działa

»/ṣ”#ḢṖ  Main link. Argument: A (array of strings)

»/       Reduce the columns of A by maximum.
         Since the space is the lowest printable ASCII characters, this returns the
         non-space character (if any) of each column.
  ṣ”#    Split the result at occurrences of '#'.
     Ḣ   Head; extract the first chunk, i.e., everything before the (first) '#'.
      Ṗ  Pop; remove the trailing space.

2
To tylko ... łał.
Jonathan Allan,

3
Jestem teraz bardzo galaretka.
MonkeyZeus,

Jak włamujesz to do swojego telefonu?
simbabque

2
@simbabque Cierpliwość i dużo kopiowania i wklejania.
Dennis

Zawsze stawiam używając 9-żelazka, może nadszedł czas, że nauczyłem się używać puttera, gdy jestem na zielonym ...
Magic Octopus Urn

13

Python 2, 48 43 bajtów

lambda x:`map(max,*x)`[2::5].split(' #')[0]

Dzięki @xnor za grę w golfa z 5 bajtów!

Przetestuj na Ideone .


1
Myślę, że możesz to zrobić, map(max,*x)ponieważ maxwymaga dowolnej liczby argumentów i Nonejest niewielka.
xnor

Racja, zawsze zapominam, że mapmożna tak wykorzystać ... Dzięki!
Dennis

1
Jak działa `...`[2::5]sztuczka?
smls

1
@smls `...`jest równoważne repr(...), więc dla listy ciągów singletonowych ['a', 'b', 'c']otrzymasz ciąg "['a', 'b', 'c']". Na koniec [2::5]odcina pierwsze dwa znaki ( "['") i pobiera co piąty znak pozostałego ciągu.
Dennis

5

JavaScript (ES6), 97 75 60 bajtów

Dzięki @Neil za pomoc w golfa z 22 bajtów

a=>a.reduce((p,c)=>p.replace(/ /g,(m,o)=>c[o])).split` #`[0]

Dane wejściowe to tablica wierszy.

  • a to wejście tablicowe
  • p jest poprzednim przedmiotem
  • c jest bieżącym przedmiotem
  • m jest dopasowanym ciągiem
  • o jest przesunięty

Zliczam 96 bajtów? Ponadto mflaga wyrażenia regularnego jest niepotrzebna (czy miałeś kiedyś $punkt?) , Podobnie jak miejsce (p, c). Wreszcie myślę, że replacebędzie działać krócej niż [...p].map().join.
Neil

97 dla mnie, zarówno z instrukcji, jak lengthi skryptu użytkownika, może nie policzyłeś nowego wiersza, ale tylko dlatego, że przypadkowo umieściłem średnik
tylko ASCII

Rozumiem teraz - nie skopiowałem tego, ;co nie jest wymagane (JavaScript ma ASI).
Neil

Tak, przepraszam, musiałem upewnić się, że konsola Chromium umieszcza wywołanie funkcji poza ciałem funkcji (kiedyś było to na źle napisanej lambda)
tylko ASCII

Och, wow, nie zdawałem sobie sprawy, replaceże to tak bardzo pomoże, to naprawdę fajnie!
Neil

4

Perl, 35 34 32 bytes

Includes +1 for -p

Give input on STDIN

eso.pl

#!/usr/bin/perl -p
y/ /\0/;/.#/;$\|=$`}{$\=~y;\0; 

Notice that there is a space after the final ;. The code works as shown, but replace \0 by the literal character to get the claimed score.


Very nice code. That $a|=... is rather well done, it took me a while to figure out what you were doing! One question though : *_=a seems to be roughly equivalent to $_=$a, why is that?
Dada

*_=a is a very obscure glob assignment which aliases the _ globals and the a globals. So it's not so much a copy from $a to $_ but from that point on (global) $a and $_ are actually the same variable. All to save 1 byte...
Ton Hospel

Ok, thanks for the explanation! (and nice improvement thanks to `$\`)
Dada

3

Python 2, 187 bytes

def f(x,o=""):
 l=[i[:i.index("#")-1]for i in x]
 for n in range(len(l[0])):
  c=[x[n]for x in l]
  if sum([1for x in c if x!=" "])<1:o+=" "
  else:o+=[x for x in c if x!=" "][0]
 print o

I'm gonna golf this more tomorrow I have school ;)


1 for can be reduced to 1for. Also, if the sum of the list (at line 5) can't be negative, you can just check for <1 instead of ==0. Happy school day! :D +1.
Yytsi


2

CJam, 12 bytes

Thanks to Sp3000 for saving 2 bytes.

{:.e>_'##(<}

An unnamed block that takes a list of strings (one for each line) and replaces it with a single string.

Try it online!

Explanation

:.e>  e# Reduce the list of strings by elementwise maximum. This keeps non-spaces in
      e# favour of spaces. It'll also wreak havoc with the comments, but we'll discard
      e# those anyway.
_'##  e# Duplicate and find the index of '#'.
(<    e# Decrement that index and truncate the string to this length.

2

J, 30 bajtów

(#~[:<./\'#'~:])@(>./&.(3&u:))

Bierze listę ciągów jako dane wejściowe. Zasadniczo używa tego samego podejścia, co Dennis w swojej odpowiedzi na galaretkę.

Skomentował i wyjaśnił

ord =: 3 & u:
under =: &.
max =: >./
over =: @
maxes =: max under ord
neq =: ~:
arg =: ]
runningMin =: <./\
magic =: #~ [: runningMin ('#' neq arg)

f =: magic over maxes

Kroki pośrednie:

   p
Hello                     #Comment 1
      world               #Comment 2
           ,              #Comment 3
             how          #Comment 4
                 are      #Comment 5
                     you? #Comment 6
   maxes p
Hello world, how are you? #Comment 6
   magic
#~ ([: runningMin '#' neq arg)
   3 neq 4
1
   '#' neq '~'
1
   '#' neq '#'
0
   '#' neq maxes p
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1
   runningMin 5 4 2 5 9 0 _3 4 _10
5 4 2 2 2 0 _3 _3 _10
   runningMin '#' neq maxes p
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
   0 1 0 1 1 0 # 'abcdef'
bde
   'abcdef' #~ 0 1 0 1 1 0
bde
   (maxes p) #~ runningMin '#' neq maxes p
Hello world, how are you? 
   (#~ [: runningMin '#' neq arg) maxes p
Hello world, how are you? 
   ((#~ [: runningMin '#' neq arg) over maxes) p
Hello world, how are you? 
   (magic over maxes) p
Hello world, how are you? 

Przypadek testowy

   f =: (#~[:<./\'#'~:])@(>./&.(3&u:))
   a
Hello                     #Comment 1
      world               #Comment 2
           ,              #Comment 3
             how          #Comment 4
                 are      #Comment 5
                     you? #Comment 6
   $a
6 36
   f a
Hello world, how are you?

2

JavaScript (ES6), 63 bajty

a=>a.reduce((p,c)=>p+/(.+?)\s+#/.exec(c)[1].slice(p.length),'')

Pobiera dane wejściowe jako tablicę ciągów.

F=a=>a.reduce((p,c)=>p+/(.+?)\s+#/.exec(c)[1].slice(p.length),'')

input.oninput = update;
update();

function update() {
  try {
    output.innerHTML = F(input.value.trim().split`
`);
  } catch(e) {
    output.innerHTML = 'ERROR: INVALID INPUT';
  }
}
textarea {
  width: 100%;
  box-sizing: border-box;
  font-family: monospace;
}
<h2>Input:</h2>
<textarea id="input" rows="8">
a                #Explanation of what 'a' does
 bc              #Bc
   d             #d
    e            #Explanation of e
     fgh         #foobar
        ij       #hello world
          k      #etc.
           l     #so on
            mn   #and
              op #so forth
</textarea>
<hr />
<h2>Output:</h2>
<pre id="output">
</pre>




1

C # 157 122 Bytes

Grał w golfa 35 bajtów dzięki @milk - chociaż przysięgam, że próbowałem wcześniej.

Pobiera dane wejściowe jako tablicę 2-d znaków.

string f(char[][]s){int i=0;foreach(var x in s)for(i=0;x[i]!=35;i++)if(x[i]!=32)s[0][i]=x[i];return new string(s[0],0,i);}

157 bajtów:

string g(char[][]s){var o=new char[s[0].Length];foreach(var x in s)for(int i=0;x[i]!=35;i++)if(x[i]!=32|o[i]<1)o[i]=x[i];return new string(o).TrimEnd('\0');}

Nie powinno Trim()działać zamiast TrimEnd()? Co więcej, myślę, że można zaoszczędzić wiele bajtów, używając s [0] jako wyjściowego var i używając return new string(s[0],0,i)gdzie ijest indeksem ostatniego znaku kodu. Pomysł ten może wymagać dwóch forpętli zamiast. foreachZastanowię się nad tym i spróbuję napisać dzisiejszy kod później.
mleko,

Trim() will trim from the start as well, which I believe wouldn't be valid. I also was originally doing the loading into s[0] and I had int i; outside of the loop (to reuse it in the return) which I believe ultimately added bytes
pinkfloydx33

1

Pyth, 11 bytes

PhceCSMCQ\#

Program, który pobiera dane z listy ciągów na STDIN i drukuje ciąg.

Wypróbuj online

Jak to działa

PhceCSMCQ\#  Program. Input: Q
       CQ    Transpose Q
     SM      Sort each element of that lexicographically
    C        Transpose that
   e         Yield the last element of that, giving the program ending with ' #' and some
             parts of the comments
  c      \#  Split that on the character '#'
 h           Yield the first element of that, giving the program with a trailing space
P            All but the last element of that, removing the trailing space
             Implicitly print

1

sed, 126 bajtów

:a;N;$!ba;s,#[^\n]*\n,#,g;s,^,#,;:;/#[^ ]/{/^# /s,^# *,,;t;H;s,#.,#,g}
t;/#[^ ]/!{H;s,#.,#,g};t;g;s,\n#(.)[^\n]*,\1,g;s,...$,,

Wymaga nowego wiersza na końcu danych wejściowych.
Jestem pewien, że mogę trochę więcej zagrać w golfa, ale cieszę się, że teraz działa.



0

Jelly, 27 bytes

żḟ€” ;€” Ḣ€
i€”#’©ḣ@"ç/ḣ®ṪṖ

Test it at TryItOnline

Uses the strictest spec - the extra space before the comment character is removed at the cost of a byte.

Input is a list of strings.


@Erik the Golfer - maybe so, but did you see the crushing he gave me here?
Jonathan Allan


0

TSQL, 216 175 bytes

Golfed:

DECLARE @ varchar(max)=
'hello         #Line one
              #Line two
       world! #Line three'

DECLARE @i INT=1,@j INT=0WHILE @i<LEN(@)SELECT @=stuff(@,@j+1,len(x),x),@j=iif(x=char(10),0,@j+1),@i+=1FROM(SELECT ltrim(substring(@,@i,1))x)x PRINT LEFT(@,patindex('%_#%',@))

Ungolfed:

DECLARE @ varchar(max)=
'hello         #Line one
              #Line two
       world! #Line three'

DECLARE @i INT=1,@j INT=0
WHILE @i<LEN(@)
  SELECT @=stuff(@,@j+1,len(x),x),@j=iif(x=char(10),0,@j+1),@i+=1
  FROM(SELECT ltrim(substring(@,@i,1))x)x
PRINT LEFT(@,patindex('%_#%',@))

Fiddle


0

Javascript, 56 34 bytes, non-competing

q=>q.split(/\n/).map(x=>/ (.?) #./.exec(x)[1]).join()

q=>q.replace(/^ *| *#.*$\n?/gm,'')

As @n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ pointed out, I am not prepared for extra spaces


Doesn't pass the "Prepare for extra spaces" case
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

0

Dyalog APL, 22 bytes

Inspiration.

(⎕UCS¯2↓⍳∘35↑⊢)⌈⌿∘⎕UCS

(

⎕UCS character representation of

¯2↓ all but the last two of

⍳∘35↑ up until the position of the first 35 ("#"), in that which is outside the parenthesis, taken from

that which is outside the parenthesis

) namely...

⌈⌿ the columnar maximums

of

⎕UCS the Unicode values

TryAPL online!


How many bytes?
acrolith
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.