Merdiven yazı


35

Belirli bir dizgeyi merdiven biçiminde çıkaran bir program ya da bir işlev yazın, bir kelimenin her bir bölümünü bir önceki bölümün altında bir sesli harfle başlayan bir harfle yazın.

Örneğin:

Input: Programming Puzzles and Code Golf


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

Giriş

Harf ve boşluk dışında hiçbir şey içermeyen bir dize.

Dize, STDINişlev argümanları veya eşdeğer herhangi bir şey aracılığıyla iletilebilir .

Harfler küçük veya büyük harf olabilir.

Girdilerin her zaman bu kuralları takip ettiği varsayılır, yanlış girdileri kontrol etmeniz gerekmez.

Çıktı

Sesli harf (olduğunu, her zaman a, e, i, o, uveya y) bir kelime karşılaşıldığında yapmanız gerekir çıktısı doğru yatay pozisyonda sonraki satıra (karşılaşılan sesli harf dahil) üzerinde kelimenin kalanı. Bu kural özyinelemelidir, bu, kelimede hiç ünlü olmadığında, n + 1 satırlarına yazılacağı anlamına gelir.

  • Ünlü harf, bir sonraki satırın başında yazılmalıdır, önceki satırın sonuna yazılmadan yazılmamalıdır.

  • Her kelime ilk satırda başlar ve bu nedenle diğer kelimelerden bağımsız olarak biçimlendirilmelidir. İki kelime bir boşlukla ayrılır.

  • Bir kelime sesli harfle başlarsa, ikinci satırdan başlayarak yazmak zorundasınız.

Test durumları

  • Giriş: Programming Puzzles and Code Golf

Çıktı:

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

Çıktı:

Th  q     br    f   j          th  l    d
  e  u      own  ox  umps ov     e  az   og
      ick                   er        y
  • Giriş: aeiouy

Çıktı:

 
a
 e
  i
   o
    u
     y
  • Giriş: YEAh UppErcAsE VOwEls

Çıktı:

               V
Y    Upp        Ow
 E      Erc       Els
  Ah       As  
             E
  • Giriş: If you only knew the power of the Dark Side

Çıktı:

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

puanlama

Bu , yani en kısa kod kazanır.


Üçüncü çıktı örneği, "Bir sözcük bir sesli harfle başlarsa, ikinci satırdan başlayarak yazmanız gerekir" kuralına uymuyor gibi görünüyor.
JohnE

1
Y, Y bir ünlü mü?
Doktor 15

1
@JohnE gerçekten öyleydi, ben düzelttim. Teşekkürler.
Temmuz’da

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.Bazı düşüncelerden sonra, bunun bir sonraki satıra geçmenin, ünlü harfin basılmadan önce gerçekleşmesi gerektiği anlamına geldiğini anlıyorum, fakat bundan hemen sonra anlaşılmayacak bir şekilde ifade etmeye değer olabilir - biraz zaman aldı.
trichoplax

3
İzleyen yeni satırlara / alanlara izin veriliyor mu?
Loovjo

Yanıtlar:


18

Retina , 50 44 34 (+10) 32 30 bayt

Gerçek kontrol karakterlerini kullanarak 14 byte tasarruf sağladığı için Dennis'e teşekkür ederiz.

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

Bu cevaba dayanarak , terminal imlecini dikey olarak hareket ettirmek için ANSI çıkış kodlarını kullanıyorum. Bu <ESC>, 0x1B kontrol karakteriyle ve <VT>dikey sekmeyle değiştirilmelidir 0x0B. Daha basit testler için ayrıca yerini alabilir <ESC>ile \e, <VT>birlikte \vve içinden çıkışını beslemek printf.

Sayma amacıyla, her satır ayrı bir dosyaya gider. Ancak, kolaylık sağlamak için kodu tek bir dosyaya yapıştırmak ve Retina'yı bu -sseçenekle çağırmak daha kolaydır .

