var QUESTION_ID=82938,OVERRIDE_USER=48934;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+(?:\.\d+)?)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
Odpowiedzi:
Domino , 122 000 bajtów lub 72 płytki
Liczba bajtów to rozmiar zapisanego pliku, który wynosi
0.122 MB
.Inspiracją było domino . Przetestowałem to wszystko do symetrii (i nie tylko!) Za pomocą gry Steam w wirtualnej rzeczywistości o nazwie Tabletop Simulator .
Detale
True
lub1False
lub0100%
Bramy
644343151132171376761615TL; DR
Czekałem / chciałem wyzwanie przyjazne domino, a kiedy to zobaczyłem, nie mogłem tego przegapić. Jedyny problem polegał na tym, że najwyraźniej nikt nie ma już domino! W końcu poddałem się i kupiłem Double Twelve . Ten zestaw ma 91 kafelków, co podsunęło mi pomysł posiadania „wywołania funkcji” / uruchomienia domina zamiast zwykłej (długiej) metody „opóźnienia czasowego”. Kredyt za obrót o 90 stopni należy do kanału dominoesdouble07 .
Po zbudowaniu ich z fizycznymi domino, na meta orzeczono, że prawidłowe rozwiązania powinny być cyfrowe. Więc odtworzyłem te bramy w Tabletop Simulator . Niestety, TS i rzeczywistość nie zgadzają się co do fizyki domina. Wymagało to dodania 11 domino, ale zapisałem również 8. Ogólnie rzecz biorąc, wirtualne domino są około x150 bardziej efektywne pod względem budowy i testowania ( Ctrl+ Z).
Aktualizacja
xor xnor nand
xnor
ixor
xor
ixnor
). Blokowanie na Tabletop wymaga tylko 1 domina zamiast 2.źródło
Sześciokąt , 89 bajtów
Dziękujemy FryAmTheEggman za niezbędną inspirację dla rozwiązania XOR.
Wszystkie programy używają wartości
0
false i1
true.Wypróbuj online! To nie jest zestaw testowy, musisz sam skopiować w różnych programach i danych wejściowych.
Powyższe rozwiązanie mieści się w granicach 2 bajtów optymalności (chyba, że rozluźnimy interpretację prawdy / fałszu, jak sądzę). Pozwoliłem, by wyszukiwanie siłowe trwało prawie dwa dni we wszystkich programach, które pasują do długości 2, tj. Do 7 bajtów (nie do końca wszystkie programy - poczyniłem kilka założeń na temat tego, czego potrzebuje każdy prawidłowy program, a czego nie prawidłowy program może mieć). Wyszukiwanie znalazło rozwiązania dla 15 z 16 możliwych bramek - i często o wiele więcej niż tylko jednej. Możesz znaleźć listę wszystkich alternatywnych rozwiązań w tym pastebinie, gdzie pogrupowałem je według równoważnych zachowań. Te, które pokazuję powyżej, wybrałem, ponieważ są albo najprostszym, albo najciekawszym rozwiązaniem, i dodam je jutro.
Jeśli chodzi o 16. bramę: XOR jest jedyną bramą, która najwyraźniej nie może być zaimplementowana w 7 bajtach. Wyszukiwanie przy użyciu brutalnej siły nad większymi programami jest niestety niemożliwe przy użyciu kodu, który mam obecnie. Więc XOR musiał być napisany ręcznie. Najkrótszy, jaki do tej pory znalazłem, to powyższy 10-bajtowy program, który jest oparty na nieudanej (ale bardzo bliskiej) próbie FryAmTheEggman. Możliwe, że istnieje rozwiązanie 8-bajtowe lub 9-bajtowe, ale poza tym wszystkie rozwiązania powinny być rzeczywiście optymalne.
Objaśnienia
Ostrzeżenie: ściana tekstu. Na wszelki wypadek, gdy ktoś jest zainteresowany tym, jak działają te wysoce skompresowane programy Hexagony, zamieściłem objaśnienia do każdego z nich poniżej. Próbowałem wybrać najprostsze rozwiązanie dla każdej bramki w przypadkach, gdy istnieje więcej niż jeden optymalny program, aby wyjaśnienia były dość krótkie. Jednak niektóre z nich wciąż psują umysł, więc pomyślałem, że zasługują na nieco więcej rozwinięcia.
0000
: FałszyweNie sądzę, że potrzebujemy diagramu dla tego:
Ponieważ cała siatka pamięci jest inicjowana na zera,
!
po prostu drukuje zero i@
kończy działanie programu.Jest to również jedyne rozwiązanie 2-bajtowe.
0001
: ITo w zasadzie powoduje zwarcie . Szary schemat poniżej pokazuje początek programu, w którym czytane jest pierwsze wejście,
?
a wskaźnik instrukcji (IP) otacza lewy róg, w którym|
odbija go lustro. Teraz narożnik działa jako warunek, na przykład istnieją dwie różne ścieżki wykonania w zależności od wartości pierwszego wejścia. Czerwony schemat pokazuje przepływ sterowania dla,A = 0
a zielony schemat dlaA = 1
:Jak widać, kiedy
A
jest0
, to po prostu go drukujemy i kończymy (pamiętaj, że.
nie ma żadnych operacji). Ale kiedyA
jest1
, adres IP ponownie przechodzi do pierwszego wiersza,B
zamiast tego odczytując i drukując.W sumie dla tej bramki istnieje szesnaście 5-bajtowych rozwiązań. Czternaście z nich jest zasadniczo takich samych, jak powyższe, albo używając
>
zamiast,|
albo zastępując.
komendą, która faktycznie nie działa, lub umieszczając?
na drugiej pozycji:A potem są dwa inne rozwiązania (które są sobie równoważne). Implementują one również tę samą logikę zwarć, ale ścieżki wykonania są nieco bardziej szalone (i pozostawione jako ćwiczenie dla czytelnika):
0010
: A, a nie BWprowadza to również formę zwarcia, ale ze względu na użycie
#
przepływu sterującego jest znacznie trudniejsze.#
jest warunkowym przełącznikiem IP. Sześciokąty faktycznie ma sześć adresów IP oznaczonych0
na5
, które zaczynają się w sześciu rogach siatki, wskazując wzdłuż ich krawędzi zgodnej z ruchem wskazówek zegara (a program zawsze zaczyna się od IP0
). Gdy#
napotkamy a, bieżąca wartość jest pobierana modulo6
, a przepływ sterowania jest kontynuowany z odpowiednim adresem IP. Nie jestem pewien, jaki przypływ szaleństwa zmusił mnie do dodania tej funkcji, ale na pewno pozwala ona na niektóre zaskakujące programy (takie jak ten).Rozróżnimy trzy przypadki. Gdy
A = 0
program jest dość prosty, ponieważ wartość jest zawsze0
, kiedy#
jest taka, że nie napotkał IP przełączanie odbywa się:#
nic nie robi,?
czytaA
(tzn. też nic nie robi),#
nadal nic nie robi,!
drukuje0
,)
inkrementuje to (jest to ważne, w przeciwnym razie IP nie przeskakuje do trzeciej linii),@
kończy działanie programu. Wystarczająco proste. Rozważmy teraz przypadek(A, B) = (1, 0)
:Czerwona ścieżka nadal odpowiada IP
0
, a ja dodałem zieloną ścieżkę dla IP1
. Widzimy, że po?
odczytachA
(1
tym razem)#
przełącza się na adres IP, który zaczyna się w prawym górnym rogu. Oznacza to, że?
można przeczytaćB
(0
). Teraz)
zwiększa to1
, aby#
w lewym górnym rogu nic nie robi i pozostajemy z IP1
. W!
drukuje1
i OD otacza lewy przekątnej.#
nadal nic nie robi i@
kończy działanie programu.Wreszcie, naprawdę dziwny przypadek, w którym oba dane wejściowe to
1
:Tym razem, drugie wejście jest również
1
i)
powiększa go2
. Oznacza to, że#
w lewym górnym rogu powoduje kolejną zmianę adresu IP na IP2
, oznaczoną kolorem niebieskim. Na tej ścieżce najpierw zwiększamy ją3
(choć nie ma to znaczenia), a następnie przechodzimy?
po raz trzeci. Ponieważ mamy teraz wciśnięty EOF (tzn. Dane wejściowe są wyczerpane),?
zwraca0
,!
drukuje to i@
kończy działanie programu.Warto zauważyć, że jest to jedyne 6-bajtowe rozwiązanie dla tej bramki.
0011
: AJest to na tyle proste, że nie potrzebujemy diagramu:
?
odczytujeA
,!
drukuje go,@
kończy.Jest to jedyne 3-bajtowe rozwiązanie dla tej bramki. (Zasadniczo byłoby to również możliwe
,;@
, ale wyszukiwanie nie obejmowało;
, ponieważ nie sądzę, że może kiedykolwiek zaoszczędzić bajty!
dla tego zadania).0100
: B, a nie ATen jest o wiele prostszy niż jego „brat”
0010
. Przepływ sterowania jest w rzeczywistości taki sam, jak widzieliśmy powyżej dla0001
(I). JeśliA = 0
, to IP przechodzi przez dolną linię, odczytującB
i drukując ją przed zakończeniem. JeśliA = 1
następnie IP ponownie przechodzi do pierwszego wiersza, również odczytujeB
, ale+
dodaje dwie nieużywane krawędzie pamięci, więc wszystko, co robi, to resetuje bieżącą wartość do0
, aby!
zawsze drukować0
.Istnieje całkiem sporo 6-bajtowych alternatyw (w sumie 42). Po pierwsze, istnieje mnóstwo rozwiązań równoważnych powyższym. Możemy ponownie swobodnie wybierać między
|
i>
, i+
możemy je zastąpić dowolnym innym poleceniem, które daje nam pustą przewagę:Ponadto możemy również użyć
]
zamiast?
.]
przenosi do następnego adresu IP (tzn. wybiera adres IP1
), dzięki czemu gałąź ta zamiast tego ponownie wykorzystuje?
w prawym górnym rogu. To daje kolejne 18 rozwiązań:I jest jeszcze sześć innych rozwiązań, które działają inaczej z różnym poziomem szaleństwa:
0101
: BWoohoo, kolejny prosty: czytaj
A
, czytajB
, drukujB
, zakończ. Istnieją jednak alternatywy dla tego. PonieważA
jest to tylko jeden znak, możemy go również odczytać za pomocą,
:Istnieje również opcja użycia pojedynczego
?
i dwukrotnego uruchomienia lustra:0110
: XorJak powiedziałem powyżej, była to jedyna brama, która nie zmieściłaby się w boku o długości 2, więc jest to odręczne rozwiązanie FryAmTheEggman i mnie, i istnieje duża szansa, że nie jest optymalna. Istnieją dwa przypadki do rozróżnienia. Jeśli
A = 0
przepływ kontrolny jest dość prosty (ponieważ w takim przypadku wystarczy wydrukowaćB
):Zaczynamy czerwoną ścieżką.
?
czytaA
,<
to gałąź, która odchyla zero w lewo. IP zawija się w dół, a następnie_
jest kolejnym lustrem, a kiedy IP uderza w narożnik, zawija się w lewym górnym rogu i kontynuuje na niebieskiej ścieżce.?
czytaB
,!
drukuje. Teraz(
to zmniejsza. Jest to ważne, ponieważ zapewnia, że wartość nie będzie dodatnia (ani jedna,0
ani-1
teraz). To powoduje, że IP zawija się w prawy róg, gdzie@
kończy program.Kiedy
A = 1
sprawy stają się trochę trudniejsze. W takim przypadku chcemy wydrukowaćnot B
, co samo w sobie nie jest zbyt trudne, ale ścieżka wykonania jest nieco trippy.Tym razem
<
odchyla adres IP w prawo, a następnie<
działa jak lustro. Tak więc IP przemierza tę samą ścieżkę w odwrotnej kolejności, czytając,B
gdy napotka?
ponownie. Adres IP zawija się w prawym rogu i kontynuuje zieloną ścieżkę. Również kolejne spotkania(~
, która jest „dekrementuj mnożenie przez -1”, który swapy0
i1
i oblicza zatemnot B
.\
jest tylko lustrem i!
drukuje pożądany rezultat. Następnie?
próbuje zwrócić inną liczbę, ale zwraca zero. Adres IP jest teraz kontynuowany w lewym dolnym rogu na niebieskiej ścieżce.(
zmniejsza,<
odzwierciedla,(
ponownie się zmniejsza, tak że bieżąca wartość jest ujemna, gdy IP uderza w narożnik. Porusza się po prawej dolnej przekątnej, a następnie w końcu uderza,@
aby zakończyć program.0111
: LubWięcej zwarć.
A = 0
Przypadek (czerwona ścieżka) jest nieco mylące tutaj. Adres IP jest odchylany w lewo, zawija się do lewego dolnego rogu, natychmiast jest odzwierciedlany przez<
i wraca?
do odczytuB
. Następnie zawija do rigt rogu, drukujeB
się!
i kończy.Obudowa
A = 1
(zielona ścieżka) jest nieco prostsza.<
Gałąź ugina IP rację, więc po prostu wydrukować!
, zawinąć z powrotem do góry po lewej, a kończą się@
.Jest tylko jedno 5-bajtowe rozwiązanie:
Działa zasadniczo tak samo, ale rzeczywiste ścieżki wykonania są zupełnie inne i używa rozgałęzienia zamiast rozgałęzienia
<
.1000
: NorTo może być mój ulubiony program znaleziony podczas tego wyszukiwania. Najfajniejsze jest to, że ta implementacja
nor
faktycznie działa dla maksymalnie 5 wejść. Będę musiał trochę zagłębić się w szczegóły modelu pamięci, aby to wyjaśnić. Tak więc, jako szybki odświeżacz, model pamięci Hexagony jest oddzielną heksagonalną siatką, w której każda krawędź zawiera wartość całkowitą (początkowo wszystkie zero). Istnieje wskaźnik pamięci (MP), który wskazuje krawędź i kierunek wzdłuż tej krawędzi (tak, że przed i za bieżącą krawędzią znajdują się dwie sąsiednie krawędzie, z wyraźnymi lewymi i prawymi sąsiadami). Oto schemat krawędzi, których będziemy używać, a MP zacznie się jak pokazano na czerwono:Rozważmy najpierw przypadek, w którym oba dane wejściowe to
0
:Zaczynamy od szarej ścieżki, która po prostu zwiększa krawędź A do,
1
tak aby#
przełącza się na IP,1
która jest niebieską ścieżką, zaczynając od prawego górnego rogu.\
nic tam nie robi i?
czyta dane wejściowe. Zawijamy do lewego górnego rogu, gdzie)
inkrementuje to wejście. Teraz, dopóki dane wejściowe są równe zero, spowoduje to1
, że#
nic nie zrobi. Następnie{
przesuwa MP w lewo, czyli na pierwszej iteracji z do B . Ponieważ ta krawędź wciąż ma swoje początkowe zero, IP zawija się z powrotem w prawy górny róg i na nowej krawędzi pamięci. Tak więc ta pętla będzie kontynuowana tak długo, jak odczyta zera, przesuwając MP wokół sześciokąta od B?
do C do D i tak dalej. Nie ma znaczenia, czy?
zwraca zero, ponieważ było to dane wejściowe, czy dlatego, że było to EOF.Po sześciu powtórzeń przez tę pętlę,
{
powraca do . Tym razem krawędź przechowuje już wartość z pierwszej iteracji, więc IP zawija się do lewego rogu i kontynuuje na zielonej ścieżce. po prostu drukuje to i kończy program.1
!
1
@
A co jeśli jakieś dane wejściowe są
1
?Następnie
?
czyta to1
w pewnym momencie i)
zwiększa to2
. Oznacza to,#
że teraz zmieni ponownie adresy IP i będziemy kontynuować w prawym rogu na czerwonej ścieżce.?
odczytuje kolejne dane wejściowe (jeśli takie są), które tak naprawdę nie mają znaczenia i{
przesuwa się o jedną krawędź dalej. To musi być niewykorzystane zbocze, dlatego działa dla maksymalnie 5 wejść. Adres IP zawija się w prawym górnym rogu, gdzie jest natychmiast odbijany i zawija się w lewym rogu.!
drukuje0
nieużywaną krawędź i#
przełącza z powrotem na IP0
. To IP wciąż czekało na#
południowo-zachodniej (szara ścieżka), więc natychmiast trafia@
i kończy program.W sumie dla tej bramki istnieje siedem 7-bajtowych rozwiązań. 5 z nich działa tak samo jak to i po prostu użyj innych poleceń, aby przejść do nieużywanej krawędzi (i może chodzić po innym sześciokącie lub w innym kierunku):
Jest jeszcze jedna klasa rozwiązań, która działa tylko z dwoma danymi wejściowymi, ale których ścieżki wykonania są w rzeczywistości jeszcze bardziej bałagan:
1001
: RównośćTo również bardzo sprytnie wykorzystuje warunkowy wybór adresu IP. Musimy ponownie rozróżnić między
A = 0
iA = 1
. W pierwszym przypadku chcemy wydrukowaćnot B
, w drugim chcemy wydrukowaćB
. DlaA = 0
nas również rozróżnić dwa przypadki dlaB
. Zacznijmy odA = B = 0
:Zaczynamy na szarej ścieżce.
(~
można zignorować, IP zawija się w lewym rogu (wciąż na szarej ścieżce) i czyta zaA
pomocą?
.(
zmniejsza to, więc otrzymujemy-1
i IP zawijamy do lewego dolnego rogu. Teraz, jak powiedziałem wcześniej,#
bierze wartość modulo6
przed wyborem jego IP, więc wartość-1
faktycznie wychodzi z IP5
, która zaczyna się w lewym rogu na czerwonej ścieżce.?
czytaB
, również to(
zmniejsza, abyśmy pozostali na IP,5
kiedy uderzymy#
ponownie.~
neguje-1
tak, że IP zawija się w prawym dolnym rogu, drukuje1
i kończy.Teraz, jeśli
B
jest1
, obecna wartość będzie,0
gdy uderzymy#
drugi raz, więc przełączamy się z powrotem na IP0
(teraz na zielonej ścieżce). To uderza?
po raz trzeci, ustępując0
,!
drukuje i@
kończy.Wreszcie przypadek, w którym
A = 1
. Tym razem obecna wartość jest już zerowa, gdy uderzamy#
po raz pierwszy, więc nigdy nie przełącza się ona na IP5
. Po prostu kontynuujemy natychmiast zieloną ścieżkę.?
teraz nie tylko podaje zero, ale zwracaB
.!
drukuje i@
kończy ponownie.W sumie istnieją trzy 7-bajtowe rozwiązania dla tej bramki. Pozostałe dwa działają bardzo odmiennie (nawet od siebie) i jeszcze dziwniej je wykorzystują
#
. W szczególności odczytują jedną lub więcej wartości za pomocą,
(odczytuje kod znakowy zamiast liczby całkowitej), a następnie używają tej wartości modulo 6, aby wybrać adres IP. To całkiem szalone.1010
: Nie bTen jest dość prosty. Ścieżka wykonania jest gałęzią poziomą, którą znamy
and
wcześniej.??
czyta,A
a potem natychmiastB
. Po odbiciu|
i rozgałęzieniuB = 0
wykonamy dolną gałąź, w której)
zwiększa się wartość, do1
której jest następnie drukowany!
. Na górnej gałęzi (jeśliB = 1
) po?
prostu zresetuj krawędź, do0
której jest następnie drukowane!
.Istnieje osiem 6-bajtowych programów dla tej bramki. Cztery z nich są prawie takie same, używając albo
>
zamiast|
albo1
zamiast)
(lub obu):Dwa używają jednego,
?
który jest używany dwa razy z powodu lustra. Negacja dzieje się wtedy tak, jak wxor
przypadku jednego z nich(~
lub~)
.I na koniec, dwa rozwiązania używają warunkowego przełącznika IP, ponieważ po co korzystać z prostego sposobu, jeśli zawiłe również działa:
1011
: B oznacza AWykorzystuje to dość skomplikowane przełączanie adresów IP.
A = 1
Tym razem zacznę od przypadku, ponieważ jest to prostsze:Zaczynamy na szarym drogi, który odczytuje
A
z?
czym uderza#
. PonieważA
jest1
to przełącza się na IP1
(zielona ścieżka).!
Natychmiast drukuje, że IP zawija się w lewym górnym rogu, czytaB
(niepotrzebnie) i kończy.Kiedy
A = 0
sprawy stają się bardziej interesujące. Najpierw zastanówmy sięA = B = 0
:Tym razem
#
nic nie robi i pozostajemy na IP0
(czerwona ścieżka od tego momentu).?
czytaB
i1
zamienia go w1
. Po owinięciu w lewym górnym rogu, uderzamy#
ponownie, więc ostatecznie trafiamy na zieloną ścieżkę i drukujemy1
jak poprzednio, przed zakończeniem.Wreszcie, oto
(A, B) = (0, 1)
fałszywy przypadek:Zauważ, że usunąłem początkową szarą ścieżkę dla przejrzystości, ale program zaczyna się w ten sam sposób i kończymy na czerwonej ścieżce jak poprzednio. Tym razem drugi
?
powraca1
. Teraz spotykamy1
. W tym momencie ważne jest, aby zrozumieć, co faktycznie robią cyfry w Heksagonii (do tej pory używaliśmy ich tylko na zerach): gdy napotkasz cyfrę, bieżąca wartość zostanie pomnożona przez 10, a następnie cyfra zostanie dodana. Zwykle jest to używane do zapisywania liczb dziesiętnych dosłownie w kodzie źródłowym, ale oznacza to, żeB = 1
faktycznie jest odwzorowane na wartość11
. Więc kiedy trafiliśmy#
, to jest brane modulo6
do orzekania5
, a więc możemy przejść do IP5
(zamiast1
, jak poprzednio) i dalej na niebieskiej ścieżce. Uderzenie?
trzeci raz zwraca zero, więc!
drukuje to, a po kolejnych dwóch?
IP zawija się w dolnym prawym rogu, gdzie kończy się program.Istnieją cztery 7-bajtowe rozwiązania tego problemu i wszystkie działają inaczej:
1100
: Nie AWystarczy jeden prosty liniowy: czytaj
A
z?
, neguje się(~
, drukować!
, kończą się@
.Istnieje jedno alternatywne rozwiązanie, a
~)
zamiast tego neguje się :1101
: A oznacza BJest to o wiele prostsze niż przeciwna implikacja, o której właśnie mówiliśmy. To znowu jeden z tych horyzontalnych programów branżowych, jak ten dla
and
. JeśliA
tak0
, po prostu zwiększa się1
na dolnej gałęzi i drukuje. W przeciwnym razie górna gałąź jest wykonywana ponownie tam, gdzie?
czyta,B
a następnie ją!
drukuje.Jest tu mnóstwo alternatyw (w sumie 66 rozwiązań), głównie ze względu na swobodny wybór skutecznych no-opów. Na początek możemy zmieniać powyższe rozwiązanie we wszystkich taki sam sposób moglibyśmy za
and
i możemy również wybierać pomiędzy)
i1
:A potem jest inna wersja wykorzystująca warunkowy wybór adresu IP, w którym pierwsze polecenie można wybrać prawie arbitralnie, a także istnieje wybór pomiędzy
)
i1
dla niektórych z tych opcji:1110
: NandOstatni skomplikowany. Jeśli nadal czytasz, prawie to zrobiłeś. :) Spójrzmy
A = 0
najpierw:?
czyta,A
a potem trafiamy$
. Jest to polecenie skoku (takie jak Befunge#
), które pomija kolejną instrukcję, abyśmy nie zakończyli na@
. Zamiast tego adres IP jest kontynuowany w#
. Jednak ponieważA
znaczy0
, to nie robi nic.)
zwiększa ją, aby1
adres IP był kontynuowany na dolnej ścieżce, w której1
drukowany jest. W<
odchyla IP w prawo, gdzie owija się w lewym rogu i program kończy.Następnie, gdy dane wejściowe są
(A, B) = (1, 0)
, otrzymujemy tę sytuację:Jest to w zasadzie takie same jak przed tą różnicą, że u
#
nas włączyć do OD1
(zielony ścieżka), ale ponieważB
jest0
nam wrócić do OD0
, kiedy uderzył#
po raz drugi (teraz niebieski ścieżki), gdzie drukuje1
jak poprzednio.Wreszcie
A = B = 1
sprawa:Tym razem, gdy my
#
po raz drugi, bieżąca wartość jest nadal1
, abyśmy nie zmienili IP ponownie.<
Odzwierciedla to i trzeci raz trafiliśmy?
otrzymujemy zero. Dlatego IP zawija się w lewym dolnym rogu, gdzie!
wypisuje zero i program się kończy.Łącznie jest na to dziewięć 7-bajtowych rozwiązań. Pierwsza alternatywa po prostu używa
1
zamiast)
:Są też dwa rozwiązania, które pozwolą ci zmierzyć się z ilością przełączanych adresów IP:
To naprawdę zadziwiło mnie: interesującą częścią jest to, że przełączanie adresów IP może być używane jako odroczony warunek. Reguły przełączania adresów IP w języku są takie, że bieżący adres IP robi kolejny krok przed przełączeniem. Jeśli ten krok zdarzy się przejść przez róg, to bieżąca wartość decyduje o tym, w której gałęzi adres IP będzie kontynuowany, jeśli kiedykolwiek wrócimy do niego. Dokładnie dzieje się tak, gdy wejście jest
A = B = 1
. Chociaż wszystko to jest spójne z tym, jak zaprojektowałem język, nigdy nie zdawałem sobie sprawy z tego wpływu specyfikacji, więc miło jest, gdy mój język uczy mnie nowych sztuczek: D.Jest też trzecie rozwiązanie, którego przełączanie adresów IP jest jeszcze gorsze (chociaż nie wykorzystuje tego odroczonego efektu warunkowego):
A potem jeszcze jeden:
A potem są te cztery równoważne rozwiązania, które wykorzystują pewne bezwarunkowe przełączanie adresów IP i zamiast tego implementują całą logikę za pośrednictwem gałęzi i narożników:
1111
: PrawdziweNa koniec zasłużyłeś sobie na coś prostego: ustaw krawędź na
1
, drukuj!
, zakończ z@
. :)Oczywiście istnieje jedna alternatywa:
Jak zwykle wszystkie diagramy kontrolne utworzone za pomocą HexagonyColorer Timwi i diagram pamięci z jego EsotericIDE .
źródło
APL,
222018 bajtówPrawda i fałsz to kompletne programy, a pozostałe 14 to funkcje. (Dzięki Adám.)
Wypróbuj tutaj.
źródło
0
i1
.Szachy / mierny szachista w grze końcowej, 70 sztuk
Zainspirowany odpowiedzią domina, zdecydowałem, że kolejna gra powinna mieć ten zaszczyt.
Pamiętaj, że wziąłem kilka zasad dotyczących ruchu elementów. Ponieważ nie mam ochoty studiować optymalnych ruchów w każdej sytuacji, zasady dotyczące białych ruchów są proste: trzymaj się z daleka, złap najwyższy kawałek, który może obrócić, tracąc jednocześnie jak najmniej materiału i zatrzymaj pionka od promowania, w tej kolejności pierwszeństwa. Jeśli są dwa pola, na które może się poruszać, z równą uprzywilejowaniem, może przejść do jednego z nich (stąd na nich, jeśli może przejść do więcej niż jednego kwadratu, mają ten sam kolor). Zauważ, że biały złapie coś, nawet jeśli zostanie złapany, jeśli atakowany element ma większą wartość niż utracony. Wartości są tutaj:
pawn<knight=bishop<rook<queen
Dane wejściowe określają, czy wieża jest obecna, czy nie. Zauważ, że wieże są oznaczone tylko nazwami A i B, gdy ma to znaczenie: jeśli brama zachowuje się tak samo, gdy wieże są przełączane, nie są one oznaczone.
Wyjście ma kolor kwadratowego białego króla, który kończy się na: Biały = 1, czarny = 0
Przed zdjęciami chcę przeprosić za słabe obrazy. Nie jestem zbyt dobry w trzymaniu aparatu nieruchomo.
Fałsz, 4:
ORAZ 4:
A, a nie B, 5 (myślę, że mogę sprowadzić to do trzech, ale nie mam teraz wyżywienia):
A, 4:
Nie A i B, 5 (myślę, że mogę sprowadzić to do trzech, ale nie mam teraz wyżywienia):
B, 4:
Xor, 5 (znam sposób, aby zrobić 4, ale nie mam teraz planszy):
Lub 4:
Ani 4:
Xnor, 5 (Znam sposób, aby zrobić 4, ale nie mam teraz planszy):
Nie B, 4:
B oznacza A, 5 (myślę, że mogę sprowadzić to do trzech, ale nie mam w tej chwili wyżywienia):
Nie A, 4:
A implikuje B, 5 (myślę, że mogę sprowadzić to do trzech, ale nie mam teraz wyżywienia):
Nand, 4:
Prawda 4:
źródło
Galaretka , 19 bajtów
Wypróbuj online!
źródło
¤
i¬
są 2 bajty, a nie 1.0 0 1 0 > 1 byte Greater than.
czy to nie zawiedzie, jeśli drugie wejście będzie ujemne?Bramy logiczne NAND - 31 bramek
Jako twórcy oryginalnej serii z NAND bramy pytania , nie mogłem przepuścić okazji do korzystania z tych bram rozwiązać inny problem logika bramy.
Na każdym z tych schematów górne wejście to A, a dolne wejście to B.
źródło
Bitowy cykliczny znacznik , 118 bitów = 14,75 bajtów
Bitowy cykliczny tag jest prawdopodobnie najprostszym językiem Turinga, jaki kiedykolwiek wymyślono. Istnieje taśma programowa i taśma danych, obie składające się z listy bitów. Taśma programu jest interpretowana cyklicznie, dopóki taśma danych nie będzie pusta, w następujący sposób:
0
: usuń pierwszy bit z taśmy danych.1x
: jeśli pierwszy bit taśmy danych ma wartość 1, dołącz bitx
do taśmy danych.Inicjalizujemy taśmę danych za pomocą 1, po której następują dwa bity wejściowe (1 jest konieczne, ponieważ nie ma możliwości utworzenia 1, jeśli taśma danych składa się w całości z 0) i używamy końcowego usuniętego bitu danych jako wyjścia bramki .
false
):001
and
):1001001
A and not B
):0110100
A
):1001
not A and B
):0100
B
):0
xor
):0110110010
or
):0110
nor
):1101001000
xnor
):110101001100
not B
):1100100
B implies A
):110101101000
not A
):11010000
A implies B
):11010011001
nand
):10110100100010
true
):1100
źródło
1
nafalse
wymagane?0
do taśmy, aby można ją było usunąć jako ostatnią.Python 2, 137 bajtów
Pobiera dane wejściowe takie jak
min(True,False)
(lub jakomin(1,0)
). Ma dużą przewagę nad wyjściami, które muszą mieć tylko odpowiednią wartość Truthy-Falsey. O ile to możliwe, wykorzystuje wbudowany system, aby uniknąć kosztownościlambda
. Użyłem kodu, aby wyszukać wbudowane działające.Moim ulubionym jest to
{0:1}.get
, o czym myślałem ręcznie. Słownik{0:1}
mapuje klucz0
na wartość1
. Taget
metoda przyjmuje klucz i domyślną wartość wyjściową odpowiadającą kluczowi lub wartość domyślną, jeśli nie ma takiego klucza. Zatem jedynym sposobem na wyprowadzenie a0
jest as{0:1}.get(1,0)
, z brakującym kluczem1
i wartością domyślną0
. Można uzyskać inne warianty z różnymi słownikami, ale tylko ten był najkrótszy.źródło
__lt__
lub__eq__
? Spowoduje to dalsze zmniejszenie liczby bajtów:int.__gt__
zamiastlambda a,b:b<1
,int.__eq__
zamiast,lambda a,b:a==b
i tak dalejint
porównują odciążeniacmp
. Nie próbowałem tego w Pythonie 3.not
for0001
,False
- ideonenot
nie spełnia wymagań funkcji, ponieważ nie możesz tego zrobićf=not;f(3,4)
. Ciągnot
zdarza się działać, ponieważ rzekome argumenty funkcji wyglądają jak krotka, tak samo3+
działałoby,3+(4)
jakby3+
nie była funkcją, którą można przyjąć4
jako dane wejściowe.Go (gra), 33 kamienie, 73 skrzyżowania
Jeśli domino i szachy są dopuszczalne, to jest to. Na pełnej planszy 19x19 Go nie może być zbyt golfowy. Użyłem więc małych prostokątnych desek. Dane wejściowe dotyczą tego, czy kamienie oznaczone 1 i 2 są obecne. Wynik jest taki, czy czarny wygrywa. Wykorzystuje ocenę punktową, 0,5 komi, superko sytuacyjne, bez samobójstw. Cały czarny do gry. Niektóre mają wiele rozwiązań.
Białe wygrane (2, 1x5):
1 i 2 (3, 2x3):
1, a nie 2 (2, 1x5):
1 (2, 1x5):
Nie 1 i 2 (2, 1x5):
2 (2, 1x5):
1 x lub 2 (2, 2x3):
1 lub 2 (2, 1x5):
1 ani 2 (2, 1x4):
1 = 2 (2, 1x7):
Nie 2 (2, 1x3):
1 lub nie 2 (2, 1x4):
Nie 1 (2, 1x3)
Nie 1 lub 2 (2, 1x4):
1 i 2 (2, 1x3):
Czarne wygrane (2, 1x3):
Ta strona pomogła mi trochę: http://www.mathpuzzle.com/go.html
Może ktoś mógłby znaleźć rozwiązanie 2 kamieni dla 1 i 2 na planszy 1x9 ...
źródło
JavaScript ES6, 124 bajty
Poważnie nienawidzę teraz lambdów.
źródło
a=>b=>0
, abya=>0
i powiedzieć gramatyka nazywając to jest(a=>0)(a,b)
tylko dla tych 4 wpisy.Math.min
zamiasta=>b=>a&b
.Math.max
zamiasta=>b=>a|b
.Math.pow
zamiasta=>b=>a>=b
.parseInt
zamiasta=>b=>a>b
.!NaN
=>true
,!!NaN
=>false
Siatkówka ,
6239 bajtów23 bajty dzięki @MartinEnder !
Pobiera dane wejściowe jako
PQ
.Zwraca liczbę całkowitą między
0
do3
.0
jest falsey, inni są prawdomówni.Wyjaśnienie
Wszystkie są tylko wyrażeniami regularnymi .
Na przykład
01|10
po prostu pasuje01
lub10
.W
0000
,2
nigdy nie będzie na wejściu, więc nigdy nie pasuje.W
1111
dopasowuje pusty ciąg znaków, który istnieje4
.źródło
^1|0$
powinien pasować tylko 1 ciąg znaków. Co tu się dzieje?1
na początku wprowadzania] LUB [0
na końcu wprowadzania]. Zajęło mi to również chwilę, aby go zdobyć ...^1|0$
jest trudniejszy do odczytania niż1.|.0
. Wydaje się, że czytanie jest trudniejszeStack Cats , 67 + 64 = 131 bajtów
Zauważ, że +64 wynika z zastosowania
-nm
flag do każdego programu.-n
wskazuje numeryczne we / wy i-m
odzwierciedla kod źródłowy ostatniego znaku - nie wszystkie zgłoszenia wymagają tych flag technicznie, ale dla spójności i prostoty oceniam je w ten sam sposób.()
w Stack Cats sprawdza, czy element jest dodatni czy dodatni (tj. 0 lub ujemny), więc używamy go odpowiednio do prawdy / fałszu. Druga kolumna jest tylko dla zainteresowania i zawiera najlepsze bramki z0
/1
s jako dane wyjściowe (z łącznym wynikiem 90).Dane wejściowe to bity oddzielone separatorem przez STDIN. Wypróbuj online!
Stack Cats to odwracalny ezoteryczny język, w którym programy mają odblaskową symetrię. Biorąc pod uwagę fragment kodu
f
(np.>[[(!-)/
), Odbicie lustrzane (np.\(-!)]]<
) Oblicza odwrotnośćf^-1
. Jako takie, nawet programy długości nic nie robią (lub utkną w nieskończonej pętli), a jedyne nietrywialne programy mają nieparzystą długość, obliczającf g f^-1
gdzieg
jest operator centralny.Ponieważ połowa kodu źródłowego jest zawsze nadmiarowa, można go pominąć, a uruchomienie kodu z
-m
flagą wskazuje, że kod źródłowy powinien być dublowany nad ostatnim znakiem, aby pobrać rzeczywisty kod źródłowy. Na przykład program*<X
jest w rzeczywistości*<X>*
symetryczny.Gra w golfa w Stack Cats jest bardzo nieintuicyjna, więc powyższe programy musiały zostać znalezione brutalną siłą. Większość z nich jest zaskakująco skomplikowana, ale wyjaśnię kilka i dodam do tej odpowiedzi, kiedy będę miał czas. Na razie niektóre objaśnienia i alternatywne rozwiązania dla wersji
0
/1
można znaleźć w repozytorium Github tutaj .źródło
Note that the +64 is from applying the -nm flags to each program.
3 * 16 = 48 lub 2 * 16 = 32, w obie strony 64 to droga haiHaskell,
787675 bajtów_#_=2<1
&&
>
pure
<
_#b=b
/=
||
(not.).max
==
_#b=not b
>=
a#_=not a
<=
(not.).min
_#_=1<2
Edycja: -1 bajt dzięki @cole.
źródło
_#_
nie jest standardowym operatorem!” I wtedy zrozumiałem ... Dobra robota.pure
pure
został wprowadzonyPrelude
w 2015 roku, więc był dostępny w czasie tego wyzwania.Brachylog ,
3634 bajtówOczekuje się,
0
że będzie to wartość fałszywa i1
prawdziwa. Zwracatrue
lubfalse
. p oznaczaInput
q oznaczaOutput
.źródło
Input
iOutput
zgodnie z konwencją, ale można ustawić wartości na oba lub zwrócić wartości z obu.Prolog,
147145 bajtówZdobył 2 bajty dzięki @SQB
Zapytanie
x(P,Q).
ox
bycie odpowiednią literę aP
iQ
ustawiony na 0 lub 1.Zwraca
true
lubfalse
.SZWAJCOWY przykład z testami - enter,
runTest.
aby uruchomić.źródło
a(2,2).
fałsz?a(a,a).
(lub jakikolwiek inny list) również działa ia
nie jest akceptowalnym wkładem do prawdy, więc to dobrze. Dzieki za sugestie.NTFJ, 86 bajtów
Wypróbuj tutaj! Ale najpierw przeczytaj poniżej.
Dane wejściowe są niejawne na stosie. Wynik zostaje pozostawiony na stosie. Dodaj 16 bajtów (jeden
*
na końcu każdego z nich), jeśli chcesz0x00
lub0x01
do wyjścia reprezentującego 0 i 1. dodać dodatkowe 160 bajtów, jeśli chcesz0
lub1
wydrukowany. (Umieść~~##~~~#{@
przed każdym*
.)Jedynym operatorem binarnym NTFJ jest NAND, więc każdy z nich jest zapisany w formie NAND.
Przejrzyjmy każdy z nich.
0: fałsz
~
reprezentuje fałszywy bit. Wystarczająco proste. Ponieważ dane wejściowe są niejawne u dołu stosu, pozostawia się je u góry stosu.1: p i q
NTFJ działa na stosie.
:
to polecenie duplikowania. Obserwuj top and q
≡not (p nand q)
i tamtonot q = q nand q
.(Uwaga:
:|
można zatem powiedzieć, że to negacja i|:|
można powiedzieć, że to koniunkcja )2: p, a nie q
Zauważ, że to tylko negacja
:|
i koniunkcja|:|
.3: s
$
wyskakuje przedmiot ze stosu. Więc tak.4: nie p i q
To jest to samo, co 2, z wyjątkiem
#{
na początku.#
przesuwa 1 (prawdziwy bit) i raz{
obraca stos w lewo. Wystarczająco proste.5: q
Obróć raz w lewo, upuść.
6: xor
Przestrzegać:
Nie ma jednak możliwości całkowitego skopiowania stosu. Więc będziemy musieli wnieść każda
p
,q
do góry i powielić go.I tak mamy nasz XOR.
7: p lub q
Neguj górę, zbliż od dołu do góry, neguj to i połącz je razem. Zasadniczo
p or q = (not p) nand (not q)
.8: nie p i nie q
Jest to po prostu negacja 7. Łatwa.
9: równ
To tylko xnor lub nie xor. Znowu proste.
10: nie q
Negacja 5.
11: p lub nie q
Neguj p, nand.
(not p) nand q = not ((not p) and q) = p or (not q) (by De Morgan's laws)
.12: nie p
Upuszczaj, zatrzymuj i neguj.
13: nie p lub q
Prawa De Morgana, by znów uratować dzień! Taki sam proces jak w przypadku 11, tylko negowanie
q
zamiastp
.14: nie p lub nie q
To tylko mimika.
15: prawda
#
to prawda.źródło
:|
?Minecraft, 89 bloków
Na wszystkich poniższych zdjęciach niebieskie bloki dotyczą wejścia A, a pomarańczowe bloki dotyczą wejścia B.
16. PRAWDA brama - 1 bloki
15. Bramka NAND - 1x2x3 = 6 bloków
14. A => B - 1x2x3 = 6 bloków
13. NOT A - 2 bloki
12. B => A - 1x2x3 = 6 bloków
11. NOT B - 2 bloki
10. XNOR - 1x3x4 = 12 bloków
9. NOR - 1x2x3 = 6 bloków
8. LUB - 1 bloki
7. XOR - 1x3x4 = 12 bloków
6. B - 1 bloki
5.! A&B - 1x2x5 = 10 bloków
4. A - 1 bloki
3. A &! B - 1x2x5 = 10 bloków
2. I - 2x2x3 = 12 bloków
1. FAŁSZ - 1 bloki
źródło
Mathematica, 67 bajtów
Każda z nich ocenia się na funkcję, więc możesz ich używać w podobny sposób
Ach, gdyby tylko liczby całkowite były zgodne z prawdą / fałszem w Mathematica, te cztery dłuższe mogłyby zostać znacznie skrócone.
źródło
MATL,
3423 bajtówMam nadzieję, że wszystko w porządku! Zero to falsey, niezerowe to prawda. Każda funkcja pobiera dwa niejawne dane wejściowe (chociaż może ignorować niektóre dane wejściowe). Pierwsze wejście to A, a drugie B. Możesz wpisać
0
/1
dla true / false lubT
/F
.Oto przykład TryItOnline dla przypadku testowego 3.
Zaoszczędziłem 4 bajty za pomocą
*
forand
, a kolejne 4 za pomocą>
/<
zamiast~wY&
/w~Y&
po tym, jak zobaczyłem odpowiedź Dennisa!źródło
-
dc, 37 bajtów
dc
(„kalkulator biurkowy”) to standardowe polecenie unixowe, kalkulator pocztowy oparty na stosie. Brakuje operacji bitowych, a operatorów porównania można używać tylko do wykonywania makr (co nie jest warte bajtów). Podział na liczby całkowite to odrobina.Skrypty te oczekują
0
i1
wartości na stosie, i pozostawić wynik na stosie.źródło
Labirynt , 85 bajtów
Dzięki Sp3000 za oszczędność 2 bajtów.
Wszystkie są pełnymi programami, odczytują dwie liczby całkowite
0
lub1
ze STDIN (przy użyciu dowolnego separatora niecałkowitego) i wypisują wynik jako0
lub1
do STDOUT.Wypróbuj online!(Nie jest to zestaw testowy, więc będziesz musiał ręcznie wypróbować różne programy i dane wejściowe).
Jeśli chodzi o wyjaśnienia, wszystkie są dość proste. Wszystkie programy są liniowe, a używane polecenia wykonują następujące czynności:
Zauważ, że używam
#
jest zawsze używany do łączenia go$
, tj. Do obliczaniaXOR 1
, lub innymi słowy do logicznej negacji. Tylko w kilku przypadkach mogłem użyć~
zamiast tego, ponieważ kolejne&
odrzucają wszystkie niechciane bity z wynikowego-1
lub-2
.źródło
Kod maszynowy IA-32, 63 bajty
Hexdump kodu z dezasemblacją:
Kod jest dłuższy niż mógłby być, ponieważ używa się standardowej konwencji kodowania: wejście w
ecx
iedx
i wyjście wal
. Można to wyrazić w C jakoWygląda na to, że MS Visual Studio nie rozumie nieudokumentowanego
SALC
opcode, więc musiałem użyć jego kodu zamiast nazwy.Dziękuję l4m2 za ulepszenie niektórych próbek kodu!
źródło
1110 8D4411FE LEA EAX, [ECX+EDX-2]
C 34 bajty
Gdzie n to numer funkcji do użycia, ale myślę, że zostałby odrzucony, więc proponuję inną:
C 244 bajty (przy użyciu pamięci)
używa podwójnie indeksowanej tablicy.
n[0][1]
jest(A implies B)(0,1)
Dalej 138 bajtów
Właśnie nauczyłem się Fortha. Przypuszczam, że jest kompatybilny z Ansi Forth, ponieważ działa również na gforth.
Funkcja z utwórz nową funkcję o podanej nazwie, a następnie umieść numer bramki logicznej z góry stosu na nowy adres funkcji. Pozostawia następną (n + 1) funkcję bramki logicznej na stosie do następnej deklaracji.
możesz to przetestować:
i AB
(„.” drukuj górę stosu „cr” oznacza powrót wózka)
źródło
C, 268 bajtów
Makra wydają się krótsze niż funkcje.
źródło
Brian & Chuck , 183 bajtów
Dzięki Sp3000 za oszczędność 4 bajtów.
Niektóre programy zawierają znak niezadrukowany. W szczególności każdy
\x01
powinien zostać zastąpiony<SOH>
znakiem kontrolnym (0x01):Wartości wejściowe i wyjściowe wykorzystują bajty , więc dane wejściowe powinny wynosić dwa bajty 0x00 lub 0x01 (bez separatora), a dane wyjściowe będą jednym takim bajtem. Jest to tak naprawdę najbardziej sensowna definicja prawdy / fałszu dla B&C, ponieważ jest to jedyne polecenie sterowania przepływem
?
traktuje zera jako fałsz i wszystko inne prawdziwe.Objaśnienia
Najpierw szybki podkład B&C:
,
(bajt wejściowy), a tylko Chuck może używać polecenia.
(bajt wyjściowy).[]
Pętla Brainfuck nie istnieje. Zamiast tego jedynym przepływem kontrolnym, jaki masz, jest?
przełączenie sterowania na inne wystąpienie, jeśli bieżąca wartość pod głowicą taśmy jest niezerowa.>
i<
, istnieją{
i}
które są zasadniczo równoważne fragmentom Brainfuck[<]
i[>]
, to znaczy, przesuwają głowicę taśmy do następnej pozycji zerowej w tym kierunku. Główną różnicą jest to, że{
można ją również zatrzymać na lewym końcu taśmy, niezależnie od jej wartości._
znaki w kodzie źródłowym są zastępowane zerowymi bajtami (ponieważ są one bardzo przydatne w nietradycyjnych programach w celu przechwytywania{
i}
).Zauważ, że we wszystkich programach taśma Chucka zaczyna się od
#
. To może być naprawdę wszystko.?
działa tak, że głowa taśmy przesuwa się o jedną komórkę przed rozpoczęciem wykonywania (tak, że sam warunek nie jest wykonywany, jeśli zdarzy się, że jest prawidłowym poleceniem). Więc nigdy nie możemy użyć pierwszej komórki Chucka do kodu.Istnieje pięć klas programów, które wyjaśnię szczegółowo później. Na razie wymieniam je tutaj w kolejności rosnącej złożoności.
0000
,1111
: Funkcje stałeTo są bardzo proste. Przechodzimy na Chucka bezwarunkowo. Chuck przesuwa głowicę taśmy do nieużywanej komórki w prawo i albo drukuje ją bezpośrednio, albo zwiększa ją najpierw, aby wydrukować
1
.0011
,0101
,1010
,1100
: Funkcje zależności tylko jedno wejścieW zależności od tego, czy zaczynamy od,
,
czy,,
pracujemy zA
lubB
. Spójrzmy na pierwszy przykład0011
(tjA
.). Po odczytaniu wartości używamy?
jej warunkowo. JeśliA = 1
, to przełącza się na Chucka, który przesuwa głowicę taśmy w prawo i drukuje dosłownie osadzony1
bajt. W przeciwnym razie kontrola pozostaje na Brianie. W tym przypadku 1-bajt to brak operacji. Następnie zwiększamy dobrze wartość wejściową,+
aby upewnić się, że jest niezerowa, a następnie przełączamy na Chuck za pomocą?
. Tym razem>
przechodzi do nieużywanej komórki po prawej stronie, która jest następnie drukowana jako0
.Aby zanegować jedną z wartości, po prostu ją zmniejszamy
-
. Włącza1
się0
i0
na-1
, która jest różna od zera, a więc truthy o ile?
dotyczy.0001
,0010
,0100
,1000
: Funkcje binarne z jednej wyniku truthyJest to rozszerzenie poprzedniego pomysłu w celu pracy z dwoma wejściami. Spójrzmy na przykład
1000
(NOR). (Potencjalnie) czytamy oba dane wejściowe za pomocą,?
. Jeśli tak1
,?
przełącza się na Chucka. Przesuwa głowę taśmy do końca za pomocą}
(na pustą komórkę po kodzie Briana), przesuwa kolejną komórkę za pomocą>
(wciąż zero) i drukuje ją.
.Jednak jeśli oba wejścia są zerowe, kontrola jest nadal z Brianem.
>
następnie przesuwa głowicę taśmy w}
taki sposób, że to polecenie nie jest wykonywane po przełączeniu na Chucka za pomocą?
. Teraz wszystko, co robi Chuck,>.
przesuwa się tylko na1
komórkę i drukuje to.Możemy łatwo uzyskać pozostałe trzy funkcje, negując jeden lub oba wejścia zgodnie z wymaganiami.
0111
,1011
,1101
,1110
: Funkcje binarne z trzech wyników truthyDrobna modyfikacja poprzedniego pomysłu, aby zignorować wynik (tj. Wydrukować,
0
gdy przejdziemy przez cały Brian i1
nie tylko). Spójrzmy na0111
(LUB) jako przykład. Zauważ, że wbudowany-1
bajt nie działa, więc nadal zaczyna się od,?,?
. Jeśli którekolwiek z tych danych wejściowych1
, przełączamy na Chucka, który przesuwa głowicę z powrotem na początek{
.>.
przesuwa głowicę taśmy na ten1
bajt i drukuje ją.Jeśli oba wejścia są równe zero, pozostajemy z Brianem, przesuń głowicę taśmy,
{
aby ją pominąć, a następnie przełącz na Chucka. Kiedy wykonuje>.
ten czas, przechodzi do pustej komórki po kodzie Briana i drukuje0
.Ponownie łatwo uzyskujemy inne funkcje, negując jedno lub oba dane wejściowe.
0110
,1001
: Funkcje binarne z dwoma prawdziwymi wynikamiTen jest nieco trudniejszy. Poprzednie funkcje były dość proste, ponieważ mogą być zwarte - wartość pierwszego wejścia może decydować o wyjściu, a jeśli nie, to patrzymy na inne wejście. W przypadku tych dwóch funkcji zawsze musimy przyjrzeć się obu wejściom.
Podstawową ideą jest użycie pierwszego wejścia do podjęcia decyzji, czy drugie wejście wybierze pomiędzy
0
i1
czy pomiędzy1
i0
. Weźmy0110
jako przykład (XOR):Zastanów się
A = 0
. W tym przypadku chcemy uzyskać dane wyjściowe bezB
zmian.,
czytaA
,?
nic nie robi.>
przechodzi do następnej (niezerowej) komórki, dzięki czemu}
dochodzimy do_
Chucka. Oto czytamy,B
ze,
i użyć?
ponownie. Jeśli takB
było0
, wciąż jesteśmy na Brianie.>
pomija}
on Chucka i?
przełącza, aby>.
drukować0
osadzony w kodzie źródłowym Briana. JeśliB
było1
z drugiej strony, Chuck już wykonuje polecenie,}
które przechodzi do_
kodu Briana, więc>.
wtedy wypisuje1
-byte.Jeśli
A = 1
, to od razu zmienimy na Chucka, który wykona polecenie}+{>?
. To powoduje przejście do_
kodu źródłowego Briana, zmienia go1
również w+
, a następnie przesuwa się z powrotem na początek{
i przeskakuje Briana,?
przesuwając jedną komórkę w prawo>
przed przekazaniem mu kontroli. Tym razem, po Brian czytać-tychB
, czyB = 0
i Chuck wykorzystuje>.
komórkę obok Briana?
będzie1
zamiast0
. Ponadto, kiedyB = 1
Chuck}
przeskakuje nad tym, co kiedyś było przerwą, i przesuwa się aż do końca taśmy, więc>.
zamiast tego drukuje zero. W ten sposób drukujemynot B
.Aby wprowadzić równoważność, po prostu zanegowaliśmy,
A
zanim użyliśmy go jako warunku. Zauważ, że z tego powodu musimy również dodać kolejny>
do Chucka, aby pominąć to-
również podczas powrotu do początku.źródło
ClojureScript,
88 84 7674 bajtynil
ifalse
są fałszywe, wszystkie inne wartości są prawdziwe. Booleany przymuszają do 0/1 za arytmetykę i nierówności. Funkcje mogą przyjmować niewłaściwą liczbę argumentów.źródło
0
fałsz?not not(0)
naFalse
wartość falsey.#f
,f
,false
, etc) jest fałszywe. Wszystkie pozostałe wartości są prawdziwe w większości języków funkcjonalnych.Brainfuck ,
184178174 bajtówWejścia / wyjścia używają U + 0000 i U + 0001.
źródło
0001
Czy nie możesz tego zrobić,[,>]<.
(biorąc pod uwagę tłumacza, który pozwala ci przejść na lewo od komórki początkowej)?Brain-Flak ,
418, 316 bajtówWypróbuj online!
Niech dane wejściowe będą górnymi dwiema liczbami na stosie na początku programu (zero dla fałszu dla prawdy), a dane wyjściowe będą górą stosu na końcu programu (zero dla fałdu dla prawdy).
false, 4 bajty (dzięki uprzejmości Leaky Nun )
(<>)
i 36 bajtów
(({}{}[(())()])){{}{}(((<{}>)))}{}{}
A, a nie B, 40 bajtów
((({}){}{}[(())()])){{}{}(((<{}>)))}{}{}
A, 6 bajtów
({}<>)
nie A i B, 38 bajtów
((({}){}{}[(())])){{}{}(((<{}>)))}{}{}
B, 2 bajty
{}
xor, 34 bajty
(({}{}[(())])){{}{}(((<{}>)))}{}{}
lub 6 bajtów
({}{})
ani 34 bajty
(({}{}<(())>)){{}{}(((<{}>)))}{}{}
xnor, 10 bajtów
({}{}[()])
nie B, 34 bajty
{}(({}<(())>)){{}{}(((<{}>)))}{}{}
B oznacza A, 14 bajtów
(({}){}{}[()])
nie A, 34 bajty
(({}<{}(())>)){{}{}(((<{}>)))}{}{}
A oznacza B, 16 bajtów
(({}){}{}[()()])
nand, 12 bajtów
({}{}[()()])
prawda, 6 bajtów
<>(())
Wyjaśnienie
Ponieważ większość z nich jest bardzo podobnych, nie zamierzam dokładnie wyjaśniać, jak działa każdy z nich. Staram się jednak wyjaśnić, jak działa cała szesnaście osób.
Po pierwsze, bramki, które zwracają trzy o tej samej wartości (tj. 2, 3, 5, 8, 9, 12, 14 i 15). Wszystkie one mają ten sam wzór. Najpierw konwertujesz dane wejściowe na liczbę dwubitową z miejscem jako dwójkami i B jako jednością. Odbywa się to za pomocą tego fragmentu
(({}){}{})
. Następnie odejmij wartość dwubitowego wejścia, które chcesz izolować({}[value])
. (W rzeczywistym kodzie odejmowanie i konwersja są wykonywane w jednym kroku, aby zapisać bajty). W razie potrzeby można to połączyć z nie(({}<(())>)){{}{}(((<{}>)))}{}{}
.Dalej: i, nor, lub, xor i xnor. Działają one podobnie do powyższych. W rzeczywistości niektóre z nich są uwzględnione powyżej, jednak ta metoda jest krótsza. Sztuczka, której tu użyłem, polega na tym, że każda z nich odpowiada sumie A B. Np. Xor ocenia na prawda, jeśli A + B = 1, a fałsz w przeciwnym razie. Najpierw dodajesz AB i odejmujesz odpowiednią kwotę. Wyrażony jako
({}{}[0,1,2 or 3])
. Następnie w razie potrzeby przeprowadź nieDalej: A, B, nie A i nie B. Są one dość oczywiste. Zaczynamy od usunięcia niepotrzebnej wartości, a następnie albo negujemy, albo kończymy.
Wreszcie są dwie prostoty: prawda i fałsz. W tym celu wypychamy prawidłową wartość na stos. W
<>
nilad zwraca zero, dzięki czemu możemy zaoszczędzić dwa bajty przy użyciu przełącznika jako wartość zerową.Nie jest to najskuteczniejsze rozwiązanie (być może najskuteczniejsze w Brain-Flak), ale pisanie ich sprawiało mi wiele radości i błagam, abyś spróbował je skrócić.
źródło
(<>)
wystarczy dlafalse
; również(<{}{}>)
ma 8 bajtów(<>)
pozostawi wejścia i umieści zero na drugim stosie.<>
wystarczy zefalse
względu na domniemane zera? Myślę też, żea
może to być pusty program.true
może być<>[][]
(nie zapisuje bajtów, ale wygląda świetnie: P).ProgFk ,
18,517,5 bajtówPonieważ instrukcje ProgFk są określone w skubkach, poniższy kod jest podany w systemie szesnastkowym, jedna bramka logiczna na linię i ze spacjami między bajtami.
Wyjaśnienie
ProgFk jest opartym na taśmie esolangiem (podobnym do Brainfuck), w którym każda komórka jest trochę, a instrukcje są podawane w postaci skubków (4 bajty). Instrukcje działają na komórce wskazanej wskaźnikiem instrukcji. Dane wejściowe są podawane w pierwszej i drugiej komórce (z odpowiednio
A
iB
pierwszą i drugą komórką), a wskaźnik instrukcji zaczyna się od pierwszej komórki. Dane wyjściowe są przechowywane w pierwszej komórce.Każda zastosowana instrukcja jest wyjaśniona poniżej.
Zapisano bajt dzięki @LeakyNun!
źródło
Właściwie 24 bajty
Programy te przyjmują dane wejściowe jako
A\nB
(z\n
reprezentacją nowej linii), co pozostawia B na górze stosu, z A poniżej.False
jest reprezentowany przez0
iTrue
jest reprezentowany przez dowolną dodatnią liczbę całkowitą.Dzięki Leaky Nun za 3 bajty
źródło