De Canadees Jeff Widderich ontwierp deze puzzel in 2007. Het doel is om in elke witte cel een cijfer tussen 1 en 9 in te vullen, zodat elk getal in het kruiswoordraadsel een straat vormt — een reeks opeenvolgende cijfers die in willekeurige volgorde mogen staan. Zo mag je op de bovenste rij van deze puzzel bijvoorbeeld de 5 cijfers 96587 invullen, maar niet 91548.
Er is nog een andere beperking: elk cijfer tussen 1 en 9 mag hoogstens één keer voorkomen op elke rij en op elke kolom. Dat betekent bijvoorbeeld dat elk van de twee lange verticale getallen alle negen cijfers zal bevatten. De cijfers in de zwart gekleurde cellen tellen mee voor deze beperking — de 9 in de zwarte cel dicht bij het midden betekent dat er in die rij en kolom geen andere 9 meer mag voorkomen. De unieke oplossing van bovenstaande opgave ziet er dan als volgt uit.
Het rooster van een str8ts puzzel bestaat steeds uit 9 rijen en 9 kolommen. Om de posities van de cellen in het rooster te kunnen aanduiden, worden de rijen (resp. de kolommen) van boven naar onder (resp. van links naar rechts) genummerd vanaf nul.
Een cel in het rooster van een str8ts puzzel heeft twee onafhankelijke eigenschappen. De cel is al dan niet zwart gekleurd en de cel bevat al dan niet een cijfer. Om het rooster compact te kunnen voorstellen, wordt de combinatie van deze twee eigenschappen gecodeerd als één enkel karakter volgens dit schema:
cijfer | geen cijfer | |
---|---|---|
niet gekleurd (wit) | een cijfer (1–9) | een punt (.) |
wel gekleurd (zwart) | een letter (A–I) | een hekje (#) |
Zo wordt een witte cel die het cijfer 3 bevat gecodeerd als 3 en een zwarte cel die het cijfer 3 bevat als C (de derde letter van het alfabet). Een witte cel zonder cijfer wordt voorgesteld door een punt (.) en een zwarte cel zonder cijfer door een hekje (#). Op die manier kan de opgave van de voorbeeldpuzzel met de volgende roostervorm voorgesteld worden:
##..5..C# .6..##1.. ...#H.... 9..D...#E #....3..# ##...I.4. 4.3.##.6. ..1##.... ##8....#B
Definieer een klasse Cel waarmee cellen in het rooster van een str8ts puzzel kunnen voorgesteld worden. Bij het aanmaken van een nieuwe cel (Cel) moet het karakter (String) doorgegeven worden dat de twee eigenschappen van de cel codeert. Als het argument geen karakter is dat de toestand van een cel codeert, dan moet een Error opgeworpen worden met de boodschap ongeldig symbool. Zorg ervoor dat je op een cel $$c$$ (Cel) minstens de volgende methoden kunt aanroepen:
Een methode toString (zonder argumenten) die het karakter (String) teruggeeft dat de twee eigenschappen van de cel $$c$$ codeert.
Een methode isGekleurd (zonder argumenten) die een Booleaanse waarde (Boolean) teruggeeft, die aangeeft of cel $$c$$ (zwart) gekleurd is.
Een methode cijfer (zonder argumenten) die het cijfer (Number) uit de cel $$c$$ teruggeeft, of de waarde null als cel $$c$$ geen cijfer bevat.
Definieer een functie isStraat waaraan een getal $$n \in \mathbb{N}$$ (Number) moet doorgegeven worden. De functie moet een Booleaanse waarde (Boolean) teruggeven, die aangeeft of $$n$$ een straat is. Dat is het geval als de cijfers van het getal in een opeenvolgende reeks kunnen gezet worden en als het cijfer nul (0) niet voorkomt in het getal.
Definieer een klasse Str8ts waarmee het rooster van een str8ts puzzel kan voorgesteld en ingevuld worden. Bij het aanmaken van een nieuwe puzzel (Str8ts) moet een reeks (Array) doorgegeven worden met de negen rijen (String) uit de roostervorm van de puzzel (opgelijst van boven naar onder). Je mag ervan uitgaan dat het argument de correcte roostervorm van een puzzel beschrijft, zonder dat dit expliciet moet gecontroleerd worden. Zorg ervoor dat je op een puzzel $$p$$ (Str8ts) minstens de volgende methoden kunt aanroepen:
Een methode toString (zonder argumenten) die de roostervorm (String) van puzzel $$p$$ teruggeeft, waarin sinds het aanmaken al extra cijfers kunnen ingevuld zijn in de witten cellen. Daarbij worden de cellen van het rooster voorgesteld door het karakter dat de combinatie van hun twee eigenschappen voorstelt.
Een methode horizontaalGetallen waaraan het nummer $$r$$ (Number) van een rij in het rooster van puzzel $$p$$ moet doorgegeven worden. De methode moet een afbeelding (Map) teruggeven die het nummer (Number) van elke kolom waar het eerste cijfer van een getal moet ingevuld worden (witte cellen) in rij $$r$$ afbeeldt op het patroon (String) dat aangeeft welke cellen van dat getal reeds ingevuld werden: een cijfer voor de ingevulde cellen en een punt voor de cellen die nog niet ingevuld werden.
Een methode verticaalGetallen waaraan het nummer $$k$$ (Number) van een kolom in het rooster van puzzel $$p$$ moet doorgegeven worden. De methode moet een afbeelding (Map) teruggeven die het nummer (Number) van elke rij waar het eerste cijfer van een getal moet ingevuld worden (witte cellen) in kolom $$k$$ afbeeldt op het patroon (String) dat aangeeft welke cellen van dat getal reeds ingevuld werden: een cijfer voor de ingevulde cellen en een punt voor de cellen die nog niet ingevuld werden.
Een methode horizontaalCijfers waaraan het nummer $$r$$ (Number) van een rij in het rooster van puzzel $$p$$ moet doorgegeven worden. De methode moet een verzameling (Set) teruggeven met alle cijfers (Number) die reeds ingevuld werden op rij $$r$$ (zowel in de witte als in de zwarte cellen).
Een methode verticaalCijfers waaraan het nummer $$k$$ (Number) van een kolom in het rooster van puzzel $$p$$ moet doorgegeven worden. De methode moet een verzameling (Set) teruggeven met alle cijfers (Number) die reeds ingevuld werden op kolom $$k$$ (zowel in de witte als in de zwarte cellen).
Een methode horizontaalInvullen waaraan drie argumenten moeten doorgegeven worden: i) een rijnummer $$r$$ (Number), ii) een kolomnummer $$k$$ (Number) en iii) een getal $$n$$ (Number). De methode moet de cijfers van getal $$n$$ horizontaal invullen vanaf de cel op rij $$r$$ en kolom $$k$$ in het rooster van puzzel $$p$$. Dit is enkel mogelijk als de volgende voorwaarden voldaan zijn:
$$n$$ is een straat
de cel op rij $$r$$ en kolom $$k$$ is de eerste cel van een horizontaal getal
$$n$$ heeft evenveel cijfers als het getal dat horizontaal moet ingevuld worden vanaf de cel op rij $$r$$ en kolom $$k$$
de cijfers die reeds in het rooster ingevuld zijn corresponderen met de overeenkomstige cijfers van $$n$$
Als minstens één van deze voorwaarden niet voldaan is, dan moet een Error opgeworpen worden met de boodschap ongeldige vulling. In dat geval mag er ook niets ingevuld worden in het rooster.
Een methode verticaalInvullen waaraan dezelfde argumenten moeten doorgegeven worden als bij de methode horizontaalInvullen. De methode werkt ook analoog aan de methode horizontaalInvullen, maar moet de cijfers van getal $$n$$ verticaal invullen in het rooster, in plaats van horizontaal.
> let cel = new Cel("C")
> cel.toString()
"C"
> cel.isGekleurd()
true
> cel.cijfer()
3
> cel = new Cel(".")
> cel.toString()
"."
> cel.isGekleurd()
false
> cel.cijfer()
> new Cel("?")
Error: ongeldig symbool
> isStraat(62534)
true
> isStraat(91548)
false
> const puzzel = new Str8ts(["##..5..C#", ".6..##1..", "...#H....", "9..D...#E", "#....3..#", "##...I.4.", "4.3.##.6.", "..1##....", "##8....#B"])
> console.log(puzzel.toString())
##..5..C#
.6..##1..
...#H....
9..D...#E
#....3..#
##...I.4.
4.3.##.6.
..1##....
##8....#B
> puzzel.horizontaalGetallen(3)
new Map([[0, "9.."], [4, "..."]])
> puzzel.horizontaalCijfers(3)
new Set([9, 4, 5])
> puzzel.verticaalGetallen(5)
new Map([[0, "."], [2, "..3"], [7, ".."]])
> puzzel.verticaalCijfers(5)
new Set([9, 3])
> puzzel.horizontaalInvullen(0, 1, 96587)
Error: ongeldige vulling
> puzzel.horizontaalInvullen(0, 2, 34567)
Error: ongeldige vulling
> puzzel.horizontaalInvullen(0, 2, 7658)
Error: ongeldige vulling
> puzzel.horizontaalInvullen(0, 2, 965874)
Error: ongeldige vulling
> puzzel.horizontaalInvullen(1, 6, 102)
Error: ongeldige vulling
> puzzel.horizontaalInvullen(0, 2, 96587)
> console.log(puzzel.toString())
##96587C#
.6..##1..
...#H....
9..D...#E
#....3..#
##...I.4.
4.3.##.6.
..1##....
##8....#B
> puzzel.verticaalInvullen(1, 1, 6587)
> console.log(puzzel.toString())
##96587C#
.6..##1..
.5.#H....
98.D...#E
#7...3..#
##...I.4.
4.3.##.6.
..1##....
##8....#B