Перетворіть експоненти в ASCII мистецтво


28

Завдання

Ваше завдання - перетворити рядки таким чином:

abc^d+ef^g + hijk^l - M^NO^P (Ag^+)

До таких струн:

   d   g       l    N P    +
abc +ef  + hijk  - M O  (Ag )

Який наближення до abc d + ef g + hijk l - M N O P (Ag + )

Словами піднесіть персонажів безпосередньо поруч із доглядом до верхньої лінії, один символ на одну карету.

Технічні характеристики

  • Допускаються додаткові пробіли білого проміжку на виході.
  • Ніякі прикуті до них послуги m^n^oне будуть надаватися як вхідні дані.
  • Карета не буде супроводжуватися відразу пробілом або іншою каретою.
  • Кареті не передує відразу пробіл.
  • Будь-яким символам передує щонайменше один персонаж, а за ним - принаймні один символ.
  • Рядок введення міститиме лише символи для друку ASCII (U + 0020 - U + 007E)
  • Замість двох рядків виводу вам дозволяється виводити масив з двох рядків.

Для тих, хто говорить регулярний вираз: вхідний рядок буде відповідати цьому регулярному вираженню:

/^(?!.*(\^.\^|\^\^|\^ | \^))(?!\^)[ -~]*(?<!\^)$/

Таблиця лідерів


2
@TimmyD "Вхідний рядок міститиме лише символи для друку ASCII (U + 0020 - U + 007E)"
Leaky Nun,

3
Навіщо зупинятися на показниках? Я хочу щось, що обробляє H_2O!
Ніл

1
@Neil Зробіть свій власний виклик, і я можу закрити це завдання як дублікат цього. :)
Leaky Nun

1
Виходячи з вашого прикладу, я б сказав, що вони є супеніндами , а не обов'язковими показниками
Луїс Мендо,

4
Ті, хто розмовляє з регулярною виразкою, приїжджають із надзвичайно регулярної країни, де вираз жорстко обмежений. Провідна причина смерті - катастрофічне зволікання.
Девід Конрад

Відповіді:


19

V , 15 14 байт

ÄÒ +òf^xxé kPj

Спробуйте в Інтернеті!

Досить прямолінійне рішення. Ідеальний виклик для V!

Пояснення:

Ä                "Duplicate this current line
 Ò               "Replace this line with spaces
   +             "Move to the beginning of the next line
    ò         ò  "Recursively (The second ò is implicit):
     f^          "  Find a caret
       xx        "  Delete two characters. The second will be saved into the main register
         é       "  Insert a space
           k     "  Move up
            P    "  Paste from the main register
             j   "  Move down

Зручно, виходячи з того, як працює рекурсія, це буде працювати один раз на кожну карету.


2
vim - ідеальна мова для цього завдання. +1
Пуховик

18

Чеддар, 77 72 67 байт

l->l.chars.vfuse.replace("^\n"," ").lines.map(j->"%-2s"%j).turn(3)

Без регексу!

Я люблю цю відповідь, оскільки це чудова демонстрація здібностей Чеддара. В основному завдяки функції заміни, яку додав Conor. PR до dev ніколи не робився, тому функція заміни існує лише на цій гілці (оновлення: я зробив PR і тепер він знаходиться на останній бета-гілці, яку можна встановити npm install -g cheddar-lang)

Я знайшов спосіб пограти в нього, але, на жаль, нагляд призводить до цього, коли довжина предметів не однакова:

["   denifednud   denifednug       denifednul    denifednuN denifednuP    denifednu+ ", "abcdenifednu +efdenifednu  + hijkdenifednu  - Mdenifednu Odenifednu  (Agdenifednu )"]

Я міг би зберегти багато байтів за допомогою регексу, а насправді я просто зробив регулярні вирази для Cheddar ... єдина проблема полягає в тому, що немає функцій регулярного вираження: /

Пояснення

