Jako programista prawdopodobnie słyszałeś o ukośnikach do przodu i do tyłu. Ale czy słyszałeś o obluzowaniach? Wtedy bierzesz kilka cięć, łączysz ich końce i rysujesz je w dół.
W dzisiejszym wyzwaniu musisz napisać program lub funkcję, która pobiera ciąg składający się wyłącznie z ukośników i wypisuje wszystkie ukośniki narysowane w dół w linii łączącej je. Będzie to o wiele wyraźniejsze, jeśli zobaczysz przykład. Biorąc pod uwagę ciąg \\\//\/\\
, powinieneś wypisać:
\
\
\
/
/
\
/
\
\
Oto kilka wyjaśnień:
Musi być jeden ukośnik na linię.
Pierwsza linia będzie miała 0 wiodących spacji.
Dla każdej pary ukośników:
Jeśli różnią się od siebie, zostaną narysowane w tej samej kolumnie. Na przykład
\/
da:\ /
Jeśli są tą samą postacią, dolna jest skierowana w kierunku wskazywanym , czyli przesuwa się w prawo, aby wykonać ukośnik odwrotny, i przesuwa się w lewo, aby wykonać ukośnik. Więc
\\//
da\ \ / /
Każda linia może mieć dodatkowe końcowe białe znaki, o ile nie zmienia to wyglądu obrazu wyjściowego. Dopuszczalny jest nawet jeden końcowy i wiodący nowy wiersz. Dodatkowe spacje wiodące są niedozwolone !
Aby uprościć to, możesz założyć, że ciąg nigdy nie będzie zawierał zbyt wielu ukośników. Innymi słowy, żaden prefiks wejścia nie będzie zawierał więcej ukośników niż ukośniki odwrotne, więc dane takie jak \\////
lub //
nigdy nie zostaną podane. Oznacza to również, że każde wejście zacznie się od ukośnika odwrotnego.
Jeśli twoje dane wejściowe są traktowane jako literał łańcuchowy, możesz uciec od ukośników odwrotnych, jeśli jest to konieczne. Nigdy nie będziesz musiał obsługiwać danych wejściowych, które są puste lub zawierają znaki inne niż ukośnik.
Możesz drukować w dowolnym rozsądnym formacie .
Jak zwykle jest to wyzwanie związane z golfem , więc postaraj się znaleźć możliwie najkrótsze rozwiązanie, nawet jeśli wybierzesz język, w którym jest to dość trudne. Punkty bonusowe za wyjaśnienie wszelkich interesujących technik, których użyłeś do zdjęcia bajtów!
Przykłady
#Input
\\\\\\\\\\\
#Output
\
\
\
\
\
\
\
\
\
\
\
#Input
\\\//\\/\//\\///
#Output
\
\
\
/
/
\
\
/
\
/
/
\
\
/
/
/
#Input
\/\/\/
#Output
\
/
\
/
\
/
Odpowiedzi:
GNU Sed, 20
Zauważ, że
^L
i^H
są dosłowne znaki formfeed i backspace (0x12 i 0x8).Ta odpowiedź polega na przesuwaniu kursora za pomocą znaków Backspace i Formfeed. Ukośniki / odwrotne ukośniki nie są wypełnione lewą spacją - Nie jestem pewien, czy to dyskwalifikuje tę odpowiedź. To nie działa w TIO, ale wygląda dobrze pod zwykłymi terminalami, takimi jak
xterm
ignome-terminal
.Odtwórz ten skrypt sed w następujący sposób:
Uruchom w następujący sposób:
Wyjaśnienie:
źródło
Węgiel drzewny ,
131211 bajtówWypróbuj online! Link jest do pełnej wersji kodu. Obsługuje dodatkowe
//
s. Wyjaśnienie:źródło
↓¶
= „Przesuń w lewo” w opisie jest niewłaściwy.\n/
dół”print \n/ down
ponieważ uważałem, że bardziej pomocne byłoby opisanie efektu kodu niż jego dosłowne tłumaczenie.MyCode - Do the spec
). Rozumiem teraz, ale efektem jest przesunięcie w lewo; może warto powiedzieć „Przesuń w lewo (drukując nowy wiersz z kierunkiem drukowania w dół)”.Python 2 ,
5554515753 bajtów-3 bajty (i poprawka błędu) dzięki Felipe Nardi Batista
Wypróbuj online!
źródło
/// , 119 bajtów
/// nie ma poleceń wejściowych, więc dane wejściowe muszą być osadzone w programie. W tym przypadku łańcuch wejściowy jest po prostu dołączany, bez konieczności zmiany znaczenia.
-d
opcją (stan programu pokazany w nawiasach przed uruchomieniem każdego polecenia).Jak to działa
\\/\//
zostanie dołączone wejście programu do demonstracji.
służy do reprezentowania znaków nowej linii w kodzie wbudowanym.Skróty
Początek
/=/\/\///M/|%%=N/%|||=C/BA=
programu zawiera zamienniki skrótów golfowych.=
rozwija się do//
,M
do|%%
,N
do%|||
iC
doBA
.Po tym następuje bieżący program
Przekodowywanie wejścia
Następny etap przekształca dołączony ciąg wejściowy w bardziej użyteczną formę. Ponieważ składa się wyłącznie z dwóch znaków polecenia ///, należy zachować ostrożność, aby uniknąć zakłócenia programu podstawowego.
/\/\\/\/BA\\/
zastępuje ciąg/\
przez/BA\
./\
w tej chwili, więc podstawienie go nie zmienia.\
s, po których następują sekwencje/
s, co wraz zABA
końcem programu podstawowego umożliwia iterację poprzez następujące podstawienia.ABA
przedrostek, przykładowy ciąg wejściowy staje się terazABA\\/BA\//
./BA\\/BAbBA/
, zastępuje sięBA\
przezBAbBA
.\
s łańcucha wejściowego, który z prefiksem staje się terazABAbBAbBA/BAbBA//
/B\A\//BAfBA/
zmianyBA/
wBAfBA
, iterowanie po/
s.\
w tej substytucji jest potrzebna, ponieważ w przeciwnym razie zostałaby uszkodzona przez poprzednią.ABAbBAbBAfBABAbBAfBAfBA
./AB//
usuwa niektóre zbędne części kodowania, zamieniając je wAbBAbBAfBAbBAfBAfBA
.AB
z/|/AB\\/
podstawieniem w dalszej części programu, który był potrzebny, aby chronić je od powyżej/\
manipulacji.\
pierwotny ciąg wejściowy stał sięAbB
i każdy/
stał sięAfB
. (b
if
stanąć do tyłu i do przodu.) NaA
końcu jest zbłąkany .A
s iB
s fragmentami programu do uruchomienia w końcowym etapie. W ciągach zastępczych%
s i|
s kodują odpowiednio to, co stanie się/
s i\
s. Ma to dwie zalety:/
i\
,%
s i|
s nie muszą uciekać, aby zostać skopiowane./\
, które w przeciwnym razie zostałyby zniekształcone przez poprzednie manipulacje./|/\\/
(wcześniej/|/AB\\/
) teraz dekoduje|
s, po której następuje/%/|//
stała się/%/\//
i dekoduje%
s.Struktura programu na końcowym etapie
W tym momencie program podstawowy uruchomił wszystkie swoje podstawienia, a pozostaje tylko kodowanie programu ciągu wejściowego.
Każdy znak wejściowy stał się podprogramem
(końcowy znak nowej linii), gdzie
*
reprezentuje albof
oryginał/
, albob
oryginał\
./\//xy
końcu programu znajduje się również niepełna komenda substytucji , która nie przyniesie żadnego efektu, poza zapewnieniem niezbędnego/
zastąpienia poprzedniego podprogramu.Współużytkowany podciąg
Zanim rozpocznie się końcowa iteracja przez podprogramy, po podprogramie każdej postaci w formularzu znajduje się podciąg
\//
./
zostanie uruchomiona jego kopia tego wspólnego podłańcucha (z wyjątkiem końcowego , który zakotwicza podstawienia), aby wydrukować linię dla tego postać./
, który jest właściwą wyimaginowaną „poprzednią linią”, aby spowodować wydrukowanie pierwszego znaku wejściowego na początku jego linii.\\
lub\/
nowej linii i następujących po nim/
.Uruchamianie podprogramu znaków
Kilka poniższych podstawień zawiera dodatkowe
\
s wewnątrz, aby zapobiec ich wzajemnemu dopasowaniu i zniekształceniu (w tym innym kopiom w innych podprogramach). Osiągnięcie to jest również powód, dlaczego obax
iy
są potrzebne./\//xyf\z/
lub/\//xyb\z/
powoduje, że/
na końcu współdzielonego podłańcucha staje sięxyfz
lubxybz
, bezpośrednio po\/
lub\\
./\\\\x\y/ /
zastępuje\\xy
się spacją, a podstawienie/\\\/x\y//
zastępuje\/xy
nic.\
lub/
.\
następnego, a następniefz
lubbz
./ \fz/\\\/\//
zastępuje fz
przez\//
i/b\z/\\\\\//
zastępujebz
przez\\/
./
lub\
./
poprawnie.///
, co jest nieskończoną pętlą./
na końcu udostępnionego podłańcucha.Po uruchomieniu podprogramu ostatniego znaku pozostała część programu
/\//xy
. Ponieważ jest to niepełna zamiana z brakującym końcem/
, program pomija ją i zatrzymuje się normalnie.źródło
Galaretka , 14 bajtów
Pełny program drukujący wynik.
Wypróbuj online!
W jaki sposób?
źródło
Haskell , 49 bajtów
Wypróbuj online!
źródło
Perl 5 , 44 bajtów
42 bajty kodu + 2 dla
-F
flagiWypróbuj online!
źródło
JavaScript (ES8),
665963 bajtów7 bajtów zapisanych dzięki Justin Mariner
+ 4 bajty do naprawy
/\\/\\/
(zauważone przez Neila )Wypróbuj online!
źródło
MATL ,
231918 bajtów1 bajt off dzięki @Sanchises
Dane wejściowe to ciąg ujęty w pojedyncze cudzysłowy.
Wypróbuj online! Lub sprawdź przypadki testowe: 1 , 2 , 3 .
Wyjaśnienie
Rozważ dane wejściowe
'\\\//\/\\'
jako przykład.źródło
C # (.NET Core) ,
748882787776 + 18 bajtów-1 bajt dzięki Kevin Cruijssen
Generuje kolekcję ciągów, po jednym dla każdej linii. Liczba bajtów obejmuje również:
Wypróbuj online!
Wyjaśnienie 77 bajtowej odpowiedzi:
źródło
/\\/\\/
.s.Take(i).Sum(y=>y<92?-1:1)+(x-s[0])/45+1
na(x-s[0])/45-~s.Take(i).Sum(y=>y<92?-1:1)
05AB1E , 14 bajtów
Wypróbuj online!
Wyjaśnienie
źródło
/\\/\\/
.Ç¥.¥0<.SηOv¹Nèy<ú,
szlochając w systemie binarnymR ,
122121 bajtów-1 bajt dzięki Giuseppe
Wypróbuj online!
Z dodatkową spacją:
Objaśnienie: Ta odpowiedź jest oparta na spostrzeżeniu, że liczba wiodących spacji zmienia każdą linię o -1, plus liczba
/
poprzednich i bieżących linii.Jeśli mamy N ukośników, zmienna
y
jest wektorem długości N, z 1 dla każdej pozycji z\
, w przeciwnym razie 0. Dlatego, aby uzyskać zmianę liczby wiodących spacji w wierszu, obliczamyy[1:(N-1)] + y[2:N] - 1
. Ta funkcjadiffinv
przekształca te różnice w sekwencję, zaczynając od 0. Reszta to tylko kwestia złożenia każdej linii jako wymaganej liczby końcowych spacji, a następnie odpowiedniego ukośnika i nowej linii.źródło
diffinv
;) Możesz także ustawićy=x>")"
na -1 bajtstrsplit
, co zawsze jest zabójcą. Możesz także skorzystać ze słynnegodiffinv
!library(methods)
nagłówek (co powinno być OK bez kary, ponieważ ten pakiet jest częścią podstawy R), możesz użyćel
.diffinv
Okazało się też, że jest tak długo, jakcumsum
! :)*S
wszystko psuje.Brain-Flak , 175 bajtów (174 znaków + 1 flaga)
Uruchom z
-c
flagą.Wypróbuj online!
Wyjaśnienie
źródło
Rubinowy ,
8076 bajtów-4 bajty dzięki manatwork
Wypróbuj online!
Wyjaśnienie:
źródło
.each_cons(2){…}
. W zamian możesz zapisać, zastępując.each_char
→.chars
.i+=
na początek zagnieżdżonego wyrażenia trójskładnikowego i kończąc go-1:1:0
.Java 8,
121118110109102 bajtów-7 bajtów dzięki nieco magicznej magii @Nevay . :)
Wyjaśnienie:
Wypróbuj tutaj.
źródło
a->{String r="";int s=0,p=0,i;for(char c:a){for(i=s+=p+(p=c-63)>>5;i-->0;r+=" ");r+=c+"\n";}return r;}
>>
/>>>
/<<
... Sprawdziłem tylko niektóre rzeczy w&
/|
/~
/^
..>.>C (GCC),
13713497 bajtówWypróbuj online!
• 3 bajty dzięki ATaco
• 37 bajtów dzięki Digital Trauma i ThePirateBay
Nic nadzwyczajnego, tylko prosta funkcja rekurencyjna, która pobiera ciąg znaków i wypisuje ukośniki. Zauważ, że wejście musi najpierw uciec przed odwrotnym ukośnikiem.
Stosowanie
Bez golfa
To jest dla starej odpowiedzi, zobacz link online wypróbuj zaktualizowany!
Wynik
źródło
c=='\0'
ze!c
dla tego samego efektu.printf("%*s%c", n, "", c)
do wydrukowania znaku z n wiodącymi spacjami?(c!=n)
zec-n
i rozmieszczanie wyrażeń trójskładnikowych. To samo z(c=='/')
. Możesz także zastąpić'/'
literalną liczbą47
. Myślę, że w sumie jest to 7 bajtów.C, 60 bajtów
Wypróbuj online!
źródło
Siatkówka , 47 bajtów
Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:
Dodaj spację na początku każdej linii i przed każdą
\
.Rozważ pierwsze dwa znaki ciągu. Jeśli pierwszym jest a,
/
to tiret musi zostać zmniejszone; osiąga się to poprzez włączenie poprzedniej przestrzeni do przechwytywania (która zawsze istnieje, ponieważ dodano ją w pierwszym etapie); jeśli drugi jest,\\
to należy go zwiększyć; osiąga się to poprzez włączenie przestrzeni, którą pierwszy etap dodał do przechwytywania. Po nadaniu drugiemu znakowi poprawnego wcięcia etap powtarza się dla drugiego i trzeciego znaku itp.Usuń dodatkowe wcięcie.
Napisałem 94-bajtową wersję, która (podobnie jak moja odpowiedź na węgiel drzewny) pozwala na dowolną kombinację ukośników: Wypróbuj online! Wyjaśnienie:
Spraw, aby piłka potoczyła się, biorąc ostatni cios i wciskając go w to samo miejsce na swojej linii.
Prefiks spacji do wszystkich ukośników do przodu, aby można je było uchwycić.
Kilkakrotnie weź ostatni ukośnik wejścia i wyrównaj go we własnej linii z ukośnikiem w linii poniżej.
Usuń wszelkie pozostałe wcięcia.
Usuń teraz puste wejście.
źródło
Lua , 96 bajtów
Wypróbuj online!
Najkrótszy, jaki mogłem wymyślić w Lua. Dane wejściowe są pobierane z wiersza poleceń.
Wykorzystuje to kilka sztuczek:
(...):gmatch(
Powinno to być najkrótsza forma wprowadzenia pojedynczego ciągu do programu Lua z wiersza poleceń.
...
Wyraz w Lua rejestruje żadnych nadmiarowych parametrów do funkcji, które nie są wymienione w deklaracji funkcji i jest używany do varargs. Ponieważ główna treść programu Lua jest wywoływana jako funkcja z argumentami wiersza poleceń jako parametrami, argumenty wiersza polecenia kończą się na...
.Nawiasy wokół niego przekształcają
...
wyrażenie potencjalnie wielowartościowe w wyrażenie jednowartościowe. Rozważ ten (nieco zaskakujący) przykład:and
/or
dla logiki „jeśli x to wartość 1 inaczej wartość 2”. OperatorLui
and
zwraca swój pierwszy argument, jeśli jest fałszem; w przeciwnym razie zwraca drugi argument.or
Operator zwraca pierwszego argumentu jeśli jest truthy; w przeciwnym razie drugi argument.p
nie wymaga żadnej inicjalizacji.p==s
zawsze musi być fałszywy w pierwszym uruchomieniu pętli, niezależnie od danych wejściowych. Brak ustawieniap
żadnej wartości przed wejściem do pętli (pozostawienie jejnil
) spowoduje, że tak się stanie i zaoszczędzi bajty.Czy ktoś może zagrać w golfa (w Lua)?
źródło
c=0(...):gsub(".",function(s)c=c+(p==s and(s=="/"and-1or 1)or 0)p=s print((" "):rep(c)..s)end)
gmatch(".")
sięgmatch"."
tak, jak w następnej odpowiedzi.Pyth , 28 bajtów
Wypróbuj online!
źródło
Q
zamiast:j.u+?qeNY?>Y\/+PNdPPNPNYtQh
.R 119 bajtów
Wypróbuj online!
Różni się to nieco od odpowiedzi user2390246 . Każdy z nich iteruje ciąg, wypisując określoną liczbę znaków spacji, a następnie odpowiedni
/\
znak.Jednak uniknąłem podziału łańcucha, zamiast tego zdecydowałem się zastąpić znaki ich wartością kodowania UTF-8, co pozwala mi wykonywać arytmetykę liczb bezpośrednio, co pozwoliło mi zaoszczędzić tylko kilka bajtów.
źródło
diffinv
zdecydowanie nie zadziała tutaj.C # (.NET Core) , 60/65 bajtów
Próbowałem krótszej wersji C #
jak stwierdzono: „Oznacza to również, że każde wejście będzie zaczynać się odwrotnym ukośnikiem”. Lub nieco dłużej, co rozwiązuje początek „/”
Wypróbuj online!
źródło
Lua ,
8884 bajtówUlepszona wersja (-4 bajty dzięki QuertyKeyboard)
Wypróbuj online!
Wersja oryginalna (88 bajtów)
Kolejna próba w Lua, tym razem z zupełnie innym podejściem, wykorzystująca manipulację ciągiem zamiast zmiennej przeciwnej.
Nie golfowany:
W kodzie jest jedna interesująca rzecz:
(...):gmatch"."
wykorzystuje kilka dziwactw w parserze Lua. Kiedy Lua napotka fragment kodu w formularzu
func "string"
, przekształci go nafunc("string")
. Dzieje się tak, aby można było napisać,print "string"
aby wydrukować stały ciąg znaków i działa tylko z jednym dosłownym ciągiem znaków po funkcji. Wszystko inne da błąd składniowy. Jednak ten cukier syntaktyczny działa również z wywołaniami funkcji w środku wyrażenia i, co bardziej zaskakujące, działa dobrze w połączeniu z:
wywołaniem metody cukru syntaktycznego. W końcu Lua zinterpretuje kod w następujący sposób:Jeśli ktoś wymyśli sposób na usunięcie jednego z trzech połączeń gsub, proszę mi powiedzieć.źródło
s=""g=s.gsub g(...,".",function(c)s=g(g(g(s,"\\"," "),"/?$",c)," /","/")print(s)end)
Pyth - 33 bajty
Pierwsza próba, golf.
Wypróbuj online tutaj .
źródło
Perl, 40 + 2 bajty
Potrzebujesz
-F
flagi.źródło
Perl,
3438 + 1 bajtówdo obsługi dwóch przypadków
do uruchomienia z
-p
opcjąEDYCJA: następujący komentarz nie działa, gdy jest pierwszy znak
/
jednak wynik zostanie przesunięty o jeden znak po prawej stronie, jeśli jest to pierwszy znak
\
źródło
/\\/\\/
.34
rozwiązanie jest teraz całkowicie poprawneVBA (Excel), 181 bajtów
źródło
[...]
notacji: zmniejszyłem go do 128 bajtówSub q
For x=1To[Len(A1)]
c=Mid([A1],x,1)
If c="\"Then Debug.?b;c:b=b+" "
If c="/"Then b=Left(b,Len(b)-1):Debug.?b;c
Next
End Sub
Pyth ,
2421 bajtówPort od odpowiedzi Rod .
Wypróbuj online!
źródło
\
. BTW, gdzie jest twój kod?SOGL V0.12 ,
1613 bajtówWypróbuj tutaj! - oczekuje danych wejściowych na stosie, więc
,
dodano dla ułatwienia użytkowaniaźródło
Dyalog APL, 31 bajtów
Wypróbuj tutaj!
źródło
{↑⍵↑¨⍨a-1-+\¯1*a←⍵='\'}