Написання сходів


35

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

Наприклад:

Input: Programming Puzzles and Code Golf


Output: Pr          P           C    G
          ogr        uzzl   and  od   olf
             amm         es        e
                ing

Вхідні дані

Рядок, що не містить нічого, крім букв і пробілів.

Рядок може передаватися через STDINабо функціонувати аргументи або що-небудь еквівалентне.

Букви можуть бути малими або великими.

Вводиться, що введення завжди відповідають цим правилам, вам не потрібно перевіряти неправильні введення.

Вихідні дані

Кожен раз , коли голосний (тобто a, e, i, o, uабо y) зустрічається в слові, ви повинні виводити інші слова на наступному рядку (зустрічається гласний включений), в правильному горизонтальному положенні. Це правило є рекурсивним, а це означає, що якщо в слові є n голосних, воно буде записане у n + 1 рядках.

  • Голосний слід писати на початку наступного рядка, а не в кінці попереднього рядка, коли зустрічається такий.

  • Кожне слово починається з першого рядка і тому має бути відформатоване незалежно від інших слів. Два слова розділені пробілом.

  • Якщо слово починається з голосної, ви повинні написати його, починаючи з другого рядка.

Тестові справи

  • Вхід: Programming Puzzles and Code Golf

Вихід:

Pr          P           C    G
  ogr        uzzl   and  od   olf
     amm         es        e
        ing
  • Вхід: The quick brown fox jumps over the lazy dog

Вихід:

Th  q     br    f   j          th  l    d
  e  u      own  ox  umps ov     e  az   og
      ick                   er        y
  • Вхід: aeiouy

Вихід:

 
a
 e
  i
   o
    u
     y
  • Вхід: YEAh UppErcAsE VOwEls

Вихід:

               V
Y    Upp        Ow
 E      Erc       Els
  Ah       As  
             E
  • Вхід: If you only knew the power of the Dark Side

Вихід:

            kn   th  p        th  D    S
If y   onl    ew   e  ow   of   e  ark  id
    o     y             er                e
     u

Оцінка балів

Це , тому виграє найкоротший код.


Третій вихідний приклад здається невідповідним правилу "Якщо слово починається з голосної, ви повинні написати його, починаючи з другого рядка".
JohnE

1
Y - це голосний?
Оптимізатор

1
@JohnE насправді це було, я це виправив. Спасибі.
Фаталізувати

2
The vowel should be written at the beginning of the next line, and not at the end of the previous line when one is encountered.Після деякої думки я розумію, що це означає, що перехід до наступного рядка має відбутися до друку голосного, а не після, але, можливо, варто сформулювати це таким чином, що миттєво зрозуміло - це зайняло у мене час.
трихоплакс

3
Чи дозволено проходження нових рядків / пробілів?
Loovjo

Відповіді:


18

Сітківка , 50 44 34 (+10) 32 30 байт

Завдяки Деннісу за збереження 14 байт за допомогою фактичних контрольних символів.