l->                    // Function take input as `l`
   l.chars             // Get array of chars in input
   .vfuse              // Join with newlines
   .replace("^\n"," ") // Replace `^\n` with a space globally
   .lines              // Get the lines (see below for more details on what this returns)
   .map(j->            // Loop through each "line" `j` is arg
       "%-2s"          // C-like printf format.
                       // think of as: padRight(j, " ", 2)
                       // see below for more details
        % j            // Pass j as the string to insert
   ).turn(3)           // Turn the string 270 degrees (see below)
   .vfuse              // Vertically fuse to get result (this is not needed as we can output an array of the lines)

Щоб краще зрозуміти. Це те, .linesза що повертається1^2

["1", " 2"]

.turnз поворотом цим:

1
 2

в:

 2
1

Ще один приклад, який стане більш зрозумілим:

1
 2
2
 2

стає:

 2 2
1 2

Чому формат?

Що %-2sробити досить просто. %вказує, що ми починаємо "формат", або що змінна буде вставлена ​​в цей рядок в цей момент. -означає праворуч накладати рядок, і 2це максимальна довжина. За замовчуванням це прокладки з пробілами. sпросто вказує, що це рядок. Щоб побачити, що це робить:

"%-2s" % "a"  == "a "
"%-2s" % " a" == " a"

2
: DI завжди підтримує чеддер.
DJMcMayhem

@DrGreenEggsandIronMan: D дякую
Пуховик

1
У Чеддара є turnметод для рядків?
TuxCrafting

6
-1 назва цієї мови завжди змушує мене голодувати.
перестала повертати проти годинника,

@ TùxCräftîñg лише для 2D-масивів, саме тому я використовував .lines для отримання рядків.
Пуховик

10

Perl, 21 + 1 = 22 байти

say'';s/\^(.)/♥[A\1↓/

Біжи з -pпрапором. Замініть необмеженим ESCбайтом ( 0x1b) та вертикальною вкладкою ( 0x0b).

Вертикальна вкладка - ідея Мартіна Ендера. Це врятувало два байти! Спасибі.


Чи не потрібно вам рухати курсор вниз по лінії на початку, щоб експоненти не перекривали останній запит консолі?
Мартін Ендер

Я не був у цьому впевнений, так. Я зробив припущення, що маю стільки місця, скільки мені потрібно, але, можливо, це трохи обманливо. (Взагалі, я не дуже пишаюся тим, що використовую рухи курсору для вирішення подібної проблеми, але це перше, що мені прийшло в голову ...)
Lynn

2
Я думаю, що це прекрасне рішення, але результат повинен бути візуально невідрізним від друку рядка за призначенням.
Мартін Ендер

1
Яке прекрасне рішення
Томас Веллер

7

JavaScript (ES6), 56 55 байт

s=>[/.(\^(.))?/g,/\^.(())/g].map(r=>s.replace(r,' $2'))

Зрозуміло, що виручає на допомогу. Перший замінює всі символи пробілами, якщо він не знайде каре, і в такому випадку він видаляє карету і зберігає персонажа після нього. (Ці символи гарантовано існують.) Другий - очевидний, щоб замінити кожну карету та її наступний символ пробілом.

Редагувати: Збережено 1 байт завдяки @Lynn, який розробив спосіб повторного використання рядка заміни для другої заміни, що дозволить відображати заміну через масив регулярних виразів.


2
Схоже s=>[/.(\^(.))?/g,/\^.(())/g].map(r=>s.replace(r,' $2')), байт коротший.
Лінн

@Lynn Це справді хитрий трюк!
Ніл

7

Python 3, 157 101 98 85 83 74 байт

Це рішення відстежує, чи був попередній символ ^, а потім вирішує, виходити на перший чи другий рядок на основі цього.

Виводи як масив ['firstline', 'secondline'].

a=['']*2
l=0
for c in input():x=c=='^';a[l]+=c*x;a[~l]+=' '*x;l=x
print(a)

Збережено 13 15 байт завдяки @LeakyNun!

Збережено 7 байт завдяки @Joffan!


1
Хороший автомат з кінцевим станом.
Лина монашка

Чи було б краще мати a=['','']і об'єднуватись ' 'і cбезпосередньо в a[l]і a[~l]?
Йофан

6

Python 2, 73 байти

l=['']*2;p=1
for c in input():b=c!='^';l[p]+=c*b;l[~p]+=' '*b;p=b
print l

Без регексу. Пам'ятає, чи був попередній символ ^, і поклав поточний символ у верхній або нижній рядок на основі цього, а пробіл в іншому.


4

Піт, 17 байт

CcsmX~Z1j;d;cQ\^2

             Q      input string
            c \^    split on '^'
   m                map for sections d:
    X      ;          insert a space at index:
     ~Z1                the old value of Z (initially 0), before setting Z to 1
                      into:
        j;d             the section joined on spaces
  s                 concatenate
 c              2   chop into groups of 2
C                   transpose

Повертає масив з 2 рядків. (Попередьте jприєднатись до них з новим рядком.)

Спробуйте в Інтернеті .


1
Я не можу перестати дивуватися, як вимовляється ваше прізвище. : D
Лінн

4

MATL , 18 байт

94=t1YSt~&vG*cw~Z)

