Wprowadzenie i zaliczenie
Dzisiaj bez wymyślnego preludium: Proszę wdrożyć takewhile
.
Odmianą tego (na nietrywialnej strukturze danych) było zadanie na moim uniwersyteckim kursie programowania funkcjonalnego. To zadanie jest teraz zamknięte i zostało omówione na zajęciach i mam pozwolenie mojego profesora na opublikowanie go tutaj (wyraźnie spytałem).
Specyfikacja
Wkład
Dane wejściowe będą listą (lub odpowiednikiem twojego języka) dodatnich liczb całkowitych.
Wydajność
Wynikiem powinna być lista (lub odpowiednik twojego języka) dodatnich liczb całkowitych.
Co robić?
Twoim zadaniem jest wdrożenie takewhile
(dozwolone są wbudowane języki) z predykatem, że rozważana liczba jest parzysta (aby skupić się na czasie).
I tak iterujesz listę od początku do końca i dopóki warunek (jest parzysty) pozostaje, kopiujesz na listę wyników i jak tylko trafisz element, który nie spełnia warunku, przerywasz operację i wyjście (przykład krok po kroku znajduje się poniżej). Ta funkcja wyższego rzędu jest również nazywana takeWhile ( takewhile
).
Potencjalne narożne skrzynki
Kolejność listy wyników w porównaniu do listy danych wejściowych nie może zostać zmieniona, np. [14,42,2]
Może się nie zmienić [42,14]
.
Pusta lista jest prawidłowym wejściem i wyjściem.
Kto wygrywa?
To jest golf golfowy, więc wygrywa najkrótsza odpowiedź w bajtach!
Oczywiście obowiązują standardowe zasady.
Wektory testowe
[14, 42, 2324, 97090, 4080622, 171480372] -> [14, 42, 2324, 97090, 4080622, 171480372]
[42, 14, 42, 2324] -> [42, 14, 42, 2324]
[7,14,42] -> []
[] -> []
[171480372, 13, 14, 42] -> [171480372]
[42, 14, 42, 43, 41, 4080622, 171480372] -> [42, 14, 42]
Przykład krok po kroku
Example Input: [42, 14, 42, 43, 41, 4080622, 171480372]
Consider first element: 42
42 is even (21*2)
Put 42 into output list, output list is now [42]
Consider second element: 14
14 is even (7*2)
Put 14 into output list, output list is now [42,14]
Consider third element: 42
42 is even (21*2)
Put 42 into output list, output list is now [42,14,42]
Consider fourth element: 43
43 is not even (2*21+1)
Drop 43 and return the current output list
return [42,14,42]
Odpowiedzi:
Mathematica, 18 bajtów
Kolejny wspaniały wbudowany, który jest pokonany 3 razy przez języki gry w golfa bez wbudowanego ...
źródło
Haskell, 13 bajtów
span
dzieli listę wejściową na parę list tuż przed pierwszym elementem, w którym predykat (->even
) ma wartość false.fst
bierze pierwszy element z pary.Alternatywna wersja, 13 bajtów:
break
jest przeciwieństwemspan
, tzn. dzieli listę na pierwszy element, w którym predykat jest prawdziwy.Oczywiście, że też
ale to 14 bajtów.
źródło
MATL , 6 bajtów
Wypróbuj online!
Wyjaśnienie
źródło
to~Y<)
również działa, ale ten bardziej mi się podoba :-)Sześciokąt , 19
Czytelny:
Wypróbuj online!
Prawdopodobnie można go zagrać w bajt lub dwa bajty, ale może to wymagać naprawdę pomysłowego układu, który można łatwiej znaleźć za pomocą brutalnej siły (nawet jeśli znalezienie go może potrwać dość długo).
Wyjaśnienie na wysokim poziomie
Program przeważnie stosuje ten pseudokod:
Które nadużywają sposobu, w jaki Hexagony próbuje odczytać liczbę, gdy STDIN jest pusty (zwraca zero). Ogromne podziękowania dla Martina za pomoc w opracowaniu tego podejścia.
Pełne wyjaśnienie
Nadal nie majstrowałem przy Mono, żeby zdobyć Timwi fantastyczne ezoteryczne IDE , więc zaufałem Martinowi, aby dostarczył mi kilka pomocnych ładnych zdjęć!
Najpierw mały podkład na podstawowy przepływ kontrolny w Hexagony. Pierwszy wskaźnik instrukcji (IP), który jest jedynym używanym w tym programie, zaczyna się w lewym górnym rogu heksagonalnego kodu źródłowego i zaczyna przesuwać się w prawo. Ilekroć IP opuszcza krawędź sześciokąta, porusza się
side_length - 1
rzędy w kierunku środka sześciokąta. Ponieważ ten program używa sześciokąta o długości boku trzy, adres IP zawsze będzie się przesuwał o dwa rzędy, kiedy to nastąpi. Jedynym wyjątkiem jest sytuacja, gdy odsuwa się od środkowego rzędu, gdzie warunkowo przesuwa się w kierunku góry lub dołu sześciokąta, w zależności od wartości aktualnej krawędzi pamięci.Teraz trochę o warunkach. Jedynymi warunkami w Hexagony dla przepływu kontrolnego są
>
:<
a środkowa krawędź sześciokąta. Wszystkie one działają zgodnie ze stałą zasadą: jeśli wartość na bieżącym zboczu pamięci wynosi zero lub ujemny przepływ sterowania przesuwa się w lewo, a jeśli jest dodatni, sterowanie płynie w prawo. Większe niż i mniejsze niż nawiasy przekierowują IP pod kątem sześćdziesięciu stopni, podczas gdy krawędź sześciokąta określa, do którego rzędu skacze IP.Heksagonia ma również specjalny model pamięci, w którym wszystkie dane są przechowywane na krawędziach nieskończonej sześciokątnej siatki. Ten program używa tylko trzech krawędzi: jednej do przechowywania dwóch, jednej dla aktualnie odczytywanego numeru i jednej dla liczby dwóch modułów. Wygląda mniej więcej tak:
Nie zamierzam dokładnie wyjaśniać, gdzie jesteśmy w pamięci w każdym punkcie podczas wyjaśniania programu, więc wróć tutaj, jeśli się zdezorientujesz, gdzie jesteśmy w pamięci.
Po tym wszystkim, prawdziwe wyjaśnienie może się rozpocząć. Najpierw wypełniamy krawędź „2” pamięcią 2, a następnie wykonujemy brak operacji i przesuwamy wskaźnik pamięci w prawo (
2.}
).Następnie rozpoczynamy główną pętlę programu. Czytamy pierwszy numer ze STDIN, a następnie trafiamy na warunkowy (
?<
). Jeśli w STDIN nie ma żadnych liczb, to odczytuje zero w bieżącym zboczu pamięci, więc skręcamy w lewo na@
, co kończy program. W przeciwnym razie odbijamy się od lustra, przesuwamy wskaźnik pamięci do tyłu i w lewo, owijamy sześciokąt, aby obliczyć pozostałą część dzielenia danych wejściowych przez 2, a następnie uderzamy w inną funkcję warunkową (/"%>
).Jeśli reszta to jeden (tzn. Liczba była nieparzysta), skręcamy w prawo, podążając niebieską ścieżką powyżej, zaczynając od ponownego wykonania operacji no-op, a następnie zawijamy się do dolnej części sześciokąta, mnożymy bieżącą krawędź przez 10, a następnie dodajemy ósemka, odbij się od kilku luster, wykonaj to samo mnożenie i dodawanie jeszcze raz, otrzymując 188 na bieżącej krawędzi, owijając się z powrotem na górę sześciokąta, ponownie wykonując brak operacji i na końcu kończąc program (
.8/\8.@
). Ten zawiły wynik był szczęśliwym wypadkiem, pierwotnie napisałem dużo prostszą logikę, ale zauważyłem, że mogę go usunąć na korzyść braku operacji, który, jak myślałem, był bardziej w duchu Sześciokąta.Jeśli reszta to zero, skręcamy w lewo, podążając czerwoną ścieżką powyżej. Powoduje to przesunięcie wskaźnika pamięci w lewo, a następnie wydrukowanie tam wartości (wartości wejściowej) jako liczby. Zwierciadło, które napotykamy, działa jako brak działania ze względu na kierunek, w którym się poruszamy ( ). Ponieważ wartość 77 jest dodatnia, poruszamy się w kierunku dolnej części sześciokąta iz powodu trampoliny pomiń pierwszą instrukcję ( ). Następnie mnożymy bieżącą krawędź pamięci przez 10 i dodajemy 8, otrzymując 778. Następnie wyprowadzamy tę wartość mod 256 (10) jako znak ASCII, który okazuje się być nowym znakiem. Na koniec wychodzimy z sześciokąta i wracamy do pierwszej, która zastępuje 778 następną wartością wejściową.
{/!
). Następnie uderzamy o krawędź sześciokąta, który działa warunkowo z tylko jednym wynikiem, ponieważ wcześniej wprowadzona wartość została już przetestowana pod kątem dodatniej, więc zawsze poruszamy się w prawo (jeśli wyobrażasz sobie, że patrzysz w kierunku IP) . Następnie mnożymy dane wejściowe przez 10 i dodajemy dwa, tylko w celu zmiany kierunku, zawinięcia i zastąpienia nowej wartości wartością ascii wielkiej litery M, 77. Następnie uderzamy w lustra i wychodzimy poza krawędź środka sześciokąt z trampoliną (2<M\>$
!
?
źródło
Pyth,
1397 bajtówKredyty dla @FryAmTheEggman za 2 (dość trudne) bajty!
Wyjaśnienie:
Sprawdź to tutaj .
źródło
G
wprowadzone dwa symbole, jeden dla warunkus%R2G
i jeden jako argument funkcjiP
.Galaretka , 5 bajtów
Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .
Jak to działa
źródło
Python 2,
4342 bajtyFunkcja modyfikuje argument na swoim miejscu .
Dzięki @xnor za grę w bajt w naprawdę sprytny sposób!
Przetestuj na Ideone .
źródło
"1'"in`map(bin,x)`
w Pythonie 2.ed, 13
Ponieważ prawdziwi programiści używają Standardowego edytora tekstu .
Pobiera dane wejściowe jako jedną liczbę całkowitą w każdym wierszu; wyjścia w tym samym formacie.
To po prostu znajduje pierwszą nieparzystą liczbę (liczbę kończącą się nieparzystą cyfrą) i usuwa z tego wiersza do końca pliku.
źródło
Clojure, 21 bajtów
Clojure w końcu prawie konkuruje! (dzięki temu, że zadanie jest wbudowane) Zobacz online https://ideone.com/BEKmez
źródło
Python,
4544 bajtówPrzetestuj na Ideone .
źródło
R, 25 bajtów
Lub równoważnie
źródło
05AB1E,
87 bajtówWyjaśnienie
Wypróbuj online
Poprzednie 8 bajtowe rozwiązanie
Wyjaśnienie
Wypróbuj online
źródło
Brainf ***, 263 bajty
Wziąłem stąd mały fragment
Dałbym wyjaśnienie, ale nawet nie mam pojęcia, jak to działa.
Oczekuje wprowadzania jako liczby oddzielone spacjami (np.
2 432 1
)źródło
+
i>
używać logiki?>
ale teraz nie rozumiem ich wystarczająco dobrzePyth, 7 bajtów
Wypróbuj tutaj!
To, co próbowałem zrobić w Pyke, ale indeks jest zepsuty w tym bankomacie
źródło
Rakieta, 22 bajty
λ
Znak jest liczony jako 2 bajty.Nie widziałem Rakieta używanego wcześniej w żadnej z odpowiedzi na pytania dotyczące gry w golfa, więc musiałem to zrobić przynajmniej raz!
źródło
Labirynt , 14 bajtów
Dane wejściowe i wyjściowe są listami oddzielonymi od linii (chociaż w zasadzie dane wejściowe mogą wykorzystywać dowolny separator inny niż cyfrowy).
Wypróbuj online!
Jest to prawdopodobnie najbardziej kompaktowy program Labiryntu, jaki kiedykolwiek napisałem.
Co ciekawe,
takewhile(odd)
jest o wiele prostsze:Wyjaśnienie
Zwykły podkład do labiryntu:
?
w tym przypadku), przesuwając się na wschód.Główny przepływ przez program jest pojedynczą pętlą wokół obwodu:
Tak się składa, że wiemy, że górna część stosu ma zero
!
i"
dlatego gwarantuje się, że IP nie skręci w kierunku centrum.`
a%
z drugiej strony są używane jako warunki warunkowe, w których adres IP może przesuwać się w kierunku centrum, co@
kończy program lub może przesuwać się po obwodzie.Spójrzmy na kod w pętli:
A potem pętla zaczyna się od nowa.
Rodzi to pytanie, dlaczego
takewhile(odd)
jest o wiele prostsze. Są dwa powody:0
(który jest parzysty), nie potrzebujemy osobnego sprawdzania EOF. W każdym razie lista zostanie skrócona.N % 2
jest0
(w przeciwieństwie do1
), co oznacza, że zamiast przepływu kontroli warunkowej możemy po prostu podzielić drugą kopięN
przezN % 2
: jeśli dane wejściowe są nieparzyste, to po prostu wychodzi,N
a nawet pozbyliśmy sięN % 2
(więc nie potrzeba;
), ale jeśli wejście jest parzyste, to po prostu kończy program z (cichym) błędem dzielenia przez zero.Dlatego drugi kod jest prostą pętlą, która w ogóle nie pozwala na rozgałęzienia.
źródło
Brachylog ,
1916 bajtówWyjaśnienie
Dzisiaj nauczyłem się zgrabnej sztuczki (która została użyta w odpowiedzi na 19 bajtów):
~b.hH
jest krótsza niż:[H]rc.
dodanie elementu na początku listy. Pierwszy oznacza „Wyjście to wynik z dodatkową pozycją na początku, a pierwszym elementem Wyjście jestH
” , podczas gdy drugi jest wprost „Wyjście to konkatenacja[[H], Result]
”.źródło
J, 10 bajtów
Wyjaśnienie
źródło
1{.2&|<;._2]
jest interesujące (choć dłuższe)$
zamiast{.
Python, 41 bajtów
Obcina
l
do indeksu pierwszego wystąpienia liczby nieparzystej. Indeks można znaleźć, szukając1
w wartości modulo2
. Aby uniknąć znalezienia nieparzystej liczby,1
na końcu znajduje się a.źródło
C #, 50 bajtów
źródło
a=>a.TakeWhile(x=>x%2<1);
CJam , 11 bajtów
Dzięki @Dennis za dwie poprawki i jeden bajt off!
Jest to blok kodu (równoważny funkcji; domyślnie dozwolony), który oczekuje tablicy wejściowej na stosie i pozostawia tablicę wyjściową na stosie.
Wypróbuj online!
Wyjaśnienie
źródło
Siatkówka , 17 bajtów
Końcowe podawanie linii jest znaczące. Dane wejściowe i wyjściowe są listami rozdzielonymi spacjami.
Wypróbuj online!
Jest to proste podstawienie wyrażenia regularnego, dopasowuje pierwszą liczbę nieparzystą (tj. Liczbę kończącą się cyfrą nieparzystą) i, jeśli to możliwe, poprzedzającą ją spację, a także wszystko po niej i zastępuje ją pustym ciągiem, tzn. Wszystkimi elementami stamtąd i później są usuwane z wejścia.
Jak wskazuje Leaky Nun, biorąc listę w formie binarnej, możemy zapisać 6 bajtów, ale wydaje się to nieco podstępne, więc prawdopodobnie nadal liczę wersję dziesiętną:
źródło
JavaScript (Firefox 30-57), 30 bajtów
źródło
V , 13 bajtów
Wypróbuj online!
Wyjaśnienie:
Dogodnie ten sam kod działa jednocześnie w celu weryfikacji wszystkich przypadków testowych.
źródło
Dyalog APL , 11 bajtów
2|
podział pozostały z dzielenia za pomocą 2~
negować∧\
AND-scan (wyłącza się od pierwszego 0)/⍨
wybierz gdzieźródło
Rubin, 25 bajtów
Myślę, że przegrywam ...
źródło
->a{a.take_while &:even?}
czy przynajmniej->a{a.take_while(&:even?)}
?Pyke, 8 bajtów
Naprawiono interpreter, użyj innych linków
Używa metody Dennisa, z wyjątkiem tego, że moja funkcja split_at obejmuje zmianę - prawdopodobnie błąd
Lub z poprawką, 7 bajtów
Wypróbuj tutaj!
Lub po 2. poprawce błędu, 6 bajtów
Wypróbuj tutaj!
Wyjaśnienie:
źródło
GolfScript, 11 bajtów
Jest to pełny program GolfScript, który odczytuje dosłownie literę tablicy GolfScript (np.
[28 14 7 0]
) I drukuje tę samą tablicę z pierwszym nieparzystym elementem i wszystkim, co zostanie usunięte:Wypróbuj online. (Również: Wersja rozszerzona z wiązką testową. )
Wersja bez golfa z komentarzami:
To rozwiązanie jest oparte na języku GolfScript
{ },
operatorze filtru , który uruchamia zawartość bloku kodu na każdym elemencie tablicy i wybiera elementy tablicy, dla których kod w bloku zwraca wartość true (tj. Niezerową) dla szczyt stosu.Na przykład
{1&},
wybrałby wszystkie liczby nieparzyste w tablicy i{~1&},
wybrałby wszystkie liczby parzyste. Wyzwaniem jest więc stworzenie filtra, który wybiera liczby parzyste, aż znajdzie pierwszy nieparzysty , a następnie nie wybierze żadnych liczb.Rozwiązaniem, które zastosowałem, jest zastąpienie stałej maski bitowej
1
(używanej do wyodrębnienia najniższego bitu każdej liczby wejściowej) zmienną na stosie, która przechowuje wynik (0 lub 1) poprzedniej iteracji pętli filtra (i jest inicjowany 1 przed pętlą). Zatem, gdy tylko filtr zwróci 0 raz, maska bitowa również zostaje ustawiona na 0, co zapobiega ponownemu zwróceniu przez filtr 1.źródło
Dalej, 114 bajtów
Forth tak naprawdę nie ma list. Parametry należy wcisnąć na stos w odwrotnej kolejności, jak to jest typowo w Forth. Wynik pozostanie na stosie w tej samej kolejności. Z jakiegoś powodu to nie działa na Ideone, ale działa na repl. Nowa linia jest wymagana do usunięcia niejasności?
Wypróbuj online
Niegolfowany, z komentarzami:
Ten program (moja poprzednia próba) drukuje wyniki, aż osiągnie nieparzystą liczbę. Wszystkie pozostałe (nie zabrane) pozostaną na stosie.
Nie powiedzie się, jeśli tylko liczby całkowite
źródło
Befunge, 35 bajtów
Ten kod obsługuje liczby od 0 do 65535
Format wejściowy:
Oto wersja, która wyświetla wartości na końcu procesu:
Możesz przetestować kod tutaj , ale będziesz musiał dodać linię końcową ze spacjami końcowymi, ponieważ ta interpretacja określa:
Nie wiem, czy jest to dopuszczalne, ponieważ nie policzyłem tego końcowego w liczbie bajtów
nb: wygląda na to, że ponieważ przechowuję liczbę w kodzie, interpreter nie pozwoli, aby ten program uruchomił się dwukrotnie we właściwym droga. Będziesz musiał go ponownie załadować.
Jak to działa: Tłumacz postępuje zgodnie ze strzałkami i pomija instrukcje podczas przekraczania „#”
Szare kropki są testowane, a czerwona linia usuwa niepotrzebne zmienne ze stosu
Korzystając z powyższego interpretera, zapisane wartości są wyświetlane w kodzie przy użyciu ich reprezentacji (nie znam formatu). Tak, Befunge jest dość refleksyjnym językiem
źródło