Cóż, podsumuj to naprawdę.
Napisz program lub funkcję, która pobierze niepustą listę liczb całkowitych dziesiętnych (0–9) i wyświetli skierowany w dół „trójkąt” cyfr z listą wprowadzania na górze, gdzie każda cyfra po pierwszym wierszu jest sumą dwóch cyfr powyżej to modulo 10.
Na przykład wejście [7, 5, 0, 9]
ma dane wyjściowe
7 5 0 9
2 5 9
7 4
1
ponieważ 2
jest (7 + 5) mod 10
, 5
jest (5 + 0) mod 10
, 9
jest (0 + 9) mod 10
itd. przez całą drogę do 1
istnienia (7 + 4) mod 10
.
Jeśli lista zawiera tylko jeden element, wówczas dane wyjściowe są zgodne z danymi wejściowymi; np. wkład [4]
woli da
4
Oto kilka dodatkowych przykładów:
[0]
0
[1, 2]
1 2
3
[8, 7]
8 7
5
[0, 0]
0 0
0
[1, 4, 2]
1 4 2
5 6
1
[0, 1, 0]
0 1 0
1 1
2
[1, 0, 0, 0]
1 0 0 0
1 0 0
1 0
1
[1, 2, 3, 4]
1 2 3 4
3 5 7
8 2
0
[1, 2, 3, 5, 8]
1 2 3 5 8
3 5 8 3
8 3 1
1 4
5
[9, 2, 4, 5, 3, 2, 2]
9 2 4 5 3 2 2
1 6 9 8 5 4
7 5 7 3 9
2 2 0 2
4 2 2
6 4
0
Zauważ, że na wyjściu:
- Pierwszy wiersz nie ma spacji wiodących.
- Każda kolejna linia ma jeszcze jedną spację wiodącą niż poprzednia linia.
- Cyfry są oddzielone pojedynczym odstępem.
- Każda linia może mieć maksymalnie jedno końcowe miejsce.
- Może występować pojedynczy opcjonalny znak nowej linii.
- Musisz używać znaków dla normalnych cyfr dziesiętnych (od 0 do 9).
Najkrótszy kod w bajtach wygrywa. Tiebreaker to wcześniejsza odpowiedź.
Odpowiedzi:
BrainF ** k,
396391 bajtówNie mogłem oprzeć się pokusie zrobienia tego. Przynajmniej trójkąt jest spiczasty bokiem.
Wprowadzane dane są ciągiem znaków numerycznych, po których następuje pojedynczy znak nowej linii.
Dane wyjściowe będą zawierać pojedyncze końcowe miejsce w każdym wierszu.
Przykłady:
Wyjaśnienie
Ponieważ trudno jest wyjaśnić kod z perspektywy funkcjonalnej, możemy zamiast tego spojrzeć na niego z perspektywy stanu taśmy w różnych momentach. Podstawową ideą jest to, że trójkąt, który wysyłamy, jest inicjalizowany jako ciasno upakowana (w każdym razie BF) tablica, która zmniejsza się o 1 przy każdej iteracji pętli. Inną ważną myślą jest to, że używamy
255
do wskazania „symbolu zastępczego”, który możemy wyszukać na taśmie.Inicjalizacja
To najłatwiejszy krok. Na początku programu wykonujemy następujące czynności:
Wymusza to przejście taśmy w następujący stan (gdzie
>N<
wskazuje położenie wskaźnika na taśmie)Pierwszą liczbą tutaj jest lokalizacja „buforowa”. Nie będziemy go używać długoterminowo, ale przydatne jest uproszczenie niewielkich operacji i kopiowanie danych.
Druga liczba to liczba spacji, które będziemy wypisywać na początku każdej linii, zaczynając od pierwszej linii. Pierwsza linia nie będzie miała spacji wiodących.
Trzecia liczba to znak spacji, który wypisujemy.
Czwarta liczba to symbol zastępczy 255, dzięki czemu możemy stosunkowo łatwo wrócić do tej pozycji.
Wkład
Z tej pozycji będziemy czytać wszystkie postacie. Pod koniec tego kroku mamy nadzieję, że znajdziemy się w następującej sytuacji:
Gdzie
a b c d e f ...
wskazuje ciąg znaków numerycznych, który został wprowadzony (nie nowy wiersz).Osiągamy to poprzez:
Są w tym pewne niuanse. Po pierwsze, wypisujemy każdy znak, gdy go otrzymamy, a następnie wypisujemy po nim spację. Po drugie, nie chcemy kopiować wartości ASCII na taśmę, chcemy skopiować rzeczywistą cyfrę. Po trzecie, chcemy przestać, kiedy trafimy na nową linię i pozostawimy się w tym miejscu w dobrym miejscu.
Powiedz, że nasz wkład to
6723
. Następnie, po przeczytaniu pierwszego6
, nasza taśma wygląda następująco:Sprawdzamy, czy ta wartość nie jest równa
10
(nowa linia ASCII) z,----------[++++++++++
. Następnie drukujemy wartość i kontynuujemy odejmując jednocześnie 48 od wartości wejściowej i dodając 32 do wartości obok niej (>>++++++++[-<++++<------>>]<
), pozostawiając nas tutaj:Zauważ, jak w tym procesie możemy założyć, że wszystkie cyfry po prawej stronie naszych danych wejściowych są równe 0 - oznacza to, że nie grozi nam zniszczenie jakiegokolwiek poprzedniego stanu, jeśli użyjemy wartości po prawej stronie do obliczenia
6 * 8
i4 * 8
.Teraz wypisujemy wygenerowany właśnie znak spacji i przyjmujemy nowe dane wejściowe, usuwając obliczone tam miejsce. Ostatecznie wejście zostanie zakończone nową linią i pętla wyjdzie, pozostawiając miejsce, w
255
którym byłaby nowa linia (,----------]-
). Jest to drugi znak zastępczy, którego użyjemy do nawigacji na taśmie. W tym momencie naszego scenariusza nasza taśma jest dokładnie taka:Obliczenie
Działa to w ten sposób, że lista cyfr między naszymi
255
symbolami zastępczymi będzie się zmniejszać o jedną iterację pętli. Gdy pozostanie w nim tylko 1 cyfra, jesteśmy skończeni i powinniśmy natychmiast się zatrzymać (zwróć uwagę, że w tym momencie każda cyfra z tej listy została już wydrukowana, więc nie musimy się martwić o jej ponowne wysłanie).Mamy teraz skorzystać z tej sztuczki, aby przejść do pierwszego
255
zastępczy:<+[-<+]-
. To skutecznie przeszukuje taśmę po lewej stronie w poszukiwaniu255
, nie zmieniając niczego pomiędzy. Teraz, gdy przesunęliśmy wskaźnik, możemy sprawdzić nasz warunek wyjścia: jeśli na liście jest tylko jedna cyfra, to komórka pomieści dwie spacje po prawej stronie255
. Sprawdzamy więc to i uruchamiamy pętlę:>>+[-<<
Pierwszym krokiem w naszej pętli jest wygenerowanie nowego wiersza. Przechodzimy więc do pierwszej komórki (naszej komórki buforowej), dodajemy do niej 10 i wyprowadzamy. Następnym krokiem jest wyprowadzenie wszystkich wiodących znaków spacji. Po ich wyliczeniu zwiększamy naszą liczbę o liczbę wiodących spacji. Kroki te są realizowane przez:
Co pozostawia nas w tym stanie:
Naszym następnym krokiem jest skopiowanie pierwszej wartości z listy obok drugiego symbolu zastępczego
255
:Zasadniczo robimy to, przeskakując tam iz powrotem między naszymi symbolami zastępczymi
255
, pozostawiając nas tutaj:Rozpoczynamy teraz pętlę, iterując resztę listy, zatrzymując się po trafieniu
255
:>+[-<
W tym momencie cyfra po naszej lewej stronie wynosi zawsze 0. Tak więc, ponieważ je kochamy, wstawiamy
255
tam symbol zastępczy , abyśmy mogli wrócić do naszego miejsca na liście. Następnym krokiem jest przeniesienie drugiego miejsca na liście do lokalizacji, w których przenieśliśmy pierwsze miejsce, obok drugiego symbolu zastępczego255
. Kroki te są realizowane przez:Zostawiając nas tutaj:
[ 0 2 32 255 255 >0< 2 3 255 7 6 7 0 ]
Teraz zarówno6
i , jak i7
zostały przeniesione do miejsca, w którym mogą wystąpić obliczenia. Potrzebujemy dwóch kopii,7
ponieważ następny numer na liście również będzie go potrzebował.7
Natychmiast po255
służy temu celowi, podczas gdy inne7
będą spożywane przez obliczeniach.Najpierw dodajemy dwie cyfry:
Zostawiając nas tutaj:
Kolejna kombinacja kroków jest najbardziej skomplikowana. Musimy sprawdzić, czy wskazana liczba jest większa niż 10, a jeśli tak, to odejmujemy
10
. W rzeczywistości odejmujemy od niego 10 i sprawdzamy, czy trafi0
w którymkolwiek punkcie odejmowania. Jeśli tak, dodajemy10
później. Na koniec powinniśmy mieć sumę modulo 10.W tym momencie osiągnęliśmy cel. Mamy sumę modulo 10! Ponadto, niezależnie od tego, czy liczba była większa niż 10, skończymy tutaj:
Naszym kolejnym celem jest wyprowadzenie tej nowej sumy, dodanie jej spacji i wprowadzenie jej z powrotem na naszą listę. Robimy to wszystko za pomocą naszych poprzednich technik
255
kupowania i dodawania48
do naszej sumy, więc nie będę tego szczegółowo omawiać.I jesteśmy tutaj:
[ 0 2 32 255 3 255 2 3 255 7 0 0 51 >32< ]
zauważ, jak255
wstawiamy dodatkowy symbol zastępczy po naszym nowym wstrzyknięciu,3
aby nie stracić miejsca na liście. W tym momencie wyprowadziliśmy naszą sumę i jej przestrzeń, więc musimy wyczyścić i powrócić do stanu, w którym zadziała kolejna iteracja tej pętli. Musimy wyczyścić nasze51
i32
komórki, przesunąć7
raz w prawo i przejść do naszego symbolu zastępczego listy, abyśmy mogli zacząć od nowa.Teraz jesteśmy tutaj:
[ 0 2 32 255 3 >0< 2 3 255 0 7 0 ... ]
właśnie tam chcemy być na następnej iteracji. Więc sprawdź 255 i idź dalej! (
>+]
)Kiedy zostaniemy wysadzeni z pętli, będziemy mieli zupełnie nową listę - złożoną z sum z poprzedniej listy. Za pierwszym razem będzie to wyglądać tak:
Teraz chcemy powtórzyć cały proces na naszej nowej liście, więc przeskoczymy w
255
dół i zaczniemy od nowa! Musimy zrobić trochę czyszczenia>>[-]<<
, a następnie upuścić nasz symbol zastępczy<-
. Potem jesteśmy dokładnie w tym samym miejscu, w którym byliśmy po wejściu, więc możemy uniknąć tych samych kontroli:<+[-<+]->>+
i bum! Mamy pełną pętlę! Wszystko, czego potrzebujemy jest nawias zamykający, a kiedy kończy mamy już wyjścia wszystko, więc skończymy:]
.źródło
Galaretka ,
201918 bajtówWypróbuj online!
tło
Generowanie liczb jest proste w Jelly. Wynik jest nieco bardziej skomplikowany.
Galaretka ma wbudowaną siatkę atom (
G
), która wyświetla listę 2D z nowymi liniami między wierszami i spacjami między kolumnami. Bierzemy tablicę liczb 2D (generowaną przy odwróceniu każdego wiersza) i transponujemy ją z wartością wypełnienia@
. Po odwróceniu wynikowej tablicy i ponownej transpozycji, zastosowanieG
daje następujące.Aby uzyskać pożądany kształt trójkąta, wystarczy usunąć wartość wypełnienia.
Jak to działa
źródło
Pyth - 18 bajtów
Pakiet testowy .
źródło
Python 3.5,
747271 bajtówWejście to lista liczb całkowitych (np.
f([1,2,3,5,8])
), Wyjście to STDOUT.%10
Oraz fakt, żemap
zwracamap
obiekt w Pythonie 3 jest nieco irytujące, co oznacza, że nie możemy zrobić,map(lambda*x:sum(x)%10,L,L[1:])
lub podobny.Funkcja wyskakuje, ale do tego czasu dane wyjściowe zostałyby zakończone. Dzięki @xsot za -1 bajt, znajdując dobre miejsce do przyklejenia
print
.źródło
f=lambda L,*S:f([sum(x)%10for x in zip(L,L[1:print(*S,*L)]or 1)],'',*S)
None
!print
coś zwraca? Nie wiem oprint
powrocie funkcji.print
powrót funkcji Pythona - tak, powraca onaNone
po zakończeniuNone
krojenie?05AB1E ,
201917 bajtówKod:
Wyjaśnienie:
Wykorzystuje kodowanie CP-1252 . Wypróbuj online! .
źródło
MATL,
3230292827262524 bajtów1 bajt zapisany dzięki @Luis
Wypróbuj online!
Zmodyfikowana wersja dla wszystkich przypadków testowych
Wyjaśnienie
źródło
V
zezwala na specyfikację formatu. Możesz zapisać 1 bajt, używającZ"
zamiastO
: zobacz ten link (mam problem z formatem w komentarzu)D
której domyślnie korzysta ta liczba między pojedynczymi odstępami.Właściwie 43 bajty
Wypróbuj online!
Ten program wypisuje pojedynczy znak nowej linii po wyjściu.
Wyjaśnienie:
źródło
Mathematica, 67 bajtów
Przykład:
źródło
CJam, 25 bajtów
Wypróbuj online!
Wyjaśnienie
Wykorzystuje to dość zgrabną sztuczkę do wygenerowania układu trójkąta.
źródło
JavaScript (ES6) 147 bajtów
źródło
Julia,
6059 bajtówNa podstawie odpowiedzi @ Sp3000 . Funkcja
\
przyjmuje tablicę jako dane wejściowe i zwraca ciąg znaków.Wypróbuj online!
źródło
Pyke, 21 bajtów
Wypróbuj tutaj!
Chciałbym myśleć, że ta metoda jest nieco inna.
źródło
Perl 6 ,
65 63 6261 bajtówWyjaśnienie:
Przykład:
źródło
TSQL,
198194191 bajtówUżywając GOTO zamiast jednego z WHILE, mogłem zagrać w golfa 3 postaci
Grał w golfa
Wypróbuj online (używając starego skryptu z 2 * WHILE)
źródło
Java 7,
230215213 bajtówSkończyło się to trochę dłużej, niż myślałem ... Może to może być trochę bardziej golfa, ponieważ myślę, że trochę pomieszałem, myślę ...
Niektóre bajty zapisane dzięki @GiacomoGarabello .
Kod niepoznany i testowy:
Wypróbuj tutaj.
Wydajność:
źródło
void p(String s){System.out.print(s);}
i zastąp standardowy wydruk. Doprintln
użytkup("\n")
. Przesuńint i
i wint j
pobliżuint c=0;
(int c=0,i,j;
) i przesuńprint(a[i]+" ")
wnętrzefor
warunku, abyś mógł usunąć wsporniki w sumie -11<T>void p(T s){System.out.print(s);}
zamiastvoid p(String s){System.out.print(s);}
.C # 6,
125 + 31125 + 18 = 143 bajtów+18 jest dla
using System.Linq;
Dzięki @TheLethalCoder za zapisanie 13 bajtów, poprzez wskazanie niepotrzebnej instrukcji using
źródło
JavaScript (ES6), 77 bajtów
źródło
C, 138 bajtów
Grał w golfa
Nie golfił
źródło
C #, 167 bajtów
Jestem naprawdę dumny z tego rozwiązania, wyrażenia lambda są tak zabawne, jak tylko się zorientujesz
tutaj niepolecany do dalszych ulepszeń:
wypróbuj to tutaj
źródło
List<int> a
->int[] a
,int x=a.Count
->int x=a.Length
,.ToList()
->ToArray()
Haskell, 139 bajtów
Pobiera dane wejściowe jako argument, wysyła dane do STDOUT.
Wersja bez golfa:
źródło
Python 3, 97 bajtów
Drukuje pojedynczy znak nowej linii.
Jak to działa
Wypróbuj na Ideone
źródło
J, 44 bajty
Na podstawie tego rozwiązania .
źródło
JavaScript (przy użyciu zewnętrznej biblioteki) (198 bajtów)
Link do lib: https://github.com/mvegh1/Enumerable/
Wyjaśnienie kodu: Korzystanie z biblioteki było łatwe! Nie wygrywa w bajtach, ale kod nie jest zbyt szczegółowy i łatwy do odczytania. Tak więc, wejście „n” jest tablicą liczb całkowitych. Załaduj go do biblioteki, zapisany w zmiennej „a”. „B” to ciąg zwracany, przechowuj połączony ciąg z „” jako separator w b. C to bieżąca iteracja, użyj tego, aby określić liczbę spacji do wstawienia. UWAGA: Wydaje się, że działa to dobrze tylko wtedy, gdy dane wejściowe pochodzą z 0-9. zestawy obecnego wyliczalnego „a”, tzn. jeśli mamy [1,2,3,4,5,6], otrzymujemy [1,2], [2,3], [3,4], ... [ 6] ... następnie odfiltruj to, abyśmy mieli tylko partie wielkości 2. Następnie mapujemy to na zbiór sum partii% 10. Jeśli a jest puste, to skończymy, w przeciwnym razie dodamy nową linię do naszego zwrotu. Wreszcie wróć ...
Zdjęcie pojawi się za kilka minut.
źródło