Nutzungsbedingungen
Ein Wurm ist eine Liste von nichtnegativen ganzen Zahlen und sein rechtes (dh letztes ) Element heißt head . Wenn der Kopf nicht 0 ist, hat der Wurm ein aktives Segment, das aus dem längsten zusammenhängenden Elementblock besteht, der den Kopf enthält, und dessen Elemente mindestens so groß sind wie der Kopf . Das reduzierte aktive Segment ist das aktive Segment, dessen Kopf um 1 dekrementiert wurde. Beispielsweise hat der Wurm 3 1 2 3 2
ein aktives Segment 2 3 2
und das reduzierte aktive Segment ist 2 3 1
.
Regeln der Evolution
Ein Wurm entwickelt sich Schritt für Schritt wie folgt:
In Schritt t (= 1, 2, 3, ...),
wenn der Kopf 0 ist: lösche den Kopf
sonst: ersetze das aktive Segment durch t + 1 verkettete Kopien des reduzierten aktiven Segments.
Fakt : Jeder Wurm entwickelt sich irgendwann zu einer leeren Liste , und die Anzahl der dazu erforderlichen Schritte ist die Lebensdauer des Wurms .
(Details finden Sie in The Worm Principle , einem Artikel von LD Beklemishev. Die Verwendung von "list" als endliche Sequenz und "head" als letztes Element ist diesem Artikel entnommen - nicht zu verwechseln mit der gebräuchlichen Verwendung für Listen als abstrakten Datentyp , wobei head normalerweise das erste Element bedeutet.)
Beispiele (aktives Segment in Klammern)
Wurm: 0,1
step worm
0(1)
1 0 0 0
2 0 0
3 0
4 <- lifetime = 4
Wurm: 1,0
step worm
1 0
1 (1)
2 0 0 0
3 0 0
4 0
5 <- lifetime = 5
Wurm: 1,1
step worm
(1 1)
1 1 0 1 0
2 1 0(1)
3 1 0 0 0 0 0
4 1 0 0 0 0
5 1 0 0 0
...
8 (1)
9 0 0 0 0 0 0 0 0 0 0
10 0 0 0 0 0 0 0 0 0
...
18 0
19 <- lifetime = 19
Wurm: 2
step worm
(2)
1 (1 1)
2 1 0 1 0 1 0
3 1 0 1 0(1)
4 1 0 1 0 0 0 0 0 0
5 1 0 1 0 0 0 0 0
6 1 0 1 0 0 0 0
...
10 1 0(1)
11 1 0 0 0 0 0 0 0 0 0 0 0 0 0
12 1 0 0 0 0 0 0 0 0 0 0 0 0
...
24 (1)
25 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
...
50 0
51 <- lifetime = 51
Wurm: 2,1
(2 1)
1 2 0 2 0
2 2 0(2)
3 2 0(1 1 1 1)
4 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0
5 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0(1 1 1)
6 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0
7 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0(1 1)
8 2 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0 1 1 0{1 0}^9
...
?? <- lifetime = ??
Wurm: 3
step worm
(3)
1 (2 2)
2 (2 1 2 1 2 1)
3 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0
4 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1(2)
5 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0(2 1 2 1 1 1 1 1 1 1)
6 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0{2 1 2 1 1 1 1 1 1 0}^7
7 2 1 2 1 2 0 2 1 2 1 2 0 2 1 2 1 2 0{2 1 2 1 1 1 1 1 1 0}^6 (2 1 2 1 1 1 1 1 1)
... ...
?? <- lifetime = ??
Beiseite
Worm Lebensdauern liegen typischerweise enorm, wie durch die folgenden unteren Grenzen in Bezug auf die Standard gezeigt schnell wachsenden Hierarchie von Funktionen f α :
worm lower bound on lifetime
---------------- ------------------------------------------
11..10 (k 1s) f_k(2)
2 f_ω(2)
211..1 (k 1s) f_(ω+k)(2)
2121..212 (k 2s) f_(ωk)(2)
22..2 (k 2s) f_(ω^k)(2)
3 f_(ω^ω)(2)
...
n f_(ω^ω^..^ω)(2) (n-1 ωs) > f_(ε_0) (n-1)
Bemerkenswerterweise hat Wurm [3] bereits eine Lebenszeit, die Grahams Zahl bei weitem übertrifft :
f ω ω (2) = f ω 2 (2) = f ω2 (2) = f ω + 2 (2) = f ω + 1 (f ω + 1 (2)) >> f ω + 1 (64) > G.
Code Golf Challenge
Schreiben Sie das kürzestmögliche Funktionsunterprogramm mit folgendem Verhalten:
Eingabe : Beliebiger Wurm.
Ausgabe : Die Lebensdauer des Wurms.Die Codegröße wird in Bytes gemessen.
Hier ist ein Beispiel (Python, Golf auf ca. 167 Bytes):
from itertools import *
def T(w):
w=w[::-1]
t=0
while w:
t+=1
if w[0]:a=list(takewhile(lambda e:e>=w[0],w));a[0]-=1;w=a*(t+1)+w[len(a):]
else:w=w[1:]
return t
Anmerkung : Wenn t (n) die Lebensdauer des Wurms [n] ist, entspricht die Wachstumsrate von t (n) in etwa der der Goodstein-Funktion . Also , wenn diese auf unter 100 Bytes golfed werden, könnte es auch eine Gewinn Antwort auf die gibt größte Zahl Druck Frage . (Für diese Antwort könnte die Wachstumsrate erheblich beschleunigt werden, indem der Schrittzähler immer bei n gestartet wird - dem gleichen Wert wie der Wurm [n] - anstatt bei 0.)
w[0]
das * am weitesten links stehende Element dieser Liste?2 1
vielleicht zu viel in einer angemessenen Zeit zu fragen, aber ein nützlicher Test ist , dass die Sequenz beginnen sollte(2 1)
,2 0 2 0
,2 0 (2)
,2 0 (1 1 1 1)
, ...Antworten:
GolfScript (
5654 Zeichen)Online-Demo
Ich denke, dass der Schlüsseltrick hier wahrscheinlich darin besteht, den Wurm in umgekehrter Reihenfolge zu halten. Das bedeutet, dass es ziemlich kompakt ist, die Länge des aktiven Segments zu finden:
.0+.({<}+??
(wobei das0
als Schutz hinzugefügt wird, um sicherzustellen, dass wir ein Element finden, das kleiner als der Kopf ist).Nebenbei eine Analyse der Wurmlebensdauer. Ich bezeichne den Wurm als
age, head tail
(dh in umgekehrter Reihenfolge von der Notation der Frage) mit Exponenten, um Wiederholungen in Kopf und Schwanz anzuzeigen: zB2^3
ist2 2 2
.Lemma : Für jedes aktive Segment
xs
gibt es einef_xs
solche Funktion ,age, xs 0 tail
die sich in verwandeltf_xs(age), tail
.Beweis: Kein aktives Segment kann jemals ein enthalten
0
, so dass das Alter bis zu dem Zeitpunkt, an dem wir alles löschen, bevor der Schwanz unabhängig vom Schwanz ist und daher nur eine Funktion von istxs
.Lemma : Für jedes aktive Segment stirbt
xs
der Wurmage, xs
im Alterf_xs(age) - 1
.Beweis:
age, xs 0
verwandelt sich nach dem vorhergehenden Lemma inf_xs(age), []
. Der letzte Schritt ist das Löschen davon0
, das vorher nicht berührt wurde, weil es niemals Teil eines aktiven Segments sein kann.Mit diesen beiden Lemmata können wir einige einfache aktive Segmente untersuchen.
Für
n > 0
,also
f_{1^n} = x -> f_{1^{n-1}}^{x+1}(x+2)
(mit basis fallf_{[]} = x -> x+1
, oder wenn sie es vorziehenf_{1} = x -> 2x+3
). Wir sehen,f_{1^n}(x) ~ A(n+1, x)
woA
ist die Ackermann-Péter-Funktion.Das ist genug, um einen Überblick zu bekommen
1 2
(2 1
in der Notation der Frage):Wenn
2 1
wir also Input haben, erwarten wir Output ~A(A(5,4), A(5,4))
.und ich kann wirklich verstehen, warum diese Funktion so wahnsinnig wächst.
quelle
9{-1%0\{\)\.0={.0+.({<}+??\((\+.@<2$*\+}{(;}if.}do;}:L~
die Lebensdauer des Wurms [9], die weit über Grahams Zahl liegt - und das kann sein weiter golfen.GolfScript,
6962 ZeichenDie Funktion
C
erwartet den Wurm auf dem Stapel und ersetzt ihn durch das Ergebnis.Beispiele:
quelle
*
und^
nicht als arithmetische Operatoren für multiplizieren verwendet werden und potenzieren. Natürlich, wenn Sie dort Ihre eigene (zweifellos überlegene) Antwort einreichen möchten, werde ich meine gerne entfernen.Ruby - 131 Zeichen
Ich weiß, dass dies nicht mit den oben genannten GolfScript-Lösungen mithalten kann, und ich bin mir ziemlich sicher, dass hierdurch eine Punktzahl oder mehr Zeichen reduziert werden können, aber ehrlich gesagt bin ich froh, dass ich das Problem ungolfed lösen konnte. Tolles Puzzle!
Meine Pre-Golf-Lösung, von der das oben Genannte abgeleitet ist:
quelle
if foo==0
kann auf getrimmt werdenif foo<1
. Das kann Ihnen hier einen Charakter ersparen.reverse
.else
Klausel auf eine Zeile reduzieren und sie dannif..else..end
durch eine ternäre Anweisung ersetzen kann. Ich könnte auch ein Lambda verwenden, um ein paar Zeichen zu speichern, denke ich.Sclipting (43 Zeichen)
Dies erwartet die Eingabe als durch Leerzeichen getrennte Liste. Dies gibt die richtige Antwort für
1 1
und2
, aber für2 1
oder aus3
es dauert zu lange, so dass ich es aufgegeben habe, darauf zu warten, dass es fertig ist.Mit Kommentar:
quelle
k (83)
worm:{-1+*({x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}.)/(1;|,/x)}
Dies kann wahrscheinlich weiter ausgenutzt werden, da es nur die Wiederholung ziemlich einfach umsetzt.
Die grundlegende Evolutionsfunktion
{x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}
ist 65 Zeichen und verwendet einige Tricks, um die Erhöhung des Alters zu stoppen, wenn der Wurm stirbt. Der Wrapper zwingt eine Eingabe einer einzelnen Ganzzahl in eine Liste, kehrt die Eingabe um (es ist kürzer, die Wiederholung in Bezug auf einen Wurm zu schreiben, der von Ihrer Notation umgekehrt ist), fragt nach dem Fixpunkt, wählt das Alter als Ausgabe aus und passt das Ergebnis an um das Überschwingen in der letzten Generation zu erklären.Wenn ich den Zwang und die Umkehrung manuell mache, fällt er auf 80 (
{-1+*({x,,(,/((x+:i)#,@[y@&w;(i:~~#y)#0;-1+]),y@&~w:&\~y<*y;1_y)@~*y}.)/(1;x)}
).einige Beispiele:
Leider ist es für Largest Number Printable nur sehr theoretisch sinnvoll, da es recht langsam, auf 64-Bit-Ganzzahlen beschränkt und wahrscheinlich nicht besonders speichereffizient ist.
insbesondere
worm 2 1
undworm 3
nur abwandern (und würde wahrscheinlich'wsfull
(aus dem Gedächtnis) werfen , wenn ich sie weitermachen lasse).quelle
` to switch from
Wenn Sie das haben, starten Sie die REPL, geben Sie q` to eink
und fügen Sie meinen Code ein. Alternativ können Sie meinen Code in einer Datei mit einer.k
Erweiterung speichern und in den Interpreter laden.APL (Dyalog Unicode) , 52 Byte SBCS
7 Bytes dank @ngn und @ Adám gespeichert.
Probieren Sie es online!
Erläuterung:
quelle
Scala, 198
Verwendung:
quelle
K 95
.
quelle
C (gcc) , 396 Bytes
Probieren Sie es online!
Ich weiß, dass ich EXTREM spät zur Party komme, aber ich dachte, ich würde mich in C daran versuchen, was eine Implementierung einer verknüpften Liste erforderte. Abgesehen davon, dass alle Bezeichner in einzelne Zeichen geändert wurden, ist es kein wirkliches Golfspiel, aber es funktioniert!
Alles in allem bin ich ziemlich glücklich, wenn man bedenkt, dass dies das dritte C / C ++ - Programm ist, das ich jemals geschrieben habe.
quelle
Haskell , 84 Bytes
Probieren Sie es online!
Danke an @xnor für zwei Bytes.
Ich bin der Meinung, dass es einen guten Weg geben sollte, das gemeinsame Inkrement herauszufiltern, aber ich habe noch keinen kurzen gefunden.
quelle
n
Sie ihn um 1.(n+1)!
zweimal zu schreiben , sondern meinen Versuch nur zu binden.Perl 5
-pa
, 92 BytesProbieren Sie es online!
quelle
Stax , 31 Bytes
Führen Sie es aus und debuggen Sie es
quelle