[Kluring] Hitta en binär sträng i en "sorterad" lista av 2^64 strängar (prog)
Drygt ett år sedan postade jag två "hitta ordet i listan"-problem. Här kommer ett nytt liknande problem som jag dock formulerar i sifferspråk.
Introduktion:
Låt säga att man tagit de binära strängarna av längd 4 och skrivit ut dem i numerisk storleksordning
0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111, 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111
Här är alltså 0101 den 5:e strängen i listan. (Vi räknar från 0!) Av någon anledning vill man istället sortera dem så att talen med minst antal ettor i representationen kommer före de med fler ettor, men att talen med lika många ettor är sorterade i numerisk storleksordning relativt varandra
0000, 0001, 0010, 0100, 1000, 0011, 0101, 0110, 1001, 1010, 1100, 0111, 1011, 1101, 1110, 1111
Här är alltså 0011 det 5:e talet. Låt oss kalla detta "siffersortering".
Problemet:
Låt säga att man skulle siffersorterar alla binära strängar av längd 64. Vilken vore då den 10402927437586948002:a strängen som förekommer i listan?
När du har funnit strängen konvertera den till decimalt och presentera det som svaret
[Har vi båda gjort rätt så känner du igen talet]
((Notera att 0000000000000000000000000000000000000000000000000000000000000000 är den 0:e strängen och 0000000000000000000000000000000000000000000000000000000000000001 är den 1:a strängen. ))
Jag såg att detta var olöst, och så kan vi ju inte ha det, så jag spenderade eftermiddagen med att programmera mig fram till lösningen på detta.
Det enda programmeringsspråket jag är bekant med är Java, vars system för att göra aritmetik med stora tal är ganska krångligt, så jag tänkte att jag kanske skulle ge en förklaring av mitt tillvägagångssätt snarare än att bara visa min kod.
Det första att ta itu med är att klura ut hur många ettor talet innehåller. Jag resonerade mig fram till att det finns tal med ettor, tal med etta, o.s.v. (Man kan ju se det som att man väljer ut ett visst antal av siffror till att vara ettor.). Det betyder att talen med ettor börjar på index , talen med etta börjar på index , talen med på o.s.v. Med datorhjälp kommer man fram till att talen med ettor börjar på och talen med ettor börjar på . Det :a talet måste därför ha ettor.
Om man utför subtraktionen (vårt index minus indexet där talen med ettor börjar) finner vi att vi söker det :e talet med ettor (räkningen börjar på noll). Jag tänker nu att vi gör en ny lista med bara talen med ettor.
Nästa steg var att klura ut hur många av talen med ettor som börjar på noll. Då tänkte jag som så att vi fixerar den första nollan, och har därför val för övriga siffror, vilket enligt multiplikationsprincipen ger att av talen som har ettor börjar på noll.
Alltså börjar de första talen på , och eftersom är den första siffran i vårt tal noll. Vi kan nu göra ett liknande resonemang för den andra siffran. Man ser att av talen som börjar på noll även har noll som andra siffra. Eftersom får vi att den andra siffran i vårt tal är noll. Proceduren upprepas, och den enda skillnaden ifall vi skulle få en etta (d.v.s. indexet är större än eller lika med binomialkoefficienten) är att indexet då måste justeras till nästa gång genom att subtrahera binomialkoefficienten (ettorna kommer ju efter nollorna).
Man får då till slut att den binära strängen är:
vilket i det decimala systemet blir:
men detta mystiska tal känner jag inte igen.
(Dock finns det ett välkänt tal som är ganska precist en -del så stort :-))
Snyggt jobbat och väl förklarat Alvin.