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.

opgave
Voorbeeldopgave van een str8ts puzzel.

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.

oplossing
Oplossing van de voorbeeldopgave.

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.

Opgave

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 (AI) 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

Cel

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:

isStraat

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.

Str8ts

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:

Voorbeeld

> 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