Wskazówki dotyczące gry w golfa w Befunge

12

Jakie masz ogólne wskazówki na temat gry w golfa w Befunge? Szukam pomysłów, które można by zastosować do problemów z golfem w kodzie, które są przynajmniej nieco specyficzne dla Befunge (np. „Usuń komentarze” nie jest odpowiedzią). Proszę zamieścić jedną wskazówkę na odpowiedź.

Justin
źródło
Nie jestem pewien, czy należy to zmienić ogólnie na Befunge, ale Befunge 93 jest znacznie mniej idealny do gry w golfa niż 98.
Justin
6
Mieliśmy ostatnio temat Befunge 93 , ale myślę, że lepiej byłoby uogólnić ten temat. Czy to by było w porządku? (i może zaznaczyć, które wskazówki są dobre dla której wersji / wersji, w taki sam sposób, w jaki wskazówki Python mówią, czy są one specyficzne dla Python 2 / Python 3)
Sp3000

Odpowiedzi:

9

Korzystając z pętli wieloliniowej, spróbuj użyć jej jak najwięcej:

>1234....v
^        <

vs

>1234v
^....<
Justin
źródło
7

Chcesz usunąć wartość po warunkowym (np. Ponieważ inna ścieżka zależy od wartości, ale ta nie)? Zamiast używać >$lub $<, skorzystaj z faktu, że znasz prawdziwą wartość zmiennej i użyj _zamiast tego zarówno do zmiany kierunku, jak i stosu pop.

Przykład

'* : v           >$ .. @          Prints number in binary followed by the original
                                  decimal number.
     > :2%\2/ :!#^_ \.

zamienia się w

'* : v           _  .. @          Since we know that the topmost value on the stack
                                  will be 0, we combine `>$` into `_`.
     > :2%\2/ :!#^_ \.
Robaczek świętojański
źródło
6

Nie zapominaj, że 0zawsze jest na stosie. Na przykład oznacza to, że przy pustym stosie gjest równoważne 00gi prównoważne 000p.

Justin
źródło
5

Jeśli musisz nacisnąć liczbę większą niż 15, użyj, 'aby pobrać wartość ASCII następnego znaku:

'*

wcisnąć 42 zamiast:

4a*2+
Justin
źródło
Lub 67*też działa
Klamka
4
@Doorknob Może powinienem był wybrać liczbę pierwszą, aby uzyskać lepszy punkt, ale 42 to taka świetna liczba.
Justin,
2
Uwaga: ta wskazówka dotyczy tylko Befunge-96 i nowszych. Befunge-93 nie obsługiwał 'instrukcji.
James Holderness
4

Zamiast używać |, wymagając innej linii (często z wieloma dodatkowymi spacjami), spróbuj użyć j. Na przykład:

01-`j@more code here

zatrzymałby się, gdyby liczba na górze stosu była ujemna, i kontynuowałaby w przeciwnym razie. Jeśli potrzebujesz wielu znaków, użyj n*jgdzie nto liczba znaków, której potrzebujesz, gdy przekazana wartość jto 0. Przykład:

01-`4*j01-*more code

co neguje liczbę ujemną.

Justin
źródło
Uwaga: ta wskazówka dotyczy tylko Befunge-96 i nowszych. Befunge-93 nie obsługiwał jinstrukcji.
James Holderness
4

W Befunge-93, jeśli pierwszą rzeczą, którą naciskasz na stos, jest sznurek, często możesz uciec od upuszczenia cytatu otwierającego. Na przykład to:

"!iH",,,@

można to uprościć:

!iH",,,@

Wypróbuj online!

Co się dzieje, interpreter najpierw próbuje wykonać znaki w niecytowanym ciągu. Do !wykonuje nieszkodliwy nie , a ii Hnie są ważne instrukcje, więc są one ignorowane (chociaż w niektórych implementacjach może pojawić się ostrzeżenie).

Po "napotkaniu jest to uważane za początek łańcucha, ale ponieważ nie ma cytatu zamykającego, owija się wokół pola gry, aż "napotka ponownie. To, co ostatecznie trafia na stos, to:

,,,@  ···72 spaces···  !iH

