계단 쓰기


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는 모음인가요?
Optimizer

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.어떤 생각을 한 후에, 이것은 모음이 인쇄되기 전에 다음 줄로 이동해야한다는 것을 이해합니다.하지만 나중에 이해할 수있는 방식으로 말로 표현할 가치가 있습니다.
trichoplax

3
후행 줄 바꿈 / 공백이 허용됩니까?
Loovjo

답변:


18

레티 나 , 50 44 34 (+10) 32 30 바이트

실제 제어 문자를 사용하여 14 바이트를 절약 해 준 Dennis에게 감사합니다.

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

이 답변을 기반으로 ANSI 이스케이프 코드를 사용하여 터미널 커서를 세로로 이동합니다. 는 <ESC>제어 문자 0x1B로 대체되어야하고, <VT>수직 탭 0x0B. 간단한 테스트를 위해, 당신은 또한 대체 할 수 <ESC>\e, <VT>함께 \v하고를 통해 출력을 공급 printf.

계산을 위해 각 줄은 별도의 파일에 저장됩니다. 그러나 편의상 코드를 단일 파일에 붙여 넣고 -s옵션으로 Retina를 호출하는 것이 더 간단합니다 .

첫 번째 교체는에서 각 모음을 둘러싸고 있으며 \v...#여기서 \v커서는 아래로 이동하고 #는 두 번째 단계의 마커입니다. 는 i`대소 문자를 구분 일치를위한 망막의 표기법입니다.

그런 다음 두 번째 단계 는 단어에서 a 를 반복적으로 +`제거하고 ( ) #단어 e\[A의 끝에 a 를 두어 커서를 위로 이동시킵니다. 문자열이 더 이상 바뀌지 않으면, 즉 #문자열에 마커 가 더 이상 없으면 중지됩니다 .


당신은 필요하지 않습니다 printf. \eESC 바이트 (0x1b)로 바꾸 십시오.
Dennis

@ 데니스 오, 훨씬 낫습니다. 감사합니다.
마틴 엔더

1
정말 대단해 !!!
kirbyfan64sos

이 대답은 아무도 Retina를 진지하게 고려하지 않는 이유입니다.)
Christopher Wirt

(사람이 있다면 실제로 두려워 할 것이지만 @ChristopherWirt : 정교한하시기 바랍니다 했다 심각하게 망막을.)
마틴 청산

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}/

소스 코드에는 인쇄 할 수없는 문자 VT (코드 포인트 0x0b)와 ESC (코드 포인트 0x1b)가 포함되어 있으므로 위의 뒤집을 수있는 xxd 덤프입니다.

이 답변 과 마찬가지로 세로 탭과 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

자바, 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)는 초기화 곳 lm그들이 나중에 값이 제공됩니다 때문이다. 에 String v="...",a[]=...;대해 위와 동일한 작업 을 수행 할 수도 있습니다 String u. 점수가 약간 낮아집니다.
TNT

나는x++-~-p
Ypnypn

4

펄, 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

소스 코드에는 인쇄 할 수없는 문자 VT (코드 포인트 0x0b)와 ESC (코드 포인트 0x1b)가 포함되어 있으므로 위의 뒤집을 수있는 xxd 덤프입니다.

코드 길이는 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);
}

사각형 버퍼 (실제로 사각형)를 할당하고 공백과 줄 바꿈으로 채운 다음 주어진 문자열을 통과합니다. 끝에 줄 바꿈 문자를 추가하여 줄 바꿈을 방지합니다.

기술적으로는 전역을 포함하기 때문에 함수가 아닙니다. 사실이 두 번 이상 호출 할 수 없습니다 ( jl시작에 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

K, 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 ( |/) 대신 number-of-diinct ( )를 사용할 수 있습니다.

`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.
Alex A.

아, 당신은 맞습니다 @AlexA. 별도의 단어로서의 공간은 초기 이론에만 중요했습니다. 감사.
manatwork

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 */
    }
}

' '-> 32f(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

( -r플래그가 필요할 때 +1 )

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 자 여야합니다. 한 줄 버전 p에는가 없으므로 아무것도 출력하지 않습니다. 작은 문제는 출력이 추가 공간으로 시작한다는 것입니다. 큰 문제는 모음으로 시작하는 첫 번째 텍스트가 사라진다는 것입니다.
manatwork

나는 그것이 더 일찍 작동하고 있다고 확신합니다. 내가보고 깨진 것을 볼 수 있습니다. @manatwork를 도와 주셔서 감사합니다!
Toby Speight

c직전의 선으로 인해 루프에 빠지는 것이 잘못되었습니다 tx. 비슷한 루프로 이전 버전을 복원했으며 나중에 다른 시도를해야합니다.
Toby Speight

2

파이썬 2, 145142 바이트

아마도 다른 방법만큼 경쟁력이 없지만 정규식을 사용하는 멋진 방법이라고 생각했습니다.

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

정규 표현식 은 단어의 끝에서 N 번째 문자 그룹에 없는(?!([^aeiouy ]*[aeiouy]){N}[^aeiouy]* ). 단일 문자와 일치합니다 . 그것은 세계의 끝에서 계산되기 때문에 문자열을 전후로 뒤집고 끝에 공백을 추가해야하지만 그 후에 는이 문자의 모든 인스턴스를 공백으로 바꾸는 데 사용하는 간단한 문제가됩니다 . 문자열이 비어있을 때까지 N의 모든 값에 대해이 작업을 수행합니다.re.sub


사용하기 좋고 읽기 쉬운 것처럼 re.I적절한 플래그 값을 대체하여 3 바이트를 절약 할 수 있습니다 2.
Sp3000

1
@ Sp3000 코드 골프에서만 "nice and readable"과 음의 연관성이 있습니다
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 웁 아야   
 E Erc Els
  아 As        
             이자형       

1

관장 : 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 젤리는 문자열과 함께 가지 않기 때문에 ... 보통. 또한 다른 프로그래밍 패러다임을 실제로 비교할 수는 없습니다 (잼은 스택 기반이며 젤리는 묵묵합니다).
Outgolfer Erik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.