Wyjaśnienie
Befunge to dwuwymiarowy program, który wykorzystuje stosy .
Oznacza to, że aby zrobić 5 + 6, piszesz 56+
, co oznacza:
56+
5 push 5 into stack
6 push 6 into stack
+ pop the first two items in the stack and add them up, and push the result into stack
(to those of you who do not know stacks, "push" just means add and "pop" just means take off)
Jednak, jak zauważyli twoi inteligentni, nie możemy wepchnąć liczby 56
bezpośrednio na stos.
Aby to zrobić, musimy napisać 78*
zamiast, który mnoży 7
i 8
i popycha produkt na stosie.
Detale
Dane wejściowe mogą być pobierane w dowolnym formacie, co oznacza, że może być STDIN lub nie, według uznania programisty.
Dane wejściowe będą dodatnimi liczbami całkowitymi (bez premii za włączenie 0
lub ujemne liczby całkowite).
Wyjście będzie ciąg składający się tylko z tych znaków: 0123456789+-*/
(I byłoby nie skorzystać %
. Modulo)
Celem jest znalezienie najkrótszego ciągu, który może reprezentować dane wejściowe, przy użyciu formatu opisanego powyżej.
Na przykład, jeśli dane wejściowe to 123
, dane wyjściowe będą 67*99*+
. Dane wyjściowe należy oceniać od lewej do prawej.
Jeśli istnieje więcej niż jeden akceptowalny wynik (np. 99*67*+
Jest również akceptowalny), można wydrukować dowolny z nich (bez premii za wydrukowanie wszystkich).
Dalsze wyjaśnienia
Jeśli nadal nie rozumiesz, jak 67*99*+
oceniać 123
, oto szczegółowe wyjaśnienie.
stack |operation|explanation
67*99*+
[6] 6 push 6 to stack
[6,7] 7 push 7 to stack
[42] * pop two from stack and multiply, then put result to stack
[42,9] 9 push 9 to stack
[42,9,9] 9 push 9 to stack
[42,81] * pop two from stack and multiply, then put result to stack
[123] + pop two from stack and add, then put result to stack
TL; DR
Program musi znaleźć najkrótszy ciąg znaków, który może reprezentować dane wejściowe (liczbę), przy użyciu formatu określonego powyżej.
Notatki
To wyzwanie dla golfa , więc wygrywa najkrótszy kod w bajtach.
Ujednoznacznienie
-
Może być albo x-y
albo y-x
, według uznania programisty. Jednak wybór musi być spójny w ramach rozwiązania. Podobnie w przypadku /
.
Przykładowy program
Lua, 1862 bajtów ( wypróbuj online )
Ponieważ jestem autorem, nie będę go w ogóle grał w golfa.
Wyjaśnienie:
This uses the depth-first search method.
Więcej informacji o wyszukiwaniu w pierwszej kolejności: tutaj .
Program:
local input = (...) or 81
local function div(a,b)
if b == 0 then
return "error"
end
local result = a/b
if result > 0 then
return math.floor(result)
else
return math.ceil(result)
end
end
local function eval(expr)
local stack = {}
for i=1,#expr do
local c = expr:sub(i,i)
if c:match('[0-9]') then
table.insert(stack, tonumber(c))
else
local a = table.remove(stack)
local b = table.remove(stack)
if a and b then
if c == '+' then
table.insert(stack, a+b)
elseif c == '-' then
table.insert(stack, b-a)
elseif c == '*' then
table.insert(stack, a*b)
elseif c == '/' then
local test = div(b,a)
if test == "error" then
return -1
else
table.insert(stack, a+b)
end
end
else
return -1
end
end
end
return table.remove(stack) or -1
end
local samples, temp = {""}, {}
while true do
temp = {}
for i=1,#samples do
local s = samples[i]
table.insert(temp, s..'0')
table.insert(temp, s..'1')
table.insert(temp, s..'2')
table.insert(temp, s..'3')
table.insert(temp, s..'4')
table.insert(temp, s..'5')
table.insert(temp, s..'6')
table.insert(temp, s..'7')
table.insert(temp, s..'8')
table.insert(temp, s..'9')
table.insert(temp, s..'+')
table.insert(temp, s..'-')
table.insert(temp, s..'*')
table.insert(temp, s..'/')
end
for i=1,#temp do
if input == eval(temp[i]) then
print(temp[i])
return
end
end
samples = temp
end
Premia
Ciasto dla Ciebie, jeśli użyjesz Befunge (lub dowolnego jego wariantu) do napisania kodu.
źródło
Odpowiedzi:
Python 2, 278 bajtów
Moje najlepsze rozwiązanie, które za każdym razem daje najkrótszą odpowiedź. (ale bardzo wolno)
Python 2, 437 bajtów
To rozwiązanie jest dłuższe, ale bardzo szybkie (nie brutalna siła). I jestem całkiem pewien, że zawsze zwraca najkrótszy możliwy wynik.
źródło
f(6551)
zwraca25*8*9*7+9*8+
(13 znaków), podczas gdy9999***52*-
(11 znaków) jest lepszy. Zweryfikowano z moją własnąeval
funkcją powyżej (w pytaniu).while c:
;
do oddzielenia przypisań do zmiennych (które zapisują bajty w wciętych blokach), końcówki ven, pozbyć się białych znaków między symbolem i czymkolwiek innym, it
możesz przejść.Perl,
134133132128 bajtówObejmuje +5 za
-Xlp
(2 dodatkowe, ponieważ kod zawiera'
)Uruchom z numerem docelowym na STDIN:
befour.pl
:Nie ma żadnych sztucznych ograniczeń i jest koncepcyjnie dość wydajny, ale mimo to ma straszne czasy działania, mimo że poświęciłem kilka bajtów, aby go przyspieszyć. Wygenerowanie rozwiązania o długości 11 (np. Numer docelowy 6551) zajmuje około 5 godzin w moim systemie.
Poświęcenie 7 dodatkowych bajtów sprawia, że prędkość jest nieco bardziej znośna.
17 minut dla roztworu o długości 11, około 5 godzin dla roztworu o długości 13. Pierwsza liczba, która potrzebuje długości 15, to 16622, co zajmuje około 2 dni. Pierwsza liczba, która potrzebuje długości 17, to 73319.
Zauważ, że zakłada, że dzielenie zwraca liczbę całkowitą przez obcięcie w kierunku 0 (zgodnie ze specyfikacją befunge 93)
źródło
$
uzyskuje dostęp do wartości skalarnej. Gdzie w większości języków piszesza=4
, użyje perl$a=4
. Ale służy również do skalarnego dostępu do bardziej złożonych zmiennych. Np.$a{$b}
Pobiera z skrótu (mapę, słownik)%a
kluczowaną wartość skalarną$b
C,
550545 bajtów550545 bajtów po usunięciu niepotrzebnych nowych linii (wszystkie oprócz trzech nowych linii po dyrektywach wstępnego przetwarzania).@Kenny Lau - Może przyjmować jako dane wejściowe liczbę całkowitą od 1 do 9998, ale myślę, że zakres danych wejściowych, dla których obliczane jest optymalne rozwiązanie, jest mniejszy niż 9998. Z drugiej strony oba zakresy można rozszerzyć, jeśli pamięć pozwala na to.
Program nie może wypchnąć na stos żadnej liczby większej niż 9998. (9998 można zmodyfikować.) Uruchomiłem program w innej wersji, iterując po zewnętrznej pętli (tej z literą k), dopóki istnieje poprawa dla dowolnej liczby od 1 do 9998 (jak w algorytmie Dijkstry). Po trzech iteracjach nie ma poprawy. Aby zaoszczędzić bajty, zapisałem na stałe k = 3.
Aby rozszerzyć zakres, konieczne są dwie rzeczy - zmodyfikowanie stałych 9999 i 9998, uruchomienie go ze zmienną liczbą iteracji w pętli zewnętrznej tak długo, jak długo istnieje poprawa, aby zobaczyć, ile czasu zajmuje, dopóki nie nastąpi poprawa, a następnie zmodyfikuj stałą k = 3 na tę wartość.
źródło
i
,j
ik
przedmain()
.Python 2, 284 bajtów
Zrzeczenie się: Trochę wariuje na zawsze dla niektórych wartości ... ale należy zagwarantować, że zawsze zwróci najkrótszy ciąg i nie ma sztucznie narzuconego ograniczenia zasięgu ... działa nawet na wartości ujemne. :)
Algorytm:
i = 0
i
i wymienićabcd
z+-*/
odpowiednio i usuńef
i
i spróbuj ponownie.źródło
f(i)
od0 <= i <= 6551
(aby uchwycić6551
wartość użyty do unieważnienia @pbochniak „s oryginalnego dokumentu). W tej chwili działa tylko przez kilka minut, a oto ostatnie wyjście z testu:91 : 49+7* 3.020 s (total 108.174 s, worst 89: 5.827 s)
Aktualizacja - właśnie zakończyło się wartością 92:92 : 149+7*+ 258.761 s (total 366.935 s, worst 92: 258.761 s)
113
... zobacz pełny wynik testu tutaj (pastebin), jeśli jesteś zainteresowany ...Python 2, 182 bajty
Tak nieprzyzwoicie powolny, że pozostawiłem go działający przez godzinę na wejściu
221
i nadal się nie skończył. Duża część powolności polega na tym, że używam listy jako kolejki do pierwszego wyszukiwania szerokości i.pop(0)
dotyczy onaO(n)
list.L
to tylko kolejka zawierająca(stack, code to reach stack)
pary. Na każdym etapie cyfry są zawsze dodawane, a operatory są wykonywane, jeśli stos zawiera co najmniej dwa elementy. Podział jest wykonywany tylko wtedy, gdy ostatni element nie jest równy 0, chociaż mam silne podejrzenie, że podział nigdy nie jest konieczny (chociaż nie mam możliwości, aby to udowodnić, ale sprawdziłem, że tak jest w przypadku 500).Program kończy się
NameError
po wydrukowaniu wyniku (ewentualnie).źródło
;E
robi na końcu?NameError
do rozwiązania, ponieważE
nie jest zdefiniowane nigdzie indziejCJam, 79
Wypróbuj online
Jest to okropnie nieefektywne, ale biorąc pod uwagę wystarczającą pamięć i czas, w końcu działa. 123 zabrakło pamięci z 16 GB, ale 120 i 125 są w porządku.
źródło
Pyth - 35 bajtów
Brutalna siła. Dziwną rzeczą jest to, że tak naprawdę nowy domniemany wkład boli mój wynik, ponieważ wydaje się, że działa
.v
również dla pyth_eval.Wypróbuj online tutaj .
źródło
Python 3, 183 bajtów
Prędkość nie jest całkowicie nierozsądna (123, 221, 1237, 6551 kończy się w kolejności sekund lub minut). Zmiana
if
instrukcji w celuif j<=i and <k<2*n
przyspieszenia jej jeszcze bardziej kosztem 9 bajtów więcej. Pominąłem div (/
), ponieważ nie widzę, jak byłoby to potrzebne.źródło