Ponieważ zależy nam tylko na kilku ostatnich postaciach, żadne z tych innych rzeczy nie ma znaczenia. Więc po cytacie w końcu możemy wykonać trzy ,polecenia, wypisać wiadomość i @polecenie, które wychodzi.

Zauważ, że zazwyczaj nie działa to w Befunge-98, ponieważ nierozpoznana instrukcja spowoduje, że interpreter będzie się zastanawiał, zamiast go ignorować.

James Holderness
źródło
W Befunge-98 możesz zamiast tego umieścić wymagany ciąg na końcu linii, tak jak to; ",,,@!iH. Zauważ, że Pyfunge dodaje dodatkowe miejsce, podczas gdy FBBI nie.
Jo King
@JoKing Nie chciałem tego sugerować, ponieważ, jak zauważyłeś, zachowanie różni się w zależności od tłumacza. Nawet jeśli wydaje się, że działa, jest niespójny (zwróć uwagę na dodatkowe miejsce w FBBI w tym przypadku ), więc całkiem możliwe, że w pewnym momencie może zostać naprawiony.
James Holderness
Hmm ... Myślę, że przestrzeń może być częścią specyfikacji. Pamiętam, że czytałem gdzieś, że wiele spacji zostanie pominiętych i będzie liczonych jako jedna spacja. Przykład w PyFunge i FBBI. Wydaje się, że FBBI dopasowuje każdą linię do długości najdłuższej linii, podczas gdy PyFunge domyślnie dodaje dodatkowe spacje.
Jo King
Masz rację - specyfikacja mówi, że wiele spacji w ciągu powinno być traktowanych jako pojedyncza spacja. W rzeczywistości ta zasada została specjalnie zaproponowana, aby poradzić sobie z problemem zawijania ciągów na nieskończonym polu gry (więc PyFunge jest wyraźnie poprawnym AFAIC). Ale opis algorytmu zawijania w specyfikacji jest nieco otwarty na interpretację, więc rozumiem, dlaczego niektóre implementacje mogą robić coś inaczej. Ale sedno jest dość skomplikowane i myślę, że lepiej byłoby to omówić jako osobną wskazówkę dotyczącą Befunge-97/98.
James Holderness,
4

W Befunge-93 często może być korzystne spłaszczenie pętli do pojedynczej linii, przy czym sekcja pętli kodu jest wykonywana w obu kierunkach.

Rozważmy na przykład poniższy kod, który wysyła literę aosiem razy:

"a"9>1-:#v_@
    ^\,:\<

