Jest to wyzwanie polegające na kodzie golfowym, w ramach którego musisz opracować program, który działa jak quine lub quine, która modyfikuje się w celu zilustrowania uczenia maszynowego.
tło
Jest to podstawowy program sztucznej inteligencji o nazwie „gra łuskowiec”, który jest opisany tutaj . Podstawowe pomysły są takie, że program przy pierwszym uruchomieniu pyta:
OK, proszę coś wymyślić
Czy to łuskowiec?
Następnie możesz odpowiedzieć:
tak
W takim przypadku jest napisane:
Dobry. To było takie proste.
A jeśli nie, to mówi:
O. Więc wygrywasz - o czym myślałeś?
Do czego możesz powiedzieć:
pies
Do czego by to powiedział
Zadaj mi pytanie dotyczące psa, bym mógł odróżnić psa od łuskowca
możesz odpowiedzieć
Czy to je mrówki?
Następnie zapytałby:
Jaka jest odpowiedź dla psa?
Do czego byś powiedział
Nie
I to by powiedziało
Dzięki
Następnym razem, gdy uruchomi się, zadaje powyższe pytanie i tworzy binarne drzewo takich pytań.
Wyzwanie
Dosyć tła. Wyzwanie polega na napisaniu samomodyfikującego się programu łuskowca. Reguły są następujące:
Wyjście programu (jak opisano powyżej) powinno być
STDERR
. Ostateczna odpowiedź zawsze brzmi: „Dobrze. To było takie proste”. lub „Dzięki”. Następnie powinien wypisać bieżącą wersję programu lub nową wersję programu, która zawiera pytanieSTDOUT
. Żadna odpowiedź napisana w języku, który nie obsługuje pisaniaSTDOUT
iSTDERR
czytania z,STDIN
będzie ważna.Innymi słowy w systemie UNIX można wywołać program w następujący sposób:
przykład:
$ mylanguage myprogram > myprogram.1
[dialog goes here]
$ mylanguage myprogram1 > myprogram.2
[dialog goes here]
- Program musi używać dokładnie podanych podpowiedzi (ponieważ skrócenie podpowiedzi nie pokazuje umiejętności). Podpowiedzi to (bez cudzysłowów i gdzie% s jest podstawiony) w następujący sposób:
lista:
"OK, please think of something"
"Is it %s?"
"Good. That was soooo easy."
"Oh. Well you win then -- What were you thinking of?"
"Please give me a question about %s, so I can tell the difference between %s and %s"
"What is the answer for %s?"
"Thanks"
Kiedy tak / nie oczekując odpowiedzi, Twój program powinien przyjąć
y
lubyes
w każdym razie na „tak”, in
czyno
w każdym razie na „nie”. To, co zrobisz z niezgodnymi danymi wejściowymi, zależy od Ciebie. Na przykład możesz zdecydować się na odpowiedź, która zaczyna się na „tak”y
lubY
„tak”, a wszystko inne na „nie”.Możesz założyć, że nazwy dostarczonych rzeczy i pytań składają się tylko z liter ASCII, cyfr, spacji, łączników, znaków zapytania, przecinków, kropek, dwukropków i średników, tzn
^[-?,.;: a-zA-Z]+$
. Pasują one do wyrażenia regularnego . Jeśli potrafisz sobie z tym poradzić (zwłaszcza cytowane znaki w wybranym języku), możesz być zadowolony z siebie, ale nie zdobywaj żadnych dodatkowych punktów.Twój program nie może odczytać lub zapisać dowolny plik (z wyjątkiem
STDIN
,STDOUT
iSTDERR
), lub z sieci; w szczególności nie może czytać ani zapisywać własnego kodu z dysku. Jego stan należy zapisać w samym kodzie programu.Kiedy program jest uruchomiony i poprawnie zgaduje odpowiedź, musi działać dokładnie tak, jak quine, tj. Musi pisać
STDOUT
dokładnie do własnego kodu, bez zmian.Gdy program jest uruchamiany i niepoprawnie zgaduje odpowiedź, musi zakodować podane nowe pytanie i odpowiedź w swoim własnym kodzie i zapisać go
STDOUT
we własnym kodzie, aby był w stanie rozróżnić pierwotne przypuszczenie i podany nowy obiekt w dodatek do rozróżnienia wszystkich wcześniej podanych obiektów.Musisz być w stanie poradzić sobie z wieloma sekwencyjnymi uruchomieniami oprogramowania, aby uczyło się ono o wielu obiektach. Zobacz tutaj przykłady wielu przebiegów.
Przebiegi testowe są podane na łączu w głowie (oczywiście obejmujące tylko okno dialogowe
STDIN
iSTDERR
).Standardowe luki są wykluczone.
Odpowiedzi:
Common Lisp,
631576Przykładowa sesja
Nazwij skrypt
pango1.lisp
i uruchom go w następujący sposób (używając SBCL):Kolejna runda, dodając niedźwiedzia:
Dodanie lenistwa (testujemy przypadek, w którym odpowiedź brzmi „nie”):
Testowanie ostatniego pliku:
Uwagi
"Thanks"
, oto jest.(y or n)
, ponieważ używam istniejącejy-or-n-p
funkcji. W razie potrzeby mogę zaktualizować odpowiedź, aby usunąć to wyjście.*QUERY-IO*
strumień poświęcony interakcjom użytkowników, z czego właśnie tu korzystam. Standardowa wydajność i interakcja z użytkownikiem nie psują się, co podąża za duchem pytania IMHO.SAVE-LISP-AND-DIE
byłoby lepszym podejściem w praktyce.Wygenerowana produkcja
Oto ostatni wygenerowany skrypt:
Objaśnienia
Drzewem decyzyjnym może być:
"a pangolin"
który reprezentuje liść.(question if-true if-false)
gdziequestion
jest zamknięte pytanie typu tak / nie ,if-true
iif-false
jest dwoma możliwymi poddrzewami związanymi z pytaniem.U
Funkcja spacery i zwraca się ewentualnie zmodyfikowane drzewo. Każde pytanie zadawane jest kolejno, od korzenia aż do liścia, podczas interakcji z użytkownikiem.Zwrócona wartość dla węzła pośredniego
(Q Y N)
to(Q (U Y) N)
(odpowiednio(Q Y (U N))
), jeśli odpowiedź na pytanieQ
brzmi „ tak” (odpowiednio. Nie ).Zwróconą wartością liścia jest albo sam liść, jeśli program poprawnie odgadł odpowiedź, albo wyrafinowane drzewo, w którym liść jest zastąpiony pytaniem i dwoma możliwymi wynikami, zgodnie z wartościami pobranymi od użytkownika.
Ta część była raczej prosta. Aby wydrukować kod źródłowy, używamy zmiennych czytnika do budowania kodu referencyjnego.
UstawiającSztuką przy użyciu*PRINT-CIRCLE*
na true, unikamy nieskończonej rekurencji podczas ładnego drukowania.WRITE
z:print-circle T
jest to, że funkcja może również zwrócić wartość do REPL, w zależności od tego, czy zapis jest ostatnią formą, a zatem, jeśli REPL nie obsługuje struktur kołowych, tak jak to jest zdefiniowane przez standardową wartość domyślną*PRINT-CIRCLE*
nastąpi nieskończona rekurencja. Musimy tylko upewnić się, że struktura kołowa nie zostanie zwrócona do REPL, dlatego w ostatniej pozycji LET znajduje się NIL. Takie podejście znacznie zmniejsza problem.źródło
(y or n)
jest to wymagane, ale kusi mnie, aby na to pozwolić, ponieważ jest to poprawa.Python 2.7.6,
820728 bajtów(Może działać na różnych wersjach, ale nie jestem pewien)
Cóż, nie jest tak krótki jak odpowiedź Common Lisp, ale oto kod!
źródło
Python 3, 544 bajty
Wypróbuj online!
Pytania / odpowiedzi / odpowiedzi są przechowywane w tablicy, gdzie jeśli tablica przechowuje trzy elementy (np.
['Does it eat ants',['a pangolin'],['a dog']]
), Wówczas otrzymuje odpowiedź na pytanie i powtarza się z zawartością drugiego lub trzeciego elementu, w zależności od odpowiedzi. Gdy dojdzie do tablicy zawierającej tylko jeden element, zadaje pytanie, a ponieważ ma cały kod źródłowy jako ciąg, może użyć metody split-join do wstawienia rozszerzenia do tablicy w celu dodania nowej gałęzi .Oryginalnie napisałem to, nie zdając sobie sprawy z wymogu quine, więc ponowne przeczytanie pytania i znalezienie sposobu, w którym mógłbym zarówno wykonać kod, jak i użyć go jako łańcucha, było trudne, ale ostatecznie natknąłem się na pomysł ładnego, rozszerzalnego formatu quine:
źródło
Python 3 , 497 bajtów
Całkiem podobna do nieszkodliwej odpowiedzi na reprezentację drzewa. Rekurencyjnie zadaje następne pytanie, wchodząc głębiej w listę, dopóki nie ma tylko jednej odpowiedzi.
Wersja bez golfa (bez quitingu)
źródło