i`[aeiouy]
<VT>$0#
+`#(\S*)
$1<ESC>[A

Виходячи з цієї відповіді , я використовую ANSI коди евакуації, щоб переміщувати курсор терміналу вертикально. <ESC>Повинен бути замінений з характером управління 0x1B, і <VT>з вертикальною вкладці 0x0B. Для спрощення тестування можна також замінити <ESC>з \e, <VT>з \vі подачі вихідного сигналу через printf.

Для підрахунку кожного рядка йде в окремий файл. Однак для зручності простіше просто вставити код в один файл і викликати Retina за допомогою -sпараметра.

Перша заміна оточує кожну голосну \v...#, де \vзміщується курсор вниз, а #маркер другого кроку. i`Це позначення сітківки для обліку регістра відповідності.

Потім другий крок повторно ( +`) видаляє a #зі слова і ставить a e\[Aв кінці слова, що зміщує курсор вгору. Це припиняється, коли рядок перестає змінюватися, тобто коли #в рядку більше немає маркерів.


Вам не потрібно printf. Просто замініть \eбайт ESC (0x1b).
Денніс

@Dennis О, це набагато краще, дякую.
Мартін Ендер

1
Це так приголомшливо !!!
kirbyfan64sos

Ця відповідь чому ніхто не сприймає Ретину всерйоз;)
Крістофер Вірт

@ChristopherWirt Будь ласка, уточнюйте :) (Хоча я б насправді злякався, якби хтось сприйняв Retina серйозно.)
Мартін Ендер

8

CJam, 39 36 байт

0000000: 6c 7b 5f 65 6c 22 61 65 69 6f 75 79 22  l{_el"aeiouy"
000000d: 26 7b 22 1b 5b 41 22 27 0b 6f 5c 7d 26  &{".[A"'.o\}&
000001a: 5f 53 26 7b 5d 7d 26 6f 7d 2f           _S&{]}&o}/

Вищезазначене є оборотним дампами xxd, оскільки вихідний код містить недруковані символи VT (кодова точка 0x0b) та ESC (кодова точка 0x1b).

Як і у цій відповіді , він використовує вертикальні вкладки та послідовності втечі ANSI .

Для цього потрібний підтримуючий відеотекстовий термінал, який включає більшість емуляторів терміналів, що не є Windows.

Тестовий запуск

Перш ніж виконати фактичний код, ми відключимо підказку та очистимо екран.

$ PS1save="$PS1"
$ unset PS1
$ clear

Це гарантує правильний показ результатів.

echo -n Programming Puzzles and Code Golf | cjam <(xxd -ps -r <<< 6c7b5f656c226165696f757922267b221b5b4122270b6f5c7d265f53267b5d7d266f7d2f)
Pr          P           C    G
  ogr        uzzl   and  od   olf
     amm         es        e
        ing

Щоб відновити підказку, виконайте це:

PS1="$PS1save"

Як це працює

Ми вставляємо вертикальну вкладку перед кожною голосною для переміщення курсору вниз і достатньо копій послідовності байтів 1b 5b 41 ( "\e[A") після кожного пробілу, щоб перемістити курсор назад у перший рядок.

l           e# Read a line from STDIN.
{           e# For each character C:
  _el       e#   Push lowercase(C).
  "aeiouy"& e#   Intersect with "aeiouy".
  {         e#   If the intersection is non-empty:
    ".[A"   e#     Push "\e[A" (will be printed later).
    '.o     e#     Print "\v".
    \       e#     Swap "\e[A" with C.
  }&        e#
  _S&       e#   Intersect C with " ".
  {         e#   If the intersection is non-empty:
    ]       e#     Wrap the entire stack in an array.
  }&
  o         e#   Print C or the entire stack.
}/          e#

Не забудьте unset PS1saveзгодом.
usandfriends

5

Java, 428 байт

void s(String s){int l=s.length(),m=0;char[][]c=new char[l][];for(int i=0;i<c.length;java.util.Arrays.fill(c[i++],' '))c[i]=new char[l];String v="aeiouyAEIOUY";String[]a=s.split(" ");for(int r=0,p=0;r<a.length;r++){String u=a[r]+" ";int o=v.indexOf(u.charAt(0))>=0?1:0,x=p;for(;x<u.length()-1+p;o+=v.indexOf(u.charAt(x++-~-p))>=0?1:0)c[o][x]=u.charAt(x-p);p+=u.length();m=m<o?o:m;}for(int i=0;i<=m;i++)System.out.println(c[i]);}

Я знаю, це жахливо. Напевно, є якісь особливості, які можна поголити, але я лінивий робити це.


Ви , ймовірно , можете оголосити багато з ваших intзмінних (а саме i, r, p, o, і x) , де ви ініціалізації lі , mтак як вони будуть приведені значення пізніше. Ви також можете робити String v="...",a[]=...;і робити те саме, що описано вище String u. Це повинно трохи знизити ваш бал.
ТНТ

Мені подобаєтьсяx++-~-p
Ypnypn

4

Perl, 31 байт

0000000: 24 5c 3d 22 1b 5b 41 22 78 20 73 2f 5b 61  $\=".[A"x s/[a
000000e: 65 69 6f 75 79 5d 2f 0b 24 26 2f 67 69     eiouy]/.$&/gi

Вищезазначене є оборотним дампами xxd, оскільки вихідний код містить недруковані символи VT (кодова точка 0x0b) та ESC (кодова точка 0x1b).

Код завдовжки 27 байт і вимагає комутаторів 040p(4 байти).

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

Тестовий запуск

Перш ніж виконати фактичний код, ми відключимо підказку та очистимо екран.

$ PS1save="$PS1"
$ unset PS1
$ clear

Це гарантує правильний показ результатів.

echo -n Programming Puzzles and Code Golf | perl -040pe "$(xxd -ps -r <<< 245c3d221b5b41227820732f5b6165696f75795d2f0b24262f6769)"
Pr          P           C    G
  ogr        uzzl   and  od   olf
     amm         es        e 
        ing

Щоб відновити підказку, виконайте це:

PS1="$PS1save"

Як це працює

  • perl -040pавтоматично зчитує вхід як розділені пробілом лексеми ( -040), зберігає кожен маркер у $_( -p) та виконує програму.

  • s/[aeiouy]/.$&/giздійснює глобальний, нечутливий до регістру $_голосний звук і замінює кожен голосний на керуючий символ VT (переміщує курсор вниз), за ним слідує сам голосний.

  • sповертає кількість зроблених замін, тому $\=".[A"x s...зберігає кілька копій послідовності байтів 1b 5b 41 (переміщує курсор вгору) $\, по одному для кожного голосного.

  • В кінці програми Perl автоматично друкує "$_$\"через -pкомутатор.


4

C, 200 190 байт

i,j,k,l,M;f(char*s){M=strlen(s)+1;char t[M*M];for(;i<M*M;++i)t[i]=(i+1)%M?32:10;for(i=0;i<M-1;++i)k=(strspn(s+i,"aeiouyAEIOUY")?++j:s[i]==32?j=0:j)*M+i,l<k?l=k:0,t[k]=s[i];t[l+1]=0;puts(t);}

Безголівки:

i,j,k,l,M;
f(char *s){
    M = strlen(s)+1;
    char t[M*M];
    for(; i<M*M; ++i) t[i] = (i+1)%M ? 32 : 10;
    for(i=0; i<M-1; ++i)
        k = (strspn(s+i,"aeiouyAEIOUY") ? ++j : s[i]==32 ? j=0 : j) * M + i,
        l<k ? l=k : 0,
        t[k] = s[i];
    t[l+1]=0;
    puts(t);
}

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

Технічно це не функція, оскільки вона містить глобальні точки; насправді його не можна викликати більше одного разу ( jі він lповинен бути 0 на початку). Щоб відповідати, i,j,k,l,M;можна було перейти до int i,j=0,k,l=0,M;початку функції.


char*t=malloc(M*M);-> char t[M*M];і for(i=0;i<M*M;++i)->for(;i<M*M;++i)
Spikatrix

Добре ловить, відредагував.
jcai

Це не через C99 char t[M*M]?
Zacharý

4

CJam, 47

Так, це трохи довго, але це не "обман" ANSI-кодами :)

q_{_S&!\el"aeiouy"-!U+*:U}%_0|$])\zff{~@-S@?}N*

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

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


3

К, 81 72 70 66 байт

Ну, це початок:

`0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/{+\{12>"aeiouyAEIOUY"?x}'x}'(0,&~{"  "?x}'x)_ x}

Приклади використання:

  `0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/{+\{12>"aeiouyAEIOUY"?x}'x}'(0,&~{"  "?x}'x)_ x} "Programming Puzzles and Code Golf"
Pr          P           C    G   
  ogr        uzzl   and  od   olf
     amm         es        e     
        ing                      
  `0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/{+\{12>"aeiouyAEIOUY"?x}'x}'(0,&~{"  "?x}'x)_ x} "YEAh UppErcAsE VOwEls"
               V     
Y    Upp        Ow   
 E      Erc       Els
  Ah       As        
             E       

Редагувати 1:

Краще. Внесло деякі покращення рівня поверхні:

`0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/{+\{12>"aeiouyAEIOUY"?x}'x}'(0,&~{"  "?x}'x)_ x}
`0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/(+\12>?["aeiouyAEIOUY"]')'_[0,&" "=x]x}

Помітно, я перевернув аргументи, ?коли я здійснюю пошук голосних і, таким чином, усунув необхідність лямбда, зробив таку ж інверсію, _де я розділив слова на пробіл, і зрозумів, що ~{" "?x}'xце справді нерозумний, надскладний спосіб висловлювання " "=x.

Редагувати 2:

Перед sтим, як застосувати його до лямбда, відмініть ще один рівень поверхні , зберігаючи парени всередині:

`0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/(+\12>?["aeiouyAEIOUY"]')'_[0,&" "=x]x}
`0:{+{z!y,x#" "}[|/s].'x,'-s:,/(+\12>?["aeiouyAEIOUY"]')'_[0,&" "=x]x}

Редагувати 3:

Добре, давайте по-іншому підходимо до обчислення зміщення для кожного символу. Замість того, щоб розділяти послідовність на пробіли та обчислити поточну суму ( +\) позицій голосних, ми можемо оперувати всім вхідним рядком за один прохід, помноживши суму запуску на 0, коли ми стикаємося з пробілом. Мені потрібне заперечення цієї послідовності, тож я можу відняти замість додавання під час сканування і використовувати число розрізнення ( #?) замість max ( |/), коли я обчислюю кількість вертикальної прокладки.

`0:{+{z!y,x#" "}[|/s].'x,'-s:,/(+\12>?["aeiouyAEIOUY"]')'_[0,&" "=x]x}
`0:{+{z!y,x#" "}[#?s].'x,'s:1_0{(~" "=y)*x-12>"aeiouyAEIOUY"?y}\x}

Це економить ще 4 символи. Фу!


2

Рубі: 135 131 124 115 112 символів

a=[]
y=l=0
gets.split(r=/(?=[aeiouy ])/i).map{|w|w=~r&&y+=1
w<?A&&y=0
a[y]='%*s%s'%[-l,a[y],w]
l+=w.size}
puts a

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

bash-4.3$ ruby staircase.rb <<< 'Programming Puzzles and Code Golf'
Pr          P           C    G
  ogr        uzzl   and  od   olf
     amm         es        e
        ing

Якщо я не помиляюся, ви можете скоротити свій регекс /(?=[aeiouy ])/i.
Олексій А.

Ах, ти правий @AlexA. Простір як окреме слово було важливим лише для більш ранньої теорії. Спасибі.
манатура

2

C, 192 байти

f(char*s){int l=0,r=1,v,c;for(;r;l=1){v=l;r=0;char*p;for(p=s;*p;++p){c=*p;if(c==' ')v=l,putchar(c);else if((strchr("aoeuiyAOEUIY",c)?--v:v)<0)r=1,putchar(' ');else*p=' ',putchar(c);}puts(p);}}

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

Читаема версія

f(char *s) {
    int l=0,       /* true if we've done the first line (no vowels) */
        r=1,       /* true if characters remain in buffer */
        v,         /* how many vowels to print from current word */
        c;         /* current character value */
    for (l=0; r; l=1) {
        v = l;
        r = 0;
        char *p;
        for (p=s;*p;++p) {
            c=*p;
            if (c==' ') {       /* a space - reset vowel counter */
                v=l;
                putchar(c);
            } else if ((strchr("aoeuiyAOEUIY",c)?--v:v)<0) {
                /* vowel conter exceeded - print a space */
                putchar(' ');
                r=1;
            } else {
                /* print it, and obliterate it from next line of output */
                putchar(c);
                *p=' ';
            }
        }
        puts(p); /* p points at the NUL, so this just prints a newline */
    }
}

' '-> 32і f(char*s){int l=0,r=1,v,c;->l,r=1,v,c;f(char*s){
Spikatrix

@Cool - ' ' може бути 32, але це залежить від кодування символів, і, як я вже сказав, я зробив цей портативний C. Відкидання явного int- це чудово, хоча - не впевнений, чому я це забув!
Toby Speight

2

Пітон 3, 265 207 202 185 177 символів

i=input()
w,e=i.split(" "),lambda:[[" "]*len(i)]
o,x=e(),0
for p in w:
    y=0
    for c in p:
        if c in"AEIOUYaeiouy":o+=e();y+=1
        o[y][x],x=c,x+1
    x+=1
for l in o:print("".join(l))

Це страшно і я не пишаюся. Я знаю, що це можна скоротити, але я все-таки подумав.

Натхненний версією C, він створює список, який потім заповнюється під час проходження вхідного рядка.


2

GNU Sed, 151 + 1

(+1, як потрібно -rпрапор)

s/^/ /;h;s/[aoeuiy]/_/ig;:a;s/_[^ _]/__/;ta;y/_/ /;g;:x;:b;s/ [^ aoeuiy]/  /i;tb;h;s/([^ ])[aoeuiy]/\1_/ig;:c;s/_[^ _]/__/;tc;y/_/ /;g;s/ [^ ]/  /ig;tx

Я думав, що sed буде інструментом для цієї роботи, але вважаю це напрочуд важким.

Читаема версія:

#!/bin/sed -rf

# make sure the string starts with a space
s/^/ /
h

# print leading consonants, if any
s/[aoeuiy]/_/ig
:a
s/_[^ _]/__/
ta
y/_/ /
p
g

:x
# strip the consonants just printed
:b
s/ [^ aoeuiy]/  /i
tb
h

s/([^ ])[aoeuiy]/\1_/ig
:c
s/_[^ _]/__/
tc
y/_/ /
p
g
# remove leading vowel of each word
s/ [^ ]/  /ig
tx

Боюся, це має бути 128 символів. У одно рядковій версії відсутній a p, тому він нічого не видає. Невелике питання полягає в тому, що виходи починаються з додаткового простору. Величезне питання полягає в тому, що перший фрагмент тексту, що починається з голосної, зникає.
манатура

Я впевнений, що це працювало раніше. Я погляну і побачу, що я зламав. Дякую за голову, @manatwork!
Toby Speight

Я неправильно стрибнув у цикл c, завдяки лінії, що була раніше tx. Я відновив попередню версію з її подібним циклом, і пізніше буду мати іншу спробу.
Toby Speight

2

Пітон 2, 145 142 байт

Напевно, не настільки конкурентоспроможний, як деякі інші методи, але я подумав, що це класний спосіб використання регексу.

import re;s=I=input()[::-1]+" ";i=0
while s.strip()or i<2:s=re.sub("(?!([^aeiouy ]*[aeiouy]){%s}[^aeiouy]* )."%i," ",I,0,2)[::-1];print s;i+=1

Зворотній вираз (?!([^aeiouy ]*[aeiouy]){N}[^aeiouy]* ).відповідає будь-якому одному символу, що не входить до N-ї групи літер з кінця слова. Оскільки він рахується з кінця світу, я перевертаю рядок до і після, і мені також потрібно додати пробіл в кінці, але після цього це стає простою справою використання re.subдля заміни кожного примірника цих символів пробілом. Це робиться для кожного значення N, поки рядок не порожній.


Як добре і читабельно це використовувати re.I, ви можете зберегти 3 байти, замінивши відповідне значення прапора, тобто 2.
Sp3000

1
@ Sp3000 Тільки в коді-гольфі є негативні асоціації з "приємним і читабельним"
KSab

1

Октава, 132 129 символів

p=1;x=[];y=input(0);for j=1:numel(y);if regexpi(y(j),'[aeiouy]');p+=1;elseif y(j)==" ";p=1;end;x(p,j)=y(j);end;x(x==0)=32;char(x)

Тест

Вхід: "YEAh UppErcAsE VOwEls"

Вихід:

               V     
Y Upp Ow   
 E Erc Els
  Ах як        
             Е       

1

Gema : 53 48 символів

/[aeiouyAEIOUY]/=@append{u;^[[A}^K$1
 = $u@set{u;}

Зауважте, що ^[(x1b) та ^K(x0b) - це окремі символи. (У наведеному нижче прикладі виконання я використовую їхні копії-вставки \eта їх \vеквіваленти, якщо ви хочете спробувати це.)

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

bash-4.3$ gema '/[aeiouyAEIOUY]/=@append{u;\e[A}\v$1; = $u@set{u;}' <<< 'Programming Puzzles and Code Golf'
Pr          P           C    G    
  ogr        uzzl   and  od   olf 
     amm         es        e 
        ing 

1

Желе , 42 байти (не конкурує?)

Ḳµe€Øyœṗ⁸⁶ṁ$;¥\z⁶Zµ€µḷ/⁶ṁW⁸;ḣ®µ€L€Ṁ©$¡ZK€Y

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

Чому желе, чому? :-(


Довше CJam здається дивним
Fatalize

@Fatalize Це тому, що Jelly просто не йде зі струнами ... зазвичай. Крім того, ви не можете порівнювати різні парадигми програмування (cjam заснований на стеці, желе є мовчазним).
Ерік Аутгольфер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.