Uraikan komentar dari kode esoteris saya


30

Awal minggu ini, kami belajar tentang cara memformat bahasa esoterik untuk berkomentar. Hari ini, kita akan melakukan kebalikannya. Saya ingin Anda menulis sebuah program atau fungsi yang mem-parsing beberapa kode esoterik yang dikomentari dengan baik dan mem-parsing komentar, hanya mengembalikan kode. Dengan menggunakan beberapa contoh dari tantangan sebelumnya, di sini terlihat seperti apa kode yang dikomentari dengan baik:

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

Inilah yang perlu Anda lakukan untuk mengekstrak kode. Pertama, hapus karakter komentar ( #), spasi sebelum, dan semuanya setelah karakter komentar.

a               
 bc             
   d            
    e           
     fgh        
        ij      
          k     
           l    
            mn  
              op

Kemudian, pisahkan setiap baris ke atas menjadi satu baris. Misalnya, karena bberada di kolom kedua di baris dua, setelah kami menutupnya, itu akan berada di kolom kedua di baris pertama . Demikian pula, cakan diletakkan di kolom ketiga baris satu, dan dakan diletakkan di keempat. Ulangi ini untuk setiap karakter, dan Anda mendapatkan ini:

abcdefghijklmnop

Catatan penting: Sepertinya solusi sepele adalah dengan hanya menghapus komentar, menghapus setiap spasi, dan bergabung dengan setiap baris. Ini bukan pendekatan yang valid! Karena kode asli mungkin memiliki spasi di dalamnya, ini akan dihapus dengan pendekatan ini. Misalnya, ini adalah input yang benar-benar valid:

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

Dan output yang sesuai harus:

hello  world!

Tantangan:

Tulis program atau fungsi yang mengambil kode komentar sebagai input, dan mengeluarkan atau mengembalikan kode dengan semua komentar diuraikan darinya. Anda harus mengeluarkan kode tanpa spasi tambahan, meskipun satu baris tambahan diizinkan. Karakter komentar akan selalu ada #, dan akan selalu ada satu ruang ekstra sebelum komentar dimulai. tidak# akan muncul di bagian komentar dari input. Agar tantangannya lebih sederhana, berikut adalah beberapa input yang tidak harus Anda tangani:

  • Anda dapat mengasumsikan bahwa kode tidak akan memiliki dua karakter di kolom yang sama. Misalnya, ini adalah input yang melanggar aturan ini:

    a  #A character in column one
    bc #Characters in columns one and two
    
  • Anda juga dapat mengasumsikan bahwa semua karakter komentar muncul di kolom yang sama. Misalnya, input ini:

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

    melanggar aturan ini. Ini juga berarti bahwa #tidak akan ada di bagian kode.

  • Dan terakhir, Anda tidak harus menangani bagian kode dengan spasi awal atau akhir. Sebagai contoh,

      Hello,          #
             World!   #
    

Anda juga dapat mengasumsikan bahwa input hanya berisi karakter ASCII yang dapat dicetak.

Contoh:

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!

Anda dapat mengambil input dalam format beralasan apa pun yang Anda suka, misalnya, daftar string, string tunggal dengan baris baru, daftar karakter 2d, dll. Jawaban terpendek dalam byte menang!


Apakah kita perlu menerima kode dengan karakter lebih rendah dari yang berikutnya?
wizzwizz4

Bisakah Anda menambahkan test case dengan garis kosong hanya dengan dua spasi (seperti yang hello world!Anda tunjukkan)? Selain itu, Anda menyatakan: " #tidak akan muncul di bagian komentar dari input. ", Tetapi bisakah itu terjadi di cuplikan-kode itu sendiri?
Kevin Cruijssen

@KevinCruijssen Lihat hasil edit saya
DJMcMayhem

@ wizzwizz4 Saya tidak yakin apakah saya mengerti pertanyaan Anda
DJMcMayhem

Contoh @DJMcMayhem: do {stuff} while (condition);dengan penjelasan dalam urutan do while (condition); #Explainythingkemudian {stuff} #Explainything.
wizzwizz4

Jawaban:


18

Jelly , 8 7 byte

»/ṣ”#ḢṖ

Cobalah online!

Bagaimana itu bekerja

»/ṣ”#ḢṖ  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
That is just ...wow.
Jonathan Allan

3
I am so jelly right now.
MonkeyZeus

How do you even hack that into your phone?
simbabque

2
@simbabque Patience and a lot of copy-pasting.
Dennis

I'm always putting using a 9-iron, maybe it's time I learned how to use a putter when on the green...
Magic Octopus Urn

13

Python 2, 48 43 bytes

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

Thanks to @xnor for golfing off 5 bytes!

Test it on Ideone.


1
I think you can just do map(max,*x) because max takes any number of arguments and None is small.
xnor

Right, I always forget that map can be used like that... Thanks!
Dennis

1
How does the `...`[2::5] trick work?
smls

1
@smls `...` is equivalent to repr(...), so for the list of singleton strings ['a', 'b', 'c'], you get the string "['a', 'b', 'c']". Finally, [2::5] chops off the first two characters ("['") and takes every fifth character of the remaining string.
Dennis

5

JavaScript (ES6), 97 75 60 bytes

Thanks to @Neil for helping golf off 22 bytes

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

Input is an array of lines.

  • a is array input
  • p is previous item
  • c is current item
  • m is match string
  • o is offset

I count 96 bytes? Also, the m regexp flag is unnecessary (did you have a $ at one point?) as is the space in (p, c). Finally, I think replace will work out shorter than [...p].map().join.
Neil

97 for me, both from manual length and userscript, maybe you didn't count the newline, but only because I accidentally included the semicolon
ASCII-only

I see now - I hadn't copied the ; which isn't required (JavaScript has ASI).
Neil

Yeah, sorry, I had it to make sure Chromium console puts the function call outside the function body (had it once on a badly written lambda)
ASCII-only

Oh wow, I didn't realise replace would help so much, that's really neat!
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 bytes

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

Takes a list of strings as input. Basically uses the same approach as Dennis in his Jelly answer.

Commented and explained

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

f =: magic over maxes

Intermediate steps:

   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? 

Test case

   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 bytes

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

Takes input as an array of strings.

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

Pyke, 15 10 bytes

,FSe)s\#ch

Try it here!

Port of the Jelly answer

,          -     transpose()
 FSe)      -    map(min, ^)
     s     -   sum(^)
      \#c  -  ^.split("#")
         h - ^[0]

1

C# 157 122 Bytes

Golfed 35 bytes thanks to @milk -- though I swear I tried that earlier.

Takes input as a 2-d array of characters.

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 bytes:

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');}

Shouldn't Trim() work instead of TrimEnd()? Even better, I think you can save a lot of bytes by using s[0] as the output var and using return new string(s[0],0,i) where i is the index of the last code character. That idea may require two for loops instead of the foreach, I'll think about it more and try to write actual code later today.
milk

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\#

A program that takes input of a list of strings on STDIN and prints a string.

Try it online

How it works

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 bytes

: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,...$,,

Requires a newline at the end of the input.
I'm sure I can golf this a little more, but I'm just happy it works for now.



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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.