Można to spłaszczyć spłaszczić do pojedynczej linii, przerywając sekwencję pętli instrukcjami mostkowania ( #):

"a"9>1#\-#,:#:>#\_@

Wypróbuj online!

Jeśli patrzysz tylko na znaki niebiałe, możesz odnieść wrażenie, że jest on dłuższy niż oryginał. Ale gdy weźmiesz pod uwagę wysuw linii i dodatkowe wypełnienie wymagane w wersji dwuwierszowej, w rzeczywistości oszczędzasz cztery bajty.

W tym konkretnym przypadku kod można jeszcze bardziej skompresować, zauważając, że sekwencję tę :#:można po prostu zastąpić :.

"a"9>1#\-#,:>#\_@

Wypróbuj online!

W rzeczywistości, za każdym razem, gdy ta sama instrukcja jest powtarzana po obu stronach #polecenia, możesz uprościć to do jednej instrukcji, więc jest to coś, na co powinieneś zawsze zwracać uwagę podczas spłaszczania pętli.

Aby zrozumieć, jak to działa, pomocne może być napisanie sekwencji pętli dwa razy, raz ze wszystkimi znakami po #usuniętym (tj. Co dzieje się podczas wykonywania od lewej do prawej), a raz ze znakami poprzedzającymi #usuniętą (tj. Wykonywanie od prawej do lewej ).

"a"9>1#\-#,:>#\_@
    >1  -  :>  _      ; executing left to right
    >  \  ,:  \_      ; executing right to left

Teraz możesz wyraźnie zobaczyć, jak to pasuje do oryginalnej dwuliniowej wersji kodu.

James Holderness
źródło
3

Dane wyjściowe według kodu wyjścia, jeżeli jest to dozwolona postać wyjściowa. Jeśli wyzwanie wymaga wydrukowania jednego numeru, możesz zapisać bajt, kończąc program qzamiast zamiast.@

pppery
źródło
2
Uwaga: ta wskazówka dotyczy tylko Befunge-98 i nowszych. We wcześniejszych wersjach Befunge qinstrukcja miała inną funkcję (tryb kolejki) lub nie była obsługiwana.
James Holderness
3

W Befunge-93 komenda wprowadzania znaków ( ~) może być często używana jako skrót dla -1, ponieważ jest to wartość zwracana na EOF.

Na przykład poniższy kod wyświetli -1:

~.@

Wypróbuj online!

Nie jest to zalecane w kodzie produkcyjnym, ponieważ podczas działania w środowisku interaktywnym program wstrzymuje się i czeka na dane wejściowe użytkownika. I oczywiście, jeśli użytkownik coś wprowadzi, wynik nie będzie już wynosił -1.

To powiedziawszy, zasada PPCG jest taka, że program może przyjmować pusty strumień wejściowy , i tak zwykle będzie działał na TIO .

Zauważ też, że niekoniecznie jest wykluczone korzystanie z tej sztuczki tylko dlatego, że twój program musi odczytać coś ze strumienia wejściowego. Musisz tylko upewnić się, że przetworzysz swoje dane wejściowe z góry, po czym wszystkie przyszłe zastosowania ~powinny zwrócić -1.

James Holderness
źródło
2

Używaj kierunku IP, gdy masz do czynienia z, _lub |zamiast używać dodatkowego znaku dla !.

Prawdziwy przykład (z tego postu ):

#v~
,>:!#@_

Można zmienić na

#v~
:<,_@#
Justin
źródło
2

Nie zapominaj, że 0knie wykonuje następnej instrukcji. Oznacza to, że zamiast robić:

;some boolean test;!jv;code if false;
       ;code if true;<

Możesz uratować postać, robiąc to

;some boolean test;kv;code if false;
      ;code if true;<
Justin
źródło
Uwaga: ta wskazówka dotyczy tylko Befunge-98 i nowszych. Wcześniejsze wersje Befunge nie obsługiwały kinstrukcji.
James Holderness
1

Nie zapomnij o koperatorze. Zamiast "!dlroW olleH",,,,,,,,,,,,@zrobić "!dlroW olleH"bk,@. Zauważ, że koperacja na komórce, w której się znajduje , 9k,spowoduje wydrukowanie nie 9 razy, ale 10; 9 razy z ki raz z ,.

Justin
źródło
1
Uwaga: ta wskazówka dotyczy tylko Befunge-98 i nowszych. Wcześniejsze wersje Befunge nie obsługiwały kinstrukcji.
James Holderness
1

Kiedy wypychasz małe liczby na stos, prawdopodobnie łatwo zorientujesz się, że 45*dostaniesz cię 20i 67*dostaniesz 42. Jeśli jednak chodzi o większe liczby, naprawdę potrzebujesz programu, który może obliczyć najbardziej wydajną reprezentację dla Ciebie.

Najłatwiejszą opcją jest interfejs online Mike'a Schwörera dla BefunRep . Wystarczy wpisać liczbę, aby wypluł równoważną reprezentację Befunge. Nie zawsze jest najbardziej optymalny, ale jest wystarczająco blisko i prawie na pewno będzie lepszy niż cokolwiek, co można wymyślić ręcznie.

System online jest ograniczony do liczb z zakresu od 0 do 16777215, więc jeśli potrzebujesz czegoś większego, musisz pobrać samodzielne narzędzie BefunRep i samodzielnie wykonać obliczenia.

Jeśli programujesz w Befunge-98, inną opcją do rozważenia jest Fungify . Zasadniczo nie jest to tak optymalne jak BefunRep, ale w przypadku niektórych niższych liczb, gdzie cyfry szesnastkowe i znaki pojedynczych cudzysłowów są najbardziej skuteczne, może czasem dawać lepsze wyniki.

James Holderness
źródło
Pchając małe liczby w Befunge 98, używałbyś '. Np. Dla 42:'*
Justin
@Justin Wspomniałem o tym w ostatnim akapicie, ale sedno tego poradnika polega na tym, że nie musisz znać wielu tych sztuczek do generowania liczb, jeśli po prostu używasz do tego narzędzia.
James Holderness