İlk değiştirme \v...#, her \vimleci içine alır , burada imleci aşağıya kaydırır #ve ikinci adım için bir işarettir. i`Küçük harf duyarsız eşleştirme için Retina en nottur.

Ardından ikinci adım, art arda ( +`) #, bir kelimeyi a'dan çıkarır e\[Ave imleci yukarı doğru hareket ettiren kelimenin sonuna koyar . Bu, dize değişmeyi bıraktığında, yani #dize daha fazla işaretçi olmadığında durur .


İhtiyacın yok printf. Sadece \eESC baytıyla değiştirin (0x1b).
Dennis,

@Dennis Oh, bu çok daha iyi, teşekkür ederim.
Martin Ender

1
Bu çok harika !!!
kirbyfan64sos

Bu cevabın neden hiç kimsenin Retina'yı ciddiye almadığı;)
Christopher Wirt

@ChristopherWirt Lütfen detaylandırın :) (Her ne kadar biri Retina'yı ciddiye aldıysa , gerçekten dehşete düşmüş olmama rağmen .)
Martin Ender

8

CJam, 39 36 bayt

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

Kaynak kodu yazdırılamaz karakter VT (kod noktası 0x0b) ve ESC'yi (kod noktası 0x1b) içerdiğinden yukarıdakiler tersine çevrilebilir bir xxd dökümüdür.

Gibi bu cevap , dikey sekmeler ve kullanır ANSI çıkış sırasını .

Bu, çoğu Windows olmayan terminal emülatörünü içeren, destekleyici bir video metin terminali gerektirir.

Test sürüşü

Gerçek kodu çalıştırmadan önce, istemi devre dışı bırakır ve ekranı temizleriz.

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

Bu, çıkışın doğru şekilde gösterilmesini sağlar.

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

İstemi geri yüklemek için şunu yürütün:

PS1="$PS1save"

Nasıl çalışır

İmleci aşağı hareket ettirmek için her bir harfin önüne dikey bir sekme ve imleci ilk satıra geri getirmek için her boşluktan sonra bayt dizisi 1b 5b 41 ( "\e[A") ' nin yeterli kopyalarını yerleştiririz.

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#

Daha unset PS1savesonra yapmayı unutma .
usandfriends

5

Java, 428 bayt

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]);}

Biliyorum, korkunç. Muhtemelen traş edilebilecek bazı karakterler var, ama bunu yapmak için fazla tembelim.


Muhtemelen birçok ilan edebilir intdeğişkenler (yani i, r, p, o, ve x) sen başlatmak nerede lve mdaha sonra değerleri verilecektir beri. Ayrıca String v="...",a[]=...;yukarıdakileri yapmak için de aynısını yapabilirsiniz String u. Bu puanınızı biraz düşürmeli.
TNT

Sevdiğimx++-~-p
Ypnypn

4

Perl, 31 bayt

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

Kaynak kodu yazdırılamaz karakter VT (kod noktası 0x0b) ve ESC'yi (kod noktası 0x1b) içerdiğinden yukarıdakiler tersine çevrilebilir bir xxd dökümüdür.

Kod 27 bayt uzunluğunda ve anahtarları 040p(4 bayt) gerektirir .

Program dikey sekmeleri destekleyen bir video metin terminali ve çoğu Windows olmayan terminal emülatörünü içeren ANSI çıkış dizilerini gerektirir .

Test sürüşü

Gerçek kodu çalıştırmadan önce, istemi devre dışı bırakır ve ekranı temizleriz.

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

Bu, çıkışın doğru şekilde gösterilmesini sağlar.

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

İstemi geri yüklemek için şunu yürütün:

PS1="$PS1save"

Nasıl çalışır

  • perl -040pgirişi otomatik olarak boşlukla ayrılmış simgeler ( -040) olarak okur, her işareti $_( -p) içine kaydeder ve programı çalıştırır.

  • s/[aeiouy]/.$&/gi$_ünlüler için genel, büyük / küçük harf duyarlı bir arama yapar ve her bir ünlü harfini VT kontrol karakteriyle (imleci aşağı doğru hareket ettirir) ve ardından ünlü harfin kendisiyle değiştirir.

  • syaptığı değişiklik sayısını döndürür, böylece her bir ünlü için bir tane $\=".[A"x s...olan bayt dizisi 1b 5b 41'in çoklu kopyalarını kaydeder (imleci yukarı doğru hareket ettirir) $\.

  • Program sonunda "$_$\", -panahtar nedeniyle Perl otomatik olarak yazdırılır .


4

C, 200 190 bayt

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);}

Ungolfed:

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);
}

Dikdörtgen bir tampon (aslında kare) ayırır, boşlukları ve yeni satırları doldurur, sonra verilen dizeyi geçer. Sonunda izleyen satır sonlarını önlemek için boş bir karakter ekler.

Teknik olarak globals içerdiğinden bir fonksiyon değildir; aslında birden fazla kez çağrılamaz ( jve lbaşında 0 olmalıdır). Buna uymak, fonksiyonun başlangıcına i,j,k,l,M;taşınabildi int i,j=0,k,l=0,M;.


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

İyi yakalamalar, düzenlendi.
jcai

Bu C99 sadece nedeniyle değil char t[M*M]mi?
Zacharý

4

CJam, 47

Evet, biraz uzun, ama ANSI kodları ile "hile" değil :)

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

Çevrimiçi deneyin

Fikir, her karakter için bir satır numarası hesaplamaktır (0'dan başlamak, ünlü harfleri artırmak ve uzayda 0'a geri dönmek) ve sonra her satır için dizgiyi tekrarlamak, ancak farklı satır numarasına sahip karakterleri boşlukla değiştirmek .


3

K, 81 72 70 66 bayt

Peki, bu bir başlangıç:

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

Kullanım Örnekleri:

  `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       

Düzenleme 1:

Daha iyi. Bazı yüzey seviyesi iyileştirmeleri yapıldı:

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

Özellikle, ?sesli arama yaptığımda argümanları tersine çevirdim ve böylelikle bir lambda ihtiyacını ortadan kaldırdım, _beyaz boşlukta kelimeleri böldüğüm yerle aynı inversiyonu yaptım ve ~{" "?x}'xbunun gerçekten aptalca, karmaşık bir söylem biçimi olduğunu fark ettim " "=x.

Düzenleme 2:

Başka bir yüzey seviyesi lambdaya suygulamadan önce ince ayar yapar ve içindeki pareleri korur :

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

Düzenleme 3:

Tamam, her karakter için ofsetin hesaplanmasında farklı bir yaklaşım kullanalım. Diziyi boşluklara bölmek ve +\sesli harflerin konumlarının hareketli bir toplamını ( ) hesaplamak yerine , tüm giriş dizgisini tek geçişte çalıştırabiliriz, böylece bir boşlukla karşılaştığımızda hareketli toplamı 0 ile çarpabiliriz. Bu sıranın olumsuzluğuna ihtiyacım var, bu yüzden dikey doldurma miktarını hesaplarken, tararken ve #?max ( |/) yerine ayırma sayısı ( ) yerine ekleyeceğim gibi çıkarabilirim .

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

Bu 4 karakter daha kaydeder. Uf!


2

Yakut: 135 131 124 115 112 karakter

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

Örnek çalışma:

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

Yanılmıyorsam, regex'inizi kısaltabilirsiniz /(?=[aeiouy ])/i.
Alex A.

Ah, haklısın @AlexA. Ayrı bir kelime olarak boşluk sadece daha önceki bir teori için önemliydi. Teşekkürler.
manatwork

2

C, 192 bayt

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);}}

