Ideen er at holde styr på hvor mange esser, toere, ... konger, der er tilbage.
Det kan skrives med 13 tegn, fx starter vi med 4444444444444, dvs 4 af hver. Hvis vi så tager et enkelt kort, kan vi tage et af de 4 esser, hov vi døde, eller en af de fire toere, eller en af de fire treere, osv
Dvs i generation 1 er mulighederne:
4 x 4344444444444 eller 4 x 4434444444444 eller ....
Det spændende er så om det her eksploderer i hænderne på os eller om man kan finde på en måde at begrænset det på.
Det viser sig at være pænt indenfor det mulige på en standard-pc.
I alt er der 5^13 muligheder fra 4444444444444 til 0000000000000 (for
på hver af de tretten pladser kan der stå 0,1,2,3 eller 4.).
Hvis vi skal holde styr på antallet af måder man kan være havnet i hver enkelt tilstand, så er værste tilfælde 0000000000000, som vi udfra ovenstående simuleringer tror er ca 1,6% af 52! hvilket er ca 70 cifre.
Vi runder generøst op fra 13 tegn + 70 cifre til 100 pr tilstand og vi har 5^13 = ca 1,2 milliard, så 120 gb diskplads ser ud til at være rigeligt.
Undervejs har vi en udfordring med mellemresultater, men det kommer jeg til.
Et lille program kan hurtigt tøffe igennem de 1.2 milliarder muligheder og fordele på de forskellige summer og 26 kort viser sig (ikke så overraskende) at "vinde" med 94309099 mulige måder at nå dertil.
Dvs vi forventer ca 94 millioner linier med ca 100 tegn i hver, som det mellemresultat, der fylder mest. Vi har rundet pænt op undervejs, men lad os sige 5 Gb som et realistisk bud på hvad det koster at huske på alle måder, vores spil kort kan se ud på efter at vi har lagt 26 kort.
Vi er ikke helt i mål, for vi er nødt til at kunne slå dubletter sammen undervejs. Jeg prøver at forklare:
Generation 0 er "4444444444444"x1
Generation 1 er "4344444444444"x4, 4434444444444"x4, osv
Generation 2 er .... "4444444444433"x16, ..... , "4444444444433"x16, ...
Dvs en situation hvor vi har taget en dronning og en konge kan vi få
på 16 måder og vi er jo i samme situation, hvis vi har taget en konge og en dronning, så det er 16 måder mere. De to skal vi have lagt sammen til "4444444444433"x32, hvis ikke filstørrelserne skal eksplodere.
Det nemmeste er at lave to programmer. Det ene laver næste generation og er ligeglad med dubletter. Det næste slår dubletter sammen, men bekymrer sig ikke om andet.
Dubletfjerne-programmet har det nemmest, hvis de enkelte muligheder
kommer i sorteret rækkefølge, mens Næstegeneration-programmet helst ikke vil tænke over det.
Ergo skyder vi bare en sorteringskommando ind imellem, så
her er løsningen:
Næstegeneration (skrevet i perl):
while (<>) {
die unless /^(\d+):([^:]*):(\d+)$/;
$g = $1;
@f = (split(//,$2));
$m = $3;
for $f (0..12) {
next if ($f % 13) == ($g % 13);
if ($f[$f] > 0) {
$f[$f]--;
$ftext = join("",@f);
$f[$f]++;
print "".($g+1).":$ftext:${m}x$f[$f]\n";
}
}
}
Fjerndubletter skrevet i python:
import fileinput
import sys
def printf(fmt, *varargs):
sys.stdout.write(fmt % varargs)
first = 1
lastkey = "NADA"
sum = 0
for line in fileinput.input():
(gen,thiskey,mult) = line.split(":")
(multa,multb) = mult.split("x")
if first == 1:
sum = int(multa) * int(multb)
lastkey = thiskey
first = 0
else:
if thiskey != lastkey:
printf("%s:%s:%s\n",gen,lastkey,sum)
lastkey = thiskey
sum = int(multa) * int(multb)
else:
sum = sum + int(multa) * int(multb)
printf("%s:%s:%s\n",gen,thiskey,sum)
Og så en kommandofil til at sætte skub i tingene:
echo "0:4,4,4,4,4,4,4,4,4,4,4,4,4:1" > 00.g
cat 00.g | perl ng | sort | python simplificer > 01.g
cat 01.g | perl ng | sort | python simplificer > 02.g
cat 02.g | perl ng | sort | python simplificer > 03.g
cat 03.g | perl ng | sort | python simplificer > 04.g
cat 04.g | perl ng | sort | python simplificer > 05.g
cat 05.g | perl ng | sort | python simplificer > 06.g
osv
Efter at røgen har lagt sig, indeholder 52.g så
52:0000000000000:1309302175551177162931045000259922525308763433362019257020678406144
Lidt bemærkninger:
Python blev valgt, fordi den har en rimelig effektiv implementation af lange heltal.
Undervejs er der pænt store mellemresultater.
perl ng 26.g giver ca 60 Gb, inden simplificer skærer det ned til 4,7 Gb
så det må gerne køre på en disk med nogle hundrede gigabytes ledigt.
En enkelt sød ting:
51.g indeholder:
51:0000000000001:106870657266741703846538272785050110260756967966691383236014112768
51:0000000000010:109108514629264763577587083354993543775730286113501604751723200512
51:0000000000100:109108514629264763577587083354993543775730286113501604751723200512
51:0000000001000:109108514629264763577587083354993543775730286113501604751723200512
51:0000000010000:109108514629264763577587083354993543775730286113501604751723200512
51:0000000100000:109108514629264763577587083354993543775730286113501604751723200512
51:0000001000000:109108514629264763577587083354993543775730286113501604751723200512
51:0000010000000:109108514629264763577587083354993543775730286113501604751723200512
51:0000100000000:109108514629264763577587083354993543775730286113501604751723200512
51:0001000000000:109108514629264763577587083354993543775730286113501604751723200512
51:0010000000000:109108514629264763577587083354993543775730286113501604751723200512
51:0100000000000:109108514629264763577587083354993543775730286113501604751723200512
51:1000000000000:109108514629264763577587083354993543775730286113501604751723200512
Dvs sandsynligheden for at sidste kort er en konge er lidt mindre end sandsynligheden for at det er fx en toer.