Napisz program lub funkcję, która wypisze dany ciąg w sposób schodowy, pisząc każdą część słowa rozpoczynającą się od samogłoski o jeden wiersz poniżej poprzedniej części.
Na przykład:
Input: Programming Puzzles and Code Golf
Output: Pr P C G
ogr uzzl and od olf
amm es e
ing
Wkład
Ciąg zawierający tylko litery i spacje.
Ciąg może być przekazywany przez STDIN
argumenty funkcji lub dowolne równoważne.
Litery mogą być małe lub wielkie.
Zakłada się, że dane wejściowe zawsze są zgodne z tymi zasadami, nie trzeba sprawdzać, czy dane wejściowe są nieprawidłowe.
Wydajność
Za każdym razem gdy samogłoski (czyli a
, e
, i
, o
, u
lub y
) spotyka się w słowie, należy wyjście reszta słowo na następnej linii (napotkał samogłoska w zestawie), w prawidłowej pozycji poziomej. Ta reguła jest rekurencyjna, co oznacza, że jeśli słowo zawiera n samogłosek, zostanie zapisane w n + 1 wierszach.
Samogłoska powinna być zapisywana na początku następnego wiersza, a nie na końcu poprzedniego wiersza, gdy zostanie napotkany.
Każde słowo zaczyna się w pierwszym wierszu i dlatego powinno być sformatowane niezależnie od innych słów. Dwa słowa są oddzielone spacją.
Jeśli słowo zaczyna się od samogłoski, musisz je zapisać zaczynając od drugiej linii.
Przypadki testowe
- Wkład:
Programming Puzzles and Code Golf
Wydajność:
Pr P C G
ogr uzzl and od olf
amm es e
ing
- Wkład:
The quick brown fox jumps over the lazy dog
Wydajność:
Th q br f j th l d
e u own ox umps ov e az og
ick er y
- Wkład:
aeiouy
Wydajność:
a
e
i
o
u
y
- Wkład:
YEAh UppErcAsE VOwEls
Wydajność:
V
Y Upp Ow
E Erc Els
Ah As
E
- Wkład:
If you only knew the power of the Dark Side
Wydajność:
kn th p th D S
If y onl ew e ow of e ark id
o y er e
u
Punktacja
To jest golf golfowy , więc wygrywa najkrótszy kod.
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.
Po namyśle rozumiem, że oznacza to, że przejście do następnej linii powinno nastąpić przed wydrukowaniem samogłoski, a nie później, ale może warto sformułować to w sposób, który jest natychmiast zrozumiały - zajęło mi to trochę czasu.Odpowiedzi:
Siatkówka ,
504434(+10)3230 bajtówDzięki Dennisowi za zapisanie 14 bajtów przy użyciu rzeczywistych znaków kontrolnych.
W oparciu o tę odpowiedź używam kodów specjalnych ANSI, aby przesunąć kursor terminala w pionie.
<ESC>
Należy zastąpić znakiem kontrolnym 0x1b oraz<VT>
z zakładki pionowej0x0B
. Dla prostszych testów, można również wymienić<ESC>
z\e
,<VT>
ze\v
i paszy poprzez wyjścieprintf
.Do celów zliczania każda linia przechodzi w osobny plik. Jednak dla wygody łatwiej jest po prostu wkleić kod do jednego pliku i wywołać Retinę z
-s
opcją.Pierwsza zamiana otacza każdą samogłoskę, w
\v...#
której\v
przesuwa kursor w dół, a#
znacznik drugiego kroku. Jesti`
to notacja Retina dla dopasowywania bez rozróżniania wielkości liter.Drugi krok następnie (
+`
) usuwa a#
ze słowa i umieszczae\[A
na końcu słowa, co przesuwa kursor w górę. Zatrzymuje się, gdy ciąg przestanie się zmieniać, tj. Gdy nie będzie więcej#
znaczników w ciągu.źródło
printf
. Wystarczy zastąpić\e
bajtem ESC (0x1b).CJam,
3936 bajtówPowyżej jest odwracalny zrzut xxd, ponieważ kod źródłowy zawiera niedrukowalny znak VT (punkt kodowy 0x0b) i ESC (punkt kodowy 0x1b).
Podobnie jak ta odpowiedź , wykorzystuje pionowe tabulatory i sekwencje specjalne ANSI .
Wymaga to obsługi terminalu tekstowego wideo, który obejmuje większość emulatorów terminali innych niż Windows.
Testowe uruchomienie
Przed wykonaniem rzeczywistego kodu wyłączymy monit i wyczyścimy ekran.
Dzięki temu dane wyjściowe są wyświetlane poprawnie.
Aby przywrócić monit, wykonaj następujące czynności:
Jak to działa
Wstawiamy pionową zakładkę przed każdą samogłoską, aby przesunąć kursor w dół, oraz wystarczającą liczbę sekwencji bajtów 1b 5b 41 (
"\e[A"
) po każdej spacji, aby przenieść kursor z powrotem do pierwszego rzędu.źródło
unset PS1save
później.Java, 428 bajtów
Wiem, to okropne. Prawdopodobnie jest kilka znaków, które można ogolić, ale jestem zbyt leniwy, aby to zrobić.
źródło
int
zmiennych (czylii
,r
,p
,o
, ix
) gdzie można zainicjowaćl
im
ponieważ zostaną one podane wartości później. Możesz także zrobićString v="...",a[]=...;
i zrobić to samo, co powyżejString u
. To powinno znacznie obniżyć twój wynik.x++-~-p
Perl, 31 bajtów
Powyżej jest odwracalny zrzut xxd, ponieważ kod źródłowy zawiera niedrukowalny znak VT (punkt kodowy 0x0b) i ESC (punkt kodowy 0x1b).
Kod ma 27 bajtów i wymaga przełączników
040p
(4 bajty).Program wymaga terminalu tekstowego wideo, który obsługuje pionowe tabulatory i sekwencje specjalne ANSI , który obejmuje większość emulatorów terminali innych niż Windows.
Testowe uruchomienie
Przed wykonaniem rzeczywistego kodu wyłączymy monit i wyczyścimy ekran.
Dzięki temu dane wyjściowe są wyświetlane poprawnie.
Aby przywrócić monit, wykonaj następujące czynności:
Jak to działa
perl -040p
automatycznie odczytuje dane wejściowe jako oddzielone spacjami tokeny (-040
), zapisuje każdy token w$_
(-p
) i wykonuje program.s/[aeiouy]/.$&/gi
wykonuje globalne wyszukiwanie wielkości liter bez rozróżniania wielkości liter$_
i zastępuje każdą samogłoskę znakiem kontrolnym VT (przesuwa kursor w dół), a następnie samą samogłoskę.s
zwraca liczbę dokonanych zamian, więc$\=".[A"x s...
zapisuje wiele kopii sekwencji bajtów 1b 5b 41 (przesuwa kursor w górę)$\
, po jednej dla każdej samogłoski.Po zakończeniu programu Perl automatycznie drukuje z
"$_$\"
powodu-p
przełącznika.źródło
C,
200190 bajtówNie golfowany:
Przydziela bufor prostokątny (właściwie kwadratowy), wypełnia go spacjami i znakami nowej linii, a następnie przechodzi przez podany ciąg. Na końcu dodaje pusty znak, aby zapobiec końcowym znakom nowej linii.
Technicznie nie jest to funkcja, ponieważ zawiera globale; w rzeczywistości nie może być wywoływany więcej niż raz (
j
il
musi być 0 na początku). Aby zachować zgodność,i,j,k,l,M;
można go przenieśćint i,j=0,k,l=0,M;
na początku funkcji.źródło
char*t=malloc(M*M);
->char t[M*M];
ifor(i=0;i<M*M;++i)
->for(;i<M*M;++i)
char t[M*M]
?CJam, 47 lat
Tak, jest trochę długi, ale to nie jest „oszukiwanie” za pomocą kodów ANSI :)
Wypróbuj online
Chodzi o to, aby obliczyć liczbę wierszy dla każdego znaku (zaczynając od 0, zwiększając samogłoski i skacząc z powrotem do 0 w spacji), a następnie dla każdej linii powtórz ciąg, ale zamień znaki, które mają inny numer wiersza, spacją .
źródło
K,
81727066 bajtówCóż, to początek:
Przykłady użycia:
Edycja 1:
Lepszy. Wprowadzono pewne ulepszenia poziomu powierzchni:
W szczególności odwróciłem argumenty,
?
gdy wykonuję wyszukiwanie samogłosek, i tym samym wyeliminowałem potrzebę lambda, zrobiłem tę samą inwersję z tym, w_
którym dzielę słowa na białe znaki, i zdałem sobie sprawę, że~{" "?x}'x
to naprawdę głupi, zbyt skomplikowany sposób wypowiadania się" "=x
.Edycja 2:
Kolejna poprawka poziomu powierzchni - negacja
s
przed nałożeniem jej na lambda, oszczędzając w środku pareny:Edycja 3:
OK, zastosujmy inne podejście do obliczania przesunięcia dla każdego znaku. Zamiast dzielić sekwencję na spacje i obliczać sumę bieżącą (
+\
) pozycji samogłosek, możemy operować na całym ciągu wejściowym w jednym przejściu, mnożąc sumę bieżącą przez 0 za każdym razem, gdy napotykamy spację. Potrzebuję negacji tej sekwencji, więc mogę odejmować zamiast dodawać podczas skanowania i używać liczby-odrębnych (#?
) zamiast max (|/
) podczas obliczania ilości pionowego wypełnienia.To oszczędza kolejne 4 znaki. Uff!
źródło
Rubin:
135131124115112 znakówPrzykładowy przebieg:
źródło
/(?=[aeiouy ])/i
.C, 192 bajty
Powoduje to iterację ciągu, wygaszanie znaków podczas ich drukowania. Powtarza się, dopóki nie zostaną żadne znaki spacji do wydrukowania. Jest przenośnym C, nie przyjmuje żadnych założeń dotyczących kodowania znaków.
Wersja do odczytu
źródło
' '
->32
if(char*s){int l=0,r=1,v,c;
->l,r=1,v,c;f(char*s){
' '
może być32
, ale zależy to od kodowania znaków, i jak powiedziałem, zrobiłem to przenośne C. Upuszczenie wyraźnegoint
jest jednak świetne - nie jestem pewien, dlaczego o tym zapomniałem!Python 3,
265207202185177 znakówTo okropne i nie jestem dumny. Wiem, że można to skrócić, ale myślałem, że i tak opublikuję.
Zainspirowany wersją C tworzy listę, która jest następnie wypełniana podczas przechodzenia przez ciąg wejściowy.
źródło
GNU Sed, 151 + 1
(+1, ponieważ potrzebuje
-r
flagi)Myślałem, że sed będzie narzędziem do tej pracy, ale uznałem to za zaskakująco trudne.
Wersja do odczytu:
źródło
p
, więc nic nie wyświetla. Mały problem polega na tym, że wyjścia zaczynają się od dodatkowej przestrzeni. Ogromnym problemem jest to, że znika pierwsza część tekstu zaczynająca się od samogłoski.c
, z powodu linii tuż przedtx
. Przywróciłem wcześniejszą wersję z podobną pętlą i spróbuję później.Python 2,
145142 bajtówPrawdopodobnie nie jest tak konkurencyjny jak niektóre inne metody, ale pomyślałem, że to fajny sposób na użycie wyrażenia regularnego.
Wyrażenie regularne
(?!([^aeiouy ]*[aeiouy]){N}[^aeiouy]* ).
dopasowuje dowolny pojedynczy znak spoza N-tej grupy liter od końca słowa. Ponieważ liczy się od końca świata, odwracam ciąg przed i po nim, a także muszę dodać spację na końcu, ale potem staje się prostą sprawąre.sub
zastąpienie każdego wystąpienia tych znaków spacją. Robi to dla każdej wartości N, dopóki łańcuch nie będzie pusty.źródło
re.I
, możesz zapisać 3 bajty, zastępując odpowiednią wartość flagi, tj2
.Oktawa,
132129 znakówTest
Wkład:
"YEAh UppErcAsE VOwEls"
Wydajność:
źródło
Gema :
5348 znakówZauważ, że
^[
(x1b) i^K
(x0b) są pojedynczymi znakami. (W poniższym przykładzie biegu używam ich kopiowania i wklejania przyjazny\e
i\v
ekwiwalentów, w przypadku, gdy chcesz go wypróbować.)Przykładowy przebieg:
źródło
Galaretka , 42 bajty (niekonkurujące?)
Wypróbuj online!
Dlaczego galaretka, dlaczego? :-(
źródło