Bu, karakterleri yazdırırken boşluk bırakarak dizge boyunca yinelenir. Yazdırılacak boş karakter kalmayıncaya kadar tekrar eder. Karakter kodlaması hakkında varsayımlarda bulunmadan taşınabilir C'dir.

Okunabilir sürüm

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

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

@Cool - ' ' verebilir olmak 32, ancak açık bu taşınabilir C. Bırakma o karakter kodlaması bağlıdır ve dediğim gibi yaptığım intolsa harika - Bunu unuttum emin niçin!
Toby Speight,

2

Python 3, 265 207 202 185 177 karakterler

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))

Bu korkunç ve gurur duymuyorum. Bunun daha kısa yapılabileceğini biliyorum, ama yine de göndereceğimi düşündüm.

C sürümünden esinlenerek giriş dizesini dolaşırken doldurduğu bir liste oluşturur.


2

GNU Sed, 151 + 1

( -rBayrağa ihtiyacı olduğu gibi +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'in bu iş için bir araç olacağını düşünmüştüm, ama şaşırtıcı bir şekilde zor buldum.

Okunabilir sürüm:

#!/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

Korkarım, bu 128 karakter olmalı. Tek satırlık sürümde bir eksik p, bu nedenle hiçbir şey çıkarmaz. Küçük bir sorun, çıktıların fazladan bir boşlukla başlamasıdır. Büyük bir sorun, sesli harfle başlayan ilk metnin kaybolmasıdır.
manatwork

Eminim daha önce çalışıyordu. Bir göz atacağım ve neyi kırdığımı göreceğim. Yardımların için teşekkürler, @manatwork!
Toby Speight

cHemen önce çizgiden dolayı döngü içine atlamak yanlıştı tx. Benzer döngüsüyle daha eski bir sürümü yeniden kullandım ve daha sonra başka bir girişimde bulunacağım.
Toby Speight

2

Python 2, 145 142 Bayt

Muhtemelen diğer bazı yöntemler kadar rekabetçi değil, ama bunun regex kullanmanın güzel bir yolu olduğunu düşündüm.

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

Düzenli ifade , bir kelimenin sonundaki Ninci gruptaki harflerin içinde olmayan(?!([^aeiouy ]*[aeiouy]){N}[^aeiouy]* ). herhangi bir karakterle eşleşir . Dünyanın sonundan sayıldığı için ipi önce ve sonra tersine çeviririm ve sonunda bir boşluk eklerim, ancak bundan sonra bu karakterlerin her bir örneğini bir boşlukla kullanmak basit bir mesele olur . Dize boşalana kadar bunu N'nin her değeri için yapar.re.sub


Kullanmak ne kadar hoş ve okunaklı re.Iolursa, uygun bayrak değerini değiştirerek 3 byte tasarruf edebilirsiniz 2.
Sp3000,

1
@ Sp3000 Sadece code-golf'da "nice and readable" ile negatif bir ilişki var
KSab

1

Octave, 132 129 karakter

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)

Ölçek

Giriş: "YEAh UppErcAsE VOwEls"

Çıktı:

               V     
Y Upp Ow   
 Erc Els
  Ah As        
             E       

1

Gema : 53 48 karakter

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

Not ^[(X1B) ve ^K(x0b) tek karakterlerdir. (Aşağıdaki örnek çalışmada , denemek istemeniz durumunda, kopyala-yapıştır dostu \eve \veşdeğerlerini kullanıyorum.)

Örnek çalışma:

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

Jöle , 42 byte (rekabet etmeyen?)

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

Çevrimiçi deneyin!

Neden Jelly, neden? :-(


CJam'dan daha uzun süre garip görünüyor
Fatalize,

@Fatalize Çünkü Jelly sadece dizeleriyle gitmiyor çünkü ... genellikle. Ayrıca farklı programlama paradigmalarını gerçekten karşılaştıramazsınız (cjam yığın tabanlıdır, jöle düzensizdir).
Outgolfer Erik,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.