Разобрать комментарии из моего эзотерического кода

30

Ранее на этой неделе мы узнали о том, как форматировать эзотерические языки для комментариев. Сегодня мы собираемся сделать обратное. Мне нужно, чтобы вы написали программу или функцию, которая анализирует некоторый хорошо прокомментированный эзотерический код и анализирует комментарии, возвращая только код. Используя некоторые примеры из предыдущего вызова, вот как выглядит хорошо прокомментированный код:

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

Вот что вам нужно сделать, чтобы извлечь код. Сначала удалите символ комментария ( #), пробел перед ним и все после символа комментария.

a               
 bc             
   d            
    e           
     fgh        
        ij      
          k     
           l    
            mn  
              op

Затем сверните каждую строку вверх в одну строку. Например, поскольку он bнаходится во втором столбце второй строки, как только мы свернем его, он будет во втором столбце первой строки . Аналогично, cбудет помещен в третий столбец первой строки и dбудет помещен в четвертый. Повторите это для каждого персонажа, и вы получите это:

abcdefghijklmnop

Важное примечание: кажется, что тривиальное решение состоит в том, чтобы просто удалить комментарии, удалить все пробелы и присоединить каждую строку. Это не обоснованный подход! Поскольку в исходном коде могут быть пробелы, при таком подходе они будут удалены. Например, это совершенно правильный ввод:

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

И соответствующий вывод должен быть:

hello  world!

Соревнование:

Напишите программу или функцию, которая принимает закомментированный код в качестве входных данных и выводит или возвращает код со всеми проанализированными комментариями. Вы должны вывести код без концевых пробелов, хотя допустим один завершающий символ новой строки. Символ комментария всегда будет #, и перед началом комментариев всегда будет один дополнительный пробел. не# будет отображаться в разделе комментариев ввода. Чтобы упростить задачу, вот некоторые входные данные, которые вам не нужно обрабатывать:

  • Можно предположить, что в коде не будет двух символов в одном столбце. Например, это входные данные, которые нарушают это правило:

    a  #A character in column one
    bc #Characters in columns one and two
    
  • Вы также можете предположить, что все символы комментария появляются в одном столбце. Например, этот вход:

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

    нарушает это правило. Это также означает, что #не будет в разделе кода.

  • И, наконец, вам не нужно обрабатывать участки кода с начальными или конечными пробелами. Например,

      Hello,          #
             World!   #
    

Вы также можете предположить, что ввод содержит только печатные символы ASCII.

Примеры:

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!

Вы можете вводить данные в любом разумном формате, который вам нравится, например, в виде списка строк, одной строки с символами новой строки, 2-го списка символов и т. Д. Самый короткий ответ в байтах побеждает!

DJMcMayhem
источник
Нужно ли принимать код с символами ниже следующего?
wizzwizz4 13.09.16
Не могли бы вы добавить контрольный пример с пустой строкой с двумя пробелами (как hello world!показано на рисунке)? Кроме того, вы заявляете: « #не будет отображаться в разделе комментариев ввода », но может ли это произойти в самом фрагменте кода?
Кевин Круйссен
@KevinCruijssen Смотрите мои правки
DJMcMayhem
@ wizzwizz4 Я не уверен, что понимаю ваш вопрос
DJMcMayhem
@DJMcMayhem Пример: do {stuff} while (condition);с объяснением в порядке do while (condition); #Explainythingтогда {stuff} #Explainything.
wizzwizz4 13.09.16

Ответы:

18

Желе , 8 7 байт

»/ṣ”#ḢṖ

Попробуйте онлайн!

Как это работает

»/ṣ”#ḢṖ  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
Это просто ... вау.
Джонатан Аллан
3
Я так желе прямо сейчас.
MonkeyZeus
Как ты вообще взломал это на свой телефон?
simbabque
2
@simbabque Терпение и много копий-вставок.
Деннис
Я всегда использую 9-железо, может быть, пришло время научиться пользоваться клюшкой, когда я на зеленом ...
Волшебная Осьминога
13

Python 2, 48 43 байта

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

Спасибо @xnor за 5 байтов!

Проверьте это на Ideone .

Деннис
источник
1
Я думаю, что вы можете просто сделать, map(max,*x)потому что maxпринимает любое количество аргументов и Noneмало.
xnor
Правильно, я всегда забываю, что mapможно так использовать ... Спасибо!
Деннис
1
Как работает `...`[2::5]трюк?
Smls
1
@smls `...`эквивалентен repr(...), поэтому для списка одноэлементных строк ['a', 'b', 'c']вы получите строку "['a', 'b', 'c']". Наконец, [2::5]отсекает первые два символа ( "['") и берет каждый пятый символ оставшейся строки.
Деннис
5

JavaScript (ES6), 97 75 60 байт

Спасибо @Neil за помощь гольфу от 22 байтов

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

Ввод представляет собой массив строк.

  • a это массив ввода
  • p предыдущий элемент
  • c это текущий элемент
  • m это строка соответствия
  • o смещен
ASCII-только
источник
Я считаю 96 байт? Кроме того, mфлаг регулярного выражения является ненужным (у вас было $в одной точке?), Как и пространство в (p, c). Наконец-то думаю replaceполучится короче [...p].map().join.
Нил
97 для меня, как из руководства, так lengthи из пользовательского сценария, может быть, вы не считали перевод строки, но только потому, что я случайно включил точку с запятой
только ASCII
Теперь я вижу - я не скопировал то, ;что не требуется (JavaScript имеет ASI).
Нил
Да, извините, у меня было это, чтобы убедиться, что консоль Chromium помещает вызов функции за пределы тела функции (было ли это однажды на плохо написанной лямбде)
только ASCII
Ого, я не знала, replaceчто так сильно поможет, это действительно здорово!
Нил
4

Perl, 35 34 32 байта

Включает +1 для -p

Внести вклад в STDIN

eso.pl

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

Обратите внимание, что после финала есть место ;. Код работает, как показано, но заменяется \0литеральным символом, чтобы получить заявленную оценку.

Тон Хоспел
источник
Очень хороший код Это $a|=...довольно хорошо сделано, мне понадобилось время, чтобы понять, что вы делаете! Хотя один вопрос: *_=aкажется, примерно эквивалентно $_=$a, почему это так?
Дада
*_=aэто очень непонятное _глобальное назначение, которое совмещает глобалы и aглобалы. Так что это не столько копия $aс , $_но с этого момента (глобальный) $aи $_фактически та же переменная. Все, чтобы сохранить 1 байт ...
Тон Хоспел
Хорошо, спасибо за объяснение! (и хорошее улучшение благодаря `$ \`)
Dada
3

Python 2, 187 байт

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

Я буду играть в гольф еще завтра у меня будет школа;)

Даниил
источник
1 forможет быть уменьшен до 1for. Кроме того, если сумма списка (в строке 5) не может быть отрицательной, вы можете просто проверить <1вместо ==0. Счастливого школьного дня! : D +1.
Yytsi
2

CJam , 12 байт

Спасибо Sp3000 за сохранение 2 байта.

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

Безымянный блок, который принимает список строк (по одной на каждую строку) и заменяет его одной строкой.

Попробуйте онлайн!

объяснение

:.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 байт

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

Принимает список строк в качестве входных данных. В основном использует тот же подход, что и Деннис в своем ответе на желе.

Прокомментировал и объяснил

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

f =: magic over maxes

Промежуточные шаги:

   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? 

Прецедент

   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 байта

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

Принимает ввод как массив строк.

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 байта

Гольф 35 байтов благодаря @milk - хотя, клянусь, я пробовал это раньше.

Вводит в виде двумерного массива символов.

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 байтов:

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');}
pinkfloydx33
источник
Не должно Trim()работать вместо TrimEnd()? Более того, я думаю, что вы можете сэкономить много байтов, используя s [0] в качестве выходной переменной и используя return new string(s[0],0,i)where iиндекс последнего символа кода. Эта идея может потребовать двух forциклов вместо foreach, я подумаю об этом больше и попытаюсь написать реальный код позже сегодня.
молоко
Trim()будет урезать с самого начала, что я считаю, не будет действительным. Я также первоначально делал загрузку в s [0], и у меня было int i;вне цикла (чтобы повторно использовать его в возврате), который, я считаю, в конечном итоге добавил байты
pinkfloydx33
1

Pyth, 11 байт

PhceCSMCQ\#

Программа, которая принимает ввод списка строк в STDIN и печатает строку.

Попробуйте онлайн

Как это работает

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
TheBikingViking
источник
1

sed, 126 байтов

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

Требуется новая строка в конце ввода.
Я уверен, что могу играть в гольф немного больше, но я просто счастлив, что пока это работает.

Райли
источник
0

Желе , 27 байт

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

Проверьте это в TryItOnline

Использует самую строгую спецификацию - дополнительный пробел перед удалением символа комментария за счет байта.

Ввод представляет собой список строк.

Джонатан Аллан
источник
@ Эрик Гольфист - может быть и так, но ты видел, как он давил меня здесь ?
Джонатан Аллан
0

Рубин, 77 байт

puts File.readlines("stack.txt").join('').gsub(/\s{1}#.*\n/,'').gsub(/\s/,'')
Forwarding
источник
Жесткое кодирование имени файла ввода не является приемлемым методом ввода.
Мего
@ Мего, где я могу найти правила того, что "приемлемо"?
Пересылка
0

TSQL, 216 175 байт

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('%_#%',@))

скрипка

t-clausen.dk
источник
0

Javascript, 56 34 байта, не конкурирует

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

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

Как указал @ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳, я не готов к дополнительным пробелам

судейская шапочка
источник
Не проходит дело «Подготовьтесь к дополнительным пробелам»
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
0

Дьялог АПЛ , 22 байта

Вдохновение .

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

(

⎕UCS символьное представление

¯2↓ все, кроме двух последних

⍳∘35↑ вплоть до позиции первых 35 ("#"), в том, что находится за скобками, взятых из

то, что находится за скобками

) а именно ...

⌈⌿ столбчатые максимумы

из

⎕UCS значения Юникода

Попробуй APL онлайн!

Адам
источник
Сколько байт?
Акролит