Richard Dawkins w swojej książce The Blind Watchmaker opisuje program łasicy . Algorytm można opisać następująco:
Zacznij od losowego ciągu 28 znaków. Prawidłowe znaki to wielkie litery i spacja.
Wykonaj 100 kopii tego ciągu, z 5% szansą na znak tej postaci zamienioną na postać losową.
Porównaj każdy nowy ciąg znaków z celem „METHINKS IT JEST JAK WEASEL” i nadaj każdemu wynik według liczby liter w ciągu, które są prawidłowe i znajdują się we właściwej pozycji.
Jeśli którykolwiek z nowych ciągów ma doskonały wynik (28), zatrzymaj się.
Wybierz strunę o najwyższym wyniku z kroku 3. To, jak wypracujesz remis, zależy od Ciebie, ale możesz wybrać tylko jeden ciąg. Weź wybrany ciąg i przejdź do kroku 2.
Zwycięzca zostanie najkrótszym fragmentem kodu, aby uzyskać poprawną odpowiedź podczas drukowania ciągu o najwyższym wyniku każdego pokolenia w następującym formacie:
Gdyby ludzie mogli pomóc poprzez sprawdzenie innych ludzi, odpowiedzi byłyby bardzo pomocne!
Odpowiedzi:
APL (143)
Wyjaśnienie:
0{
...}⊃∘(C←27↑⎕A)¨?28/27
: ustawC
na pierwsze 27 wielkich liter. Jest tylko 26, więc 27 element będzie przestrzenią. Wybierz 28 losowych elementów zC
. To będzie pierwszy⍵
. Pierwsza⍺
(generacja) będzie0
.⍵≢T←'METHINKS IT IS LIKE A WEASEL
: ustawionyT
na ciąg'METHINKS IT IS LIKE A WEASEL'
. Dopóki⍵
nie jest równyT
:{
...}¨100⍴⊂⍵
: Wykonaj 100 kopii⍵
. Dla każdego z tych ...9≠?28/20
: wybierz 28 liczb losowych od 1 do 20. Utwórz maskę bitową, gdzie każda1
oznacza, że liczba losowa nie była równa9
. (Oznacza to 5% szansy na a0
).⍵{⍵:⍺⋄C[?27]}¨
: dla każdej litery w⍵
, jeśli odpowiedni bit był1
, zachowaj tę literę, w przeciwnym razie zastąp ją losowo wybranym elementem zC
.c←
: przechowuj 100 zmutowanych ciągów wc
.G←{+/⍵=T}¨c
: dla każdego elementu wc
oblicz wynik (liczbę pasujących znakówT
) i zapisz wyniki wG
.s←⌈/G
: znajdź maksymalny wynik i zapisz go ws
.c←⊃c/⍨G=s
: wybierz pierwszy element,c
którego wynik jest równys
(maksimum), i zapisz goc
ponownie.⎕←(⍕⍺),':'c'-- score:',s
: wydrukuj generację w podanym formacie (⍺
jest bieżącą generacją,c
jest bieżącym najlepszym ciągiem,s
jest wynikiem)c∇⍨1+⍺
: Zwiększ generowanie i ponownie uruchom mutację, używając bieżącego najlepszego ciągu (c
) jako danych wejściowych.źródło
Mathematica -
238236225Przykładowe dane wyjściowe
źródło
Python (273)
źródło
K
173167/
źródło
Python: 282 znaków bez średników
278 z:
źródło
JavaScript,
277246(wymaga obsługi funkcji strzałek; dodawanie wcięć tylko dla czytelności)
Krępuj się zmienić
alert
, abyconsole.log
jeśli chcesz bardziej przyjemne doświadczenie wykonania.Jest tu kilka fajnych golfowych kawałków:
Funkcja
c
zwraca losowy znak z ciągu alfabetu" ABC..."
. Funkcja przyjmuje argument, aby użyć jej jako górnej granicy losowego wyboru indeksu. Podczas generowania ciągu podstawowego używamy27
, więc funkcja zachowuje się normalnie.Jednak nadużywamy tego zachowania, prosząc o losową górną granicę 540 cali
h = c(540) || h
. Tylko 5% czasuc
faktycznie zwraca ciąg znaków (ponieważ 540 * .05 = 27); w pozostałych 95% przypadków losowo wybrany indeks wykracza poza długość łańcucha, więc funkcja powracaundefined
. Ta wartość falsey powoduje logiczną kaskadę ORc(540) || h
, więc używana jest pierwotnamap
wartośćh
(tzn. Nie występuje zamiana).Czy operacja wynik-zsumowanie
f+=h=="METHINKS IT IS LIKE A WEASEL"[p]
, który mówi „dodajtrue
dof
jeżeli obecnymap
charakterh
odpowiadap
th znak łańcucha Weasel”. Dodanie liczby plus wartość logiczna wymusza wynik boolowski na jeden0
lub1
, co oznacza, żef
jest zwiększany tylko wtedy, gdy występuje dopasowanie do docelowego ciągu WEASEL.źródło
v
podano w kodzie? Nigdzie indziej tam nie ma wzmianki. Możesz zapisać sobie 2 znaki.v
jest argument do funkcji strzałki przechowywanej wc
:c = (v => ...)
. Jeśli chcesz zdefiniować funkcję strzałki bez argumentów, kosztuje ona dwa znaki()=>...
zamiast jednegov=>...
, więc lepiej po prostu mieć nieużywany argument.k=s=[28]
i++
nie miałem pojęcia!R (
245239238 znaków)Daje:
...
źródło
0: ...
jeśli przy pierwszym wywołaniucat
zwiększasz jąc
do 1? (+1 jednak próbuję od godziny zrobić coś krótszego, a ja wciąż nie mogę :))ifelse(…,h(f,1),…)
zastępuje wszystkie wybrane pozycje tym samym losowym char. Możesz interpretować reguły w tym kierunku, ale wydaje mi się, że je zginasz, więc przynajmniej o tym wspomnę. Po drugie, zamieniaszs=z
w1:100
pętli, więc nie tworzysz 100 kopii tego samego łańcucha, ale czasami kopiujesz kopię. Wydaje mi się, że to łamanie reguły, a nie tylko jej naginanie.C 256
Proste trzy pętle, inicjalizacja, generowanie nowych ciągów od rodzica i wynik obliczony na podstawie tej samej instrukcji. Nie jest to zbyt czytelne nawet przy wcięciach.
C 252
Jedna pętla, z jedną tablicą zawierającą wszystkie 101 ciągów.
Ta druga wersja łamie reguły, ponieważ drukuje ciąg z (odpowiednik) kroku 1, ale to był ten ostatni wydruk lub nie. Jestem zaskoczony, jak to naprawić bez eksplozji wielkości. Mimo to wysyłam to dla inspiracji.
C 256
Inne podejście, zamiast tworzenia tablicy do przechowywania 101 łańcuchów, wystarczy zregenerować łańcuch 100 razy i użyć przypisania struktury dla łatwego kopiowania. Inicjalizacja odbywa się poprzez uruchomienie licznika „powtórz 100 razy” przy -1 i ostrożne obchodzenie się z nim poprzez strategicznie wybrany przyrost. Pomimo zupełnie innego podejścia kończy się dokładnie tak samo jak pierwsza próba - 256 znaków.
źródło
C # - 436
źródło
Lua 5.1 (502)
Wersja zminimalizowana:
i łatwiejsza do odczytania wersja (z komentarzami!):
Szczerze mówiąc, nawet jeśli to na pewno nie wygra, cieszyłem się, że udało mi się znaleźć i zminimalizować dość krótkie rozwiązanie tego problemu! (nacisk na racjonalnie): s
źródło
SAS - 374
->
Ze znakami podziału / wcięcia / komentarzy:
źródło
C
361331Nie tak dobre jak rozwiązanie Art, ale oto moja (nowa) próba rozwiązania C. 361 znaków, jeśli usuniesz znaki nowej linii i tabulatory.
Edycja: Pozbyłem się zagnieżdżonej pętli i użyłem tablicy 1D. Miałem nadzieję, że zrobi to większą różnicę, ale uratowało mi to tylko 30 postaci. Oto kod:
Edycja: Jest to oryginalny, nie golfowy kod, dla tych, którzy są zainteresowani wiedzą, w jaki sposób „golf” został zrobiony. Kod nie generuje ostrzeżeń po kompilacji z GCC z włączoną opcją -Wall i C99. Może jesteś początkującym golfistą, takim jak ja, lub początkującym C, jak ja, a może jesteś po prostu ciekawy. :) https://gist.github.com/cpx/97edbce4db3cb30c306a
źródło
Scala,
347341337 znaków:=>
źródło
println("%2d: %s -- score: %d".format(i,a,s(a))
można zmienić naprintln(f"$i%2d: $a%s -- score: ${s(a)}%d")
, zapisując 4 znaki!def c=(' '+:('A'to'Z'))(r(27))
daje mierror: type mismatch; found : Int required: scala.collection.generic.CanBuildFrom[scala.collection.immutable.IndexedSeq[Char],Char,?]
PHP 442
Readbly:
źródło
if\for
, jest na 436. można również sprawdzić$n>90
inny znakr()
is()
funkcji. Oto zmiany z komentarzami: ideone.com/4ecZQc%s
jest zawsze tej samej długości i%d
jest wyrównana do lewej, dlatego można zamiast tego użyć następujących opcji:printf("%2d: $s -- score: $l\n",$i);
Java (632)
Java to taki pełny język ... :(
źródło
Python (
330321)Wersja do odczytu:
Przykładowe dane wyjściowe:
edycja: usunięto kilka znaków na podstawie odpowiedzi AMK i Timtechs
źródło
sum(1for c in range(28)if n[c]==t[c])
może zostać skrócony dosum(n[c]==t[c] for c in range(28))
(-3 znaków)import random as r
w celufrom random import*
, a następnie usunąć trzech wystąpieńr.
S
? Wyzwanie wymaga rozpoczęcia od ciągu losowych postaci.PHP (
381 397 323 319312):Wersja do odczytu:
Kredyty optymalizacyjne (319):
Kredyty optymalizacyjne (312):
źródło
for
w$f=N;while($f--){
ciągu 3 char każdego. i dla innego char:$n=rand(0,26);[...]chr($n?$n+64:32)
Ruby, 218
przykładowy bieg
źródło
Ruby -
225202203198 znakówRuby wydaje się być niedostatecznie reprezentowana w tym wyzwaniu, więc pomyślałem, że spróbuję! Ulepszenia mile widziane.
źródło
1
ale pytanie określa0
. Jeśli inicjujesz,g=-1
to jest w porządku. Może być mądrzejszy sposób, ale zrobiłem to w ten sposób. Pozdrawiam, RubyGolfer.puts"#{g+=1}: #{$.,s=(0..99).map{n=(r=0..27).map{|i|x=[' ',*?A..?Z].sample;rand<0.05?x:s[i]||=x};[r.count{|i|n[i]=='METHINKS IT IS LIKE A WEASEL'[i]},n*'']}.max;s} -- score: #$."until$.>27
Ruby,
206200199Pierwszy wiersz jest po prostu fantazyjny sposób zdefiniować
q=-2
,i=-1
iR=(0..27).to_a
. Cała praca odbywa się w 2. linii:źródło
Japt v2.0a0,
112108 bajtówWypróbuj online!
-4 bajty dzięki produktom @ETH.
Rozpakowane i jak to działa
źródło
Japt
-R
, 94 bajtyInne podejście, ale z niewielką inspiracją od rozwiązania Bubblera .
Przetestuj (lub wypróbuj online )
Wyjaśnienie
Linia 1
Wynik zostaje przypisany do zmiennej
U
.Linia 2
Wynik zostaje przypisany do zmiennej
V
.Linia 3
Wynik tego wiersza jest domyślnie połączony z nowymi liniami i danymi wyjściowymi.
źródło
Perl 5 , 219 bajtów
Wypróbuj online!
źródło
Rubin - 410
Edycja * Obecnie nie działa (z jakiegoś powodu ustawiono [dowolny] na 0 (type => fixnum)). Jednak rzeczywisty projekt jest prawidłowy, muszę tylko znaleźć błąd, który to spowodował (to bardzo tajemnicze)
źródło
Python 284
źródło
JavaScript - 312
Powyżej jest już krótsze rozwiązanie JS, ale wykorzystuje ono eksperymentalne funkcje wskaźnika, więc pomyślałem, że wrzucę inne rozwiązanie, które działa w dowolnym środowisku JS:
źródło
Java:
557534Nieopakowane:
źródło
PHP
429426421415ładny druk
Następnym razem będę potrzebować mniej pełnego języka
źródło
Python 2.7 - 319 bajtów
Pewnie nie jest to najmniejsze, ale programowanie było fajne.
Używa funkcji rekurencji, więc może osiągnąć maksymalną głębokość rekurencji, jeśli istnieje jakiś dziwny dewolucja z łańcuchem.
Ogromne podziękowania dla Sp3000 za pomoc w grze w golfa.
źródło
Julia, 281 bajtów
Gra w golfa:
Sam algorytm nie jest zbyt sprytny, ale jest tu kilka fajnych elementów. Łącząc szereg znaków z inną postać, a następnie indeksowanie do niego:
['A':'Z',' '][rand(1:27,n)]
a biorąc suma tablicę wartości logiczne (wspólne, ale wciąż kocham ten pomysł)sum(a.=="METHINKS IT IS LIKE A WEASEL".data)
. Cieszę się, że mam mniej niż 300!Nie golfowany:
źródło