Спробуйте в Інтернеті!

94=    % Take input implicitly. Create logical array of the same size that contains
       % true for carets, false otherwise
t      % Push a copy of this array
1YS    % Circularly shift 1 unit to the right. This gives an array that contains true
       % for the elements right after a caret (superindices), and false for the rest 
t~     % Push a copy and negate
&v     % Concatenate vertically. This gives a 2D, 2-row array
G*     % Push the input again, multiply with broadcast. This gives a 2D array in
       % which the first row contains the superindices (characters after a caret)
       % and 0 for the rest; and the second row contains the non-superindices and
       % 0 for the superindices
c      % Convert to char
w      % Swap. Brings to top the array containing true for carets and false otherwise
~      % Negate
Z)     % Use as logical index to remove rows that contain carets. Display implicitly

4

Ruby, 47 + 1 ( -nпрапор) = 48 байт

puts$_.gsub(/\^(.)|./){$1||" "},gsub(/\^./," ")

Виконайте так: ruby -ne 'puts$_.gsub(/\^(.)|./){$1||" "},gsub(/\^./," ")'


Я думаю, ви можете зберегти 1 байт за допомогою $_=$_.gsub(/\^(.)|./){$1||" "}+gsub(/\^./," ")та -pзамість -n.
Дом Гастінгс

1
@DomHastings незалежно від того, працює він чи ні, у вашого коду, схоже, немає нового рядка, і додавання +$/означає, що він не збирається зберігати байти. putsкидає в новий рядок для вас автоматично, коли ,аргумент присутній між аргументами.
Значення чорнила

Ох, я тестував за допомогою, ruby -p ... <<< 'input'але я згоден, якщо у ньому відсутній новий рядок, це не добре! Насправді мені, можливо, раніше був доданий новий рядок у мої тести ... Це було на роботі, хоча я не можу перевірити!
Дом Гастінгс

@DomHastings Переглянувши це ще раз, я здогадуюсь, що це тому, getsщо більшу частину часу включає тривалий новий рядок, але якщо ви передасте файл, який не містить задніх рядків, то він не з’явиться, і вихід буде неправильним . Перевірте свій код, ruby -p ... inputfileоскільки Ruby перенаправляє getsфайл у файл, якщо це аргумент командного рядка.
Значення чорнила

Зрозумів, має ідеальний сенс. Я думаю, що останній рядок у файлі також вирішить проблему. Я жодним чином не досвідчений рубіст, тому відчуваю, що сьогодні дізнався трохи більше про це. Спасибі!
Дом Гастінгс

3

Пітон (2), 76 68 67 байт

-5 байт завдяки @LeakyNun

-3 байти завдяки @ KevinLau-notKenny

-1 байт завдяки @ValueInk

-0 байт завдяки @DrGreenEggsandIronMan

import re
lambda i,s=re.sub:[s("(?<!\^).\^?"," ",i),s("\^."," ",i)]

Ця анонімна функція лямбда приймає рядок введення як єдиний аргумент і повертає два вихідні рядки, розділені новим рядком. Щоб зателефонувати, дайте йому ім'я, написавши перед ним "f =".

Досить прямий вираз: Перша частина замінює наступне пробілом: будь-який персонаж і каре з моркви або лише чарка, але лише якщо перед ними немає ніякої карети. Друга частина замінює будь-яку каре в рядку та знаку після неї пробілом.


@LeakyNun: Мені чомусь було цікаво, чи 1. також, якщо я імпортую бібліотеки. Копіював 2. у це питання прямо зараз, коли я побачив ваш коментар. Дякую тобі та Кевіну!
KarlKastor

Ви можете зняти один байт зfrom re import*
DJMcMayhem

@DrGreenEggsandIronMan Це, здається, використовує точно таке ж число байтів. (див. вище)
КарлКастор

Збережіть стару заяву про імпорт та виконайте lambda i,s=re.sub:[s("(?<!\^).\^?"," ",i),s("\^."," ",i)]-1 байт
Value Ink


2

Сітківка, 16 байт

S`^
\^(.)
♥[A$1↓

Порт моєї відповіді Perl, вказаний Мартіном Ендером. Замініть необмеженим ESCбайтом ( 0x1b) та вертикальною вкладкою ( 0x0b).


2

оболонка + TeX + catdvi, 51 43 байт

tex '\empty$'$1'$\end'>n;catdvi *i|head -n2

Використовує texдля набору гарної математики, а потім використовує catdviдля подання тексту. Команда head видаляє небажаний (нумерація сторінок, виведення нових рядків), який є в іншому випадку.

Редагувати: Навіщо робити довгі, правильні речі та перенаправлення, /dev/nullколи ви можете ігнорувати побічні ефекти та писати в один лист?


Приклад

Вхід: abc^d+ef^g + hijk^l - M^NO^P (Ag^+)

Вихід TeX (обрізаний до рівняння): "Прекрасна" математика! Кінцевий вихід:

   d   g     l  N P   +
abc +ef +hijk -M O (Ag )

Припущення: Почніть з порожнього dir (або конкретно з dir без імені, що закінчується на "i"). Введення - це єдиний аргумент сценарію оболонки. Введення не є порожнім рядком.

Хтось скаже мені, якщо це правило зловживання, особливо catdvi.


2

Haskell, 74 56 55 байт

g('^':c:r)=(c,' '):g r
g(c:r)=(' ',c):g r
g x=x
unzip.g

Повертає пару рядків. Приклад використання: unzip.g $ "abc^d+e:qf^g + hijk^l - M^NO^P: (Ag^+)"->(" d g l N P + ","abc +e:qf + hijk - M O : (Ag )")

gскладає список пар, де перший елемент є знаком у верхній рядку, а другий - символом у нижньому рядку. unzipперетворює це на пару списків.

Редагувати: @xnor запропонував unzipзберегти 18 байт. @Laikoni знайшов ще один байт для збереження. Спасибі!


Можна зробити j=unzip.g?
xnor

@xnor: о, як нерозумно я не бачу цього! Дуже дякую!
німі

Ви можете замінити g[]=[]з , g x=xщоб зберегти один байт.
Laikoni

@Laikoni: Добре помічений! Спасибі!
німі

1

Perl, 35 байт

34 байти код + 1 для -p

$_=s/\^(.)|./$1||$"/ger.s/\^./ /gr

Використання

perl -pe '$_=s/\^(.)|./$1||$"/ger.s/\^./ /gr' <<< 'abc^d+ef^g + hijk^l - M^NO^P (Ag^+)'
   d   g       l    N P    + 
abc +ef  + hijk  - M O  (Ag )

Примітка: Це точно так само, як відповідь Value Ink , яку я шпигував згодом. Видаляється, якщо потрібно, оскільки це насправді не додає до рішення Ruby.


1

Java 8 лямбда, 132 128 112 символів

i->{String[]r={"",""};for(char j=0,c;j<i.length();j++){c=i[j];r[0]+=c==94?i[++j]:32;r[1]+=c==94?32:c;}return r;}

Необоротна версія виглядає так:

public class Q86647 {

    static String[] printExponents(char[] input) {
        String[] result = {"",""};
        for (char j = 0, c; j < input.length(); j++) {
            c = input[j];
            result[0] += c == 94 ? input[++j] : 32;
            result[1] += c == 94 ? 32 : c;
        }
        return result;
    }
}

Виводиться як масив, просто перевіряючи, чи є карета, і якщо так, наступний символ буде розміщений у верхньому рядку, інакше буде пробіл.


Оновлення

Замінено символів з їх значеннями ascii, щоб зберегти 4 символи.

Дякуємо @LeakyLun за те, що він вказав на використання масиву char як вхідного.

Також спасибі @KevinCruijssen за переключення intна, charщоб зберегти ще кілька символів.


Ви можете спробувати ввести char[]та використати, for(char c:i)щоб побачити, чи можна зменшити кількість байтів.
Leaky Nun

Ви можете покатати його трохи до 110 байт, використовуючи: i->{String[]r={"",""};for(char j=0,c;j<i.length;j++){c=i[j];r[0]+=c==94?i[++j]:32;r[1]+=c==94?32:c;}return r;}з "abc^d+ef^g + hijk^l - M^NO^P (Ag^+)".toCharArray()введенням. ( Ідея цих змін. )
Кевін Кройсейсен

1

Кокосовий горіх , 122 114 96 байт

Змінити: 8 26 байт вниз за допомогою Leaky Nun.

def e(s,l)=''==l and s or"^"==l[0]and l[1]+e(s+' ',l[2:])or' '+e(s+l[0],l[1:])
f=print..e$('\n')

Отже, як я дізнався сьогодні, у python є термінальний умовний оператор, або насправді два з них: <true_expr> if <condition> else <false_expr>і <condition> and <true_expr> or <false_expr>останній приходить з одним char менше.
Версію, відповідна пітону, можна уявити .


Перша спроба:

def e(s,l):
 case l:
  match['^',c]+r:return c+e(s+' ',r)
  match[c]+r:return' '+e(s+c,r)
 else:return s
f=print..e$('\n')

Дзвінки з f("abc^d+ef^g + hijk^l - M^NO^P (Ag^+)")відбитками

   d   g       l    N P    +
abc +ef  + hijk  - M O  (Ag )

Хтось ще спробував гольф у кокосі? Він збагачує python більш функціональними поняттями програмування, такими як узгодження шаблонів і з'єднання функцій (з ..), що використовуються вище. Оскільки це моя перша спроба кокосового горіха, будь-які поради будуть вдячні.

Це безумовно можна скоротити, оскільки будь-який дійсний код python також є дійсним кокосовим горіхом, а короткі відповіді python були розміщені, проте я намагався знайти суто функціональне рішення.


Я думаю, що ви можете використовувати потрійні оператори ( x and y or z) для заміни case.
Leaky Nun

Можна навіть використовувати s[0]=="^"замістьmatch['^',c]+r in l
Leaky Nun

@LeakyNun Коли я замінити match['^',c]+rз s[0]=="^", то cі rбільше не пов'язані. Як би це допомогло?
Лайконі

Ви можете використовувати s[1]для заміни cта s[2:]заміни r.
Leaky Nun

тоді ви можете використовувати термінал зараз.
Leaky Nun

0

Діалог APL, 34 байти

{(0 1=⊂b/¯1⌽b){⍺\⍺/⍵}¨⊂⍵/⍨b←⍵≠'∧'}

Він повертає двоелементний вектор з двома лініями

Пробіг зразків (удар вгору попереду полягає у форматуванні двоелементного вектора для споживання людиною):

      ↑{(0 1=⊂b/¯1⌽b){⍺\⍺/⍵}¨⊂⍵/⍨b←⍵≠'∧'}'abc∧d+ef∧g + hijk∧l - M∧NO∧P (Ag∧+)'
   d   g       l    N P    + 
abc +ef  + hijk  - M O  (Ag )

На ваш коментар до мого запитання про код, що нічого не робить: так, той код, який ви ставите, рахується.
хайкам

0

PowerShell v2 +, 88 83 байти

-join([char[]]$args[0]|%{if($c){$_;$b+=' '}elseif($_-94){$b+=$_;' '}$c=$_-eq94});$b

Трохи довше інших, але демонструє трохи магії PowerShell і трохи іншу логіку.

По суті те саме поняття, що й відповідь Python - ми повторюємо вхідний символ за символом, пам’ятаємо, чи був попередній знак каретою ( $c) і ставимо поточний символ у відповідне місце. Однак логіка та метод визначення місця виведення обробляються дещо інакше, і без кортежу чи окремих змінних - ми перевіряємо, чи попередній символ був каретою, і якщо так, виведіть персонаж у конвеєр і з'єднайте простір на $b. В іншому випадку ми перевіряємо, чи є поточний персонаж каретою, elseif($_-94)і доки його немає, ми з'єднуємо поточний символ на $bта виводимо пробіл у конвеєр. Нарешті, ми встановимо, чи є поточний персонаж піклуванням для наступного кругообігу.

Ми збираємо цих персонажів з трубопроводу разом у парени, інкапсулюємо їх в а, -joinщо перетворює їх у рядок, і залишаємо це разом з $bна конвеєрі. Висновок в кінці мається на увазі між новим рядком між ними.

Для порівняння, ось прямий порт відповіді Python @ xnor на 85 байт :

$a=,''*2;[char[]]$args[($l=0)]|%{$a[!$l]+="$_"*($c=$_-ne94);$a[$l]+=' '*$c;$l=!$c};$a

0

Гема, 42 41 символ

\^?=?@set{s;$s }
?=\ @append{s;?}
\Z=\n$s

Gema обробляє введення як потік, тому вам доведеться вирішити його за один прохід: перший рядок записується негайно як оброблений, другий рядок збирається в змінну $ s, потім виводиться в кінці.

Проба зразка:

bash-4.3$ gema '\^?=?@set{s;$s };?=\ @append{s;?};\Z=\n$s' <<< 'abc^d+ef^g + hijk^l - M^NO^P (Ag^+)'
   d   g       l    N P    +  
abc +ef  + hijk  - M O  (Ag )

0

Кориця гумка, 21 байт

0000000: 5306 6533 bd92 d1db 8899 8381 a2f8 8f8c  S.e3............
0000010: 1230 249e a1                             .0$..

Без конкуренції Спробуйте в Інтернеті.

Пояснення

Я не дуже гольфіст з реджексу, тому, мабуть, є кращий спосіб зробити це.

Рядок декомпресується на:

S(?<!\^)[^^]& &\^&`S\^.& 

(відзначте пробіл)

Перший Sетап отримує вхід і використовує негативний погляд позаду, щоб замінити всі символи, крім карток, без попередньої каретки на пробіл, а потім видаляє всі кадри. Потім він негайно виводить модифікований рядок введення з новим рядком і видаляє цей Sетап. Оскільки STDIN зараз вичерпаний, і попередній етап не надав жодного вводу, наступний Sетап знову отримує останній рядок STDIN, а потім замінює всі опіки, за якими слідує будь-який символ, на пробіл і виводи, які.

У пседе-коді Perl:

$first_stage_sub_1 = ($input =~ s/(?<!\^)[^^]/ /gr);
$first_stage_sub_2 = ($first_stage_sub_1 =~ s/\^//gr);
print $first_stage_sub_2, "\n";

$second_stage_sub = ($input =~ s/\^./ /gr);
print $second_stage_sub, "\n";

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