Розбирайте коментарі з мого езотеричного коду


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!

Ви можете взяти вхід у будь-якому розумному форматі, наприклад, список рядків, одна рядок з новими рядками, 2d список символів тощо. Найкоротший відповідь у байтах виграє!


Чи потрібно нам приймати код із символами, нижчими від наступних?
wizzwizz4

Чи можете ви додати тестовий випадок із порожнім рядком із лише двох пробілів (як hello world!показано вами)? Крім того, ви заявляєте: " #не відображатиметься в розділі коментарів вхідних даних. ", Але чи може це відбутися в самому фрагменті коду?
Kevin Cruijssen

@KevinCruijssen Дивіться мої зміни
DJMcMayhem

@ wizzwizz4 Я не впевнений, чи розумію ваше запитання
DJMcMayhem

@DJMcMayhem Приклад: do {stuff} while (condition);з поясненням в порядку do while (condition); #Explainythingтоді {stuff} #Explainything.
wizzwizz4

Відповіді:


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-праску, можливо, саме час я навчився користуватися шпателем, коли на зеленому ...
Magic Octopus Urn

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 компенсується

Я рахую 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

Пітон 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');}

Не слід Trim()працювати замість TrimEnd()? Ще краще, я думаю, ви можете зберегти багато байтів, використовуючи s [0] як вихідний var і використовуючи, return new string(s[0],0,i)де iіндекс останнього символу коду. Ця ідея може зажадати двох forциклів замість того foreach, що я подумаю більше про це і спробую написати фактичний код пізніше сьогодні.
молоко

Trim()Вирізаємо також з самого початку, що, на мою думку, не було б дійсним. Я також спочатку робив завантаження в s [0], і у мене був int i;за межами циклу (щоб повторно його використовувати у відповідь), який, на мою думку, зрештою додав байти
pinkfloydx33

1

Pyth, 11 байт

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

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.