Wyzwanie polega na sformatowaniu listy słów w wielu wierszach, które nie są dłuższe niż podana liczba znaków, tak aby każda linia zawierała jak najwięcej słów i żadne słowa nie były niepotrzebnie odcinane.
Wejście
Dane wejściowe będzie oddzieloną spacjami listą słów, a następnie liczbą co najmniej 4.
Wynik
Wynikiem powinny być słowa wejściowe pogrupowane w wiersze, aby żaden wiersz nie zawierał więcej znaków niż numer wejściowy. Słowa powinny być wypisywane w kolejności, w jakiej zostały wprowadzone. Słowa powinny być oddzielone przecinkiem, a następnie spacją, z wyjątkiem końca każdego wiersza, w którym spacja nie jest potrzebna. Jeśli słowo jest zbyt długie, aby zmieściło się w linii, należy je jak najmniej uciąć, przestrzegając pozostałych zasad, a na końcu dodać „…”.
Przypadki testowe
Input:
foo bar baz qux 12
Output:
foo, bar,
baz, qux
Input:
foo bar baz qux 5
Output:
foo,
bar,
baz,
qux
Input:
strength dexterity constitution intelligence wisdom charisma 10
Output:
strength,
dexterity,
consti...,
intell...,
wisdom,
charisma
Input:
quas wex exort 4
Output:
...,
wex,
e...
Odpowiedzi:
Nieczytelny , 2559 bajtów
To wyzwanie jest niesamowicie odpowiednie dla Nieczytelnych.
Pierwsza wersja tego pliku miała 3379 bajtów, aby dać wyobrażenie o tym, jak bardzo grałem w golfa.
Program akceptuje dane wejściowe dokładnie tak, jak opisano w wyzwaniu: rozdzielona spacjami lista słów (która może również zawierać cyfry i znaki interpunkcyjne), po której następuje spacja i liczba całkowita o wartości co najmniej 4 (niższe liczby generują nieskończone pętle) .
Wyjaśnienie
Przeprowadzę cię przez proces przetwarzania danych wejściowych przez program
thyme horseradish peppermint 10
. Oczekiwany wynik tothyme,\nhorser...,\npeppermint
.Najpierw zaczynamy od komórki nr 7 i odczytujemy całe dane wejściowe, ale odejmujemy 32 od każdego znaku, aby spacje stały się zerami.
Z oczywistych powodów pozostawia to działający wskaźnik (o nazwie tutaj o p , przechowywany w komórce nr 0) na końcu. Używamy pętli while, aby znaleźć ostatnią przerwę, która jest początkiem liczby określającej szerokość wyniku (komórka nr 36 w tym przykładzie).
Chcemy teraz dekodować liczbę (tzn. Konwertować z dziesiętnego). Wynik końcowy będzie zarówno komórek T i r . Polegamy na tym, że zaczynają od zera.
Dla każdej cyfry w liczbie wykonaj następujące czynności:
'0'
które'9'
mają kody ASCII 48–57, więc po wcześniejszym odjęciu 32 mają one 16–25, więc faktycznie dodajemy 15–24 do t , co anuluje się z -15 ustawiliśmy to na wcześniej. Ważne jest również, aby to zerowało komórki, które zawierały znaki cyfrowe, aby późniejszy kod mógł rozpoznać koniec listy słów.Na koniec używamy innej prostej pętli while (zmniejszającej t jako licznik) do konwersji obliczonej właśnie liczby na unarną. Przechowujemy ciąg 1s idących w lewo od komórki nr 0. Opiera się to na tym, że komórka nr 1, nasz działający wskaźnik dla tego ( q ), zaczyna się od 0. Dostajemy jeden mniej 1s, ponieważ podczas gdy pętle w Nieczytelnym są takie:
Po tym nie potrzebujemy już wartości wr , więc ponownie wykorzystujemy tę komórkę do czegoś innego. Resetujemy wskaźniki p i q i inicjalizujemy niektóre komórki za pomocą kodów ASCII znaków, których potrzebujemy później. Oznaczyłem również c i s, których użyjemy później i będziemy polegać na tym, że s zaczyna się od zera:
Hej, poczekaj chwilę. Dlaczego komórka nr 0 ma kolor czerwony? Cóż, ma to na celu podstępną sztuczkę. Pamiętasz, jak wyprodukowaliśmy jeden 1 za mało? Sztuka polega na tym, że używamy komórki nr 0 jako „rozszerzenia”, aby to poprawić. Działa to, ponieważ wiemy, że p nigdy nie będzie wynosić 0. W ten sposób czerwony blok ma teraz szerokość 10 komórek, dokładnie taką liczbę, jakiej chcemy. Zapisuje również 9 znaków, aby móc zainicjować q do 1 zamiast 0.
Teraz wchodzimy do pętli while, która przechodzi przez słowa i wypisuje je wszystkie.
Krok 1: Sprawdź, czy następne słowo będzie pasować do bieżącego wiersza. Robimy to po prostu przesuwając p w prawo i q w lewo za pomocą pętli while, aż p osiągnie następną przerwę:
Teraz, gdy p znajduje się po prawej stronie słowa, możemy sprawdzić, czy jest to ostatnie słowo na liście, sprawdzając, czy * (p + 1) wynosi zero. Przechowujemy również tę wartość (która w naszym przykładzie wynosi 72, ponieważ jest to „h” z „chrzanu” minus 32) c, ponieważ będziemy jej później potrzebować. W tym przypadku nie jest to zero, więc będziemy musieli wprowadzić przecinek wraz ze słowem, więc słowo jest dłuższe o jeden znak. Weź to pod uwagę, zmniejszając q jeszcze raz. Na koniec użyj innej pętli while, aby przenieść p z powrotem na początek słowa.
Wiemy teraz, że słowo zmieści się w bieżącym wierszu, ponieważ q wskazuje na niezerową wartość, więc wszystko, co musimy zrobić, to:
Dotychczasowe wyniki:
thyme,
Następnie rozpoczyna się kolejna iteracja dużej pętli. Tak jak poprzednio, sprawdzamy, czy następne słowo pasuje do reszty wiersza, zmniejszając q, gdy przechodzimy przez słowo od lewej do prawej. Zauważ, że q nadal wynosi -5 od poprzedniej iteracji, śledząc, ile znaków już wydrukowaliśmy w bieżącym wierszu. Po zliczeniu znaków w „chrzanie”, plus jeden dla przecinka, plus jeden, ponieważ s jest niezerowy, co oznacza, że musimy również wypisać spację, q będzie miało przekroczenie końca bloku 1s:
Teraz q wskazuje na zerową komórkę, co oznacza, że „chrzan” nie będzie pasował do bieżącej linii. To, co teraz robimy, zależy od tego, czy s jest niezerowe. W naszym przypadku tak jest, co oznacza, że musimy przejść do następnej linii. Wszystko, co musimy zrobić, to:
Dotychczasowe wyniki:
thyme,\n
W następnej iteracji p znajduje się w tym samym miejscu co poprzednio, więc ponownie przyjrzymy się temu samemu słowu. Tak jak poprzednio, liczymy znaki w „chrzanie”, ustawiamy ponownie c na 80, gdy zauważymy, że po nim jest inne słowo, zmniejszamy q przecinkiem i przewijamy p z powrotem do początku słowa:
Podobnie jak w poprzedniej iteracji, okazuje się, że „chrzan” nadal nie pasuje, ponieważ q kończy się na komórce, która ma zero. Jednak ten czas s wynosi zero, co oznacza, że robimy coś innego niż ostatnim razem. Musimy wypisać część słowa, trzy kropki i przecinek. Nasza szerokość wynosi 10, więc musimy wypisać 6 znaków tego słowa. Zobaczmy, gdzie skończymy, jeśli:
Taśma wygląda teraz tak:
Zaznaczyłem tutaj rozpiętość 6 komórek. Jak widać, musimy wypisywać znaki, dopóki q = -1. Jest to bardzo efektywne pod względem kodu sprawdzanie (w zasadzie
while ((++q)+1) { ... }
). Więc:print(print(print('.')))
). Bierzemy wartość ASCII z komórki nr 5 i dodajemy 2 do niej, aby uzyskać kod ASCII kropki.Po tym wszystkim wypisujemy również nową linię (używając komórki nr 3) i ustawiamy q z powrotem na 1. Możemy również ustawić s na 0, nawet jeśli jest to już 0, co czyni to to samo, co poprzednio, kiedy zawijaliśmy do następny wiersz (gdy s było niezerowe), więc aby uniknąć powtórzenia kodu, robimy to po warunku, który sprawdza s .
Dotychczasowe wyniki:
thyme,\nhorser...,\n
Pozostała tylko jedna iteracja. Tym razem po policzeniu liter słowa otrzymujemy:
Tym razem po p nie ma nic , więc ustawiamy c na 0, aby wskazać „brak przecinka”, a zatem nie zmniejszamy q ponownie. Ponieważ q wskazuje teraz na niezerową komórkę, wiemy, że słowo będzie pasować, więc wykonywany jest ten sam kod, co w pierwszej iteracji, z tym wyjątkiem, że tym razem c wynosi zero, więc po prostu nie wydrukuje przecinka.
Wynik:
thyme,\nhorser...,\npeppermint
W tym przewodniku nie uwzględniłem przypadku, w którym kod wydrukowałby spację, ale myślę, że teraz powinno być dość jasne. Jeśli kod stwierdzi, że słowo pasuje ( * q ≠ 0), a s jest niezerowe, po prostu wyświetli spację przed słowem.
źródło
JavaScript (ES6), 171
Jako anonimowa funkcja zwracająca dane wyjściowe jako tablicę
(ponieważ jest to ogólnie dozwolone, chyba że wyraźnie zabronione: meta meta )
źródło
Python 2, 206 bajtów
źródło