Nonogram. Vad är nonogram? Nonogram är små enkla men fascinerande pyssel som ursprungligen kommer från Japan. De har också givits ut i söndagsbilagan i engelska dagstidningar under flera år. Idén bakom nonogram är mycket enkel. Du ska bygga upp en bild genom att fylla i rutorna i ett rutnät. Siffror som står till höger och under rutnätet anger hur många rutor som ska vara ifyllda i varje rad respektive kolumn. Nedanstående nonogram får tjäna som exempel..... 0 0... Siffrorna ska tolkas så att på den första raden skall fyra rutor i rad vara ifyllda. På den tredje raden ska tre sekvenser om vardera två rutor vara ifyllda, naturligtvis med minst en tom ruta mellan sig. På samma sätt gäller för den femte kolumnen att två sekvenser om sju respektive två rutor ska vara ifyllda i ordning uppifrån och ner. Lösningen på detta enkla nonogram blir helt enkelt:.... 0 0... En lämplig startpunkt för att lösa nonogrammet här ovan kan vara raderna i mitten. De ska uppenbarligen vara helt ifyllda. På samma sätt kan man fylla i de mittersta kolumnerna. Två sekvenser om totalt nio rutor ska fyllas i och det kan man bara göra på ett sätt i en kolumn med tio platser. Under själva lösandet av nonogrammet brukar man markera rutor som man vet ska vara tomma med en liten prick. De tjockare linjerna i nonogrammet markerar var femte rad för att underlätta räknandet.
. Hur löser man nonogram? Man använder samma grundläggande lösningsteknik oavsett om man ska lösa ett nonogram manuellt eller med hjälp av ett datorprogram. Som exempel kan vi ta den andra raden ur nonogrammet ovan: Här ska vi placera in ett block om sex rutor. Om vi placerar blocket så långt åt vänster respektive höger som möjligt får vi lösningarna: Vi kan alltså vara säkra på att de två mittenrutorna måste vara ifyllda, eftersom de två lösningsförslagen överlappar varandra där. Om raden redan är delvis ifylld kan vi komma ännu längre med den här lösningstekniken. Säg till exempel att vi kommit fram till att de två rutorna längst till höger ska vara tomma: Då kommer våra vänster- och högerlösningar att visa att det är fyra rutor som överlappar: Vi kan också markera rutor som tomma när ett sekvens av rutor är för liten eller när alla block är ifyllda på en rad. På detta sätt kan vi från ovanstående exempel sluta oss till följande:. Några begrepp Beskrivningar kallar vi siffrorna som står vid sidan av eller under rutnätet och som talar om hur många block som ska fyllas i samt hur stora de ska vara. Ett rutnät med tillhörande beskrivningar, helt eller delvis ifyllt, kallar vi för ett nonogram. Om rutnätet är helt ifyllt (dvs varje ruta är antingen helt fylld eller markerad med en prick) och ifyllningen stämmer överens med beskrivningarna har vi en nonogramlösning. Det är inte självklart att ett nonogram har en lösning. Ett enkelt sätt att kontrollera om ett nonogram inte har en lösning är att summera alla beskrivningar. Summan av de vertikala beskrivningarna ska vara samma som summan av de horisontella beskrivningarna. Att så är fallet inser man lätt, eftersom de ju uttrycker samma sak, nämligen antalet rutor som ska vara ifyllda.
Ett nonogram som har en enda möjlig lösning kallar vi för ett entydigt nonogram. Nonogram som har flera möjliga lösningar kallar vi flertydiga nonogram. Det enklaste flertydiga nonogrammet är nedanstående som har två olika lösningar: Ett nonogram som går att lösa enbart med hjälp av den metod som beskrevs ovan kallar vi för ett enkelt nonogram. Flertydiga nonogram är aldrig enkla, eftersom de innehåller tvetydigheter. Vi kan inte heller vara säkra på att alla entydiga nonogram är enkla. Däremot är alla enkla nonogram entydiga. Ett exempel på ett nonogram som är entydigt men inte enkelt är nedanstående:............. Med hjälp av den lösningsmetod som beskrivts tidigare kan man inte komma längre än till det tillstånd som visas ovan. Därefter måste man gissa sig fram och verifiera lösningen gentemot beskrivningarna. Nonogrammets slutliga lösning är:............. Med lite fantasi ska man kunna utskilja ett hundansikte i profil med nosen åt vänster och ett öra åt höger.
. Komplexitet För att kunna lösa ett nonogram med en dator måste vi för varje rad och kolumn kunna räkna upp alla olika sätt att placera ut blocken. Hur många sådana olika sätt finns det, givet en radlängd och ett antal olika block? Vi antar att raden (eller kolumnen) består av n rutor och att vi ska placera ut k block med storlekarna b, b,..., b k. Blockens täckning t definierar vi som den totala storleken av alla block samt de k - antal tomma distansrutor som tvunget måste vara mellan blocken för att skilja dem åt. t = k + k b i i= Om vi räknar bort blocken och de tomma distansrutorna ovan har vi n - t lediga rutor kvar på varje rad. Dessa tomma rutor ska vi nu permutera på alla möjliga sätt. De k blocken måste vara i samma ordning, men de lediga rutorna kan vi placera var som helst. Det finns k+ olika potentiella positioner för sådana lediga rutor. Det handlar alltså om att fördela n - t antal tomma rutor på k+ olika ställen. Om man vill göra det lättare för sig kan man tänka sig att man ska fördela x likadana kulor i y olika lådor där lådorna gärna får vara tomma. Det är samma sak som att permutera x kulor och y antal mellanrum, vilket ger oss följande formel för antalet möjliga fördelningar: f ( x + y )! (( n t) + ( k + ) )! ( n t + k)! = = = x!( y )! ( n t)!(( k + ) )! ( n t)! k! Exempel: Vi har en rad med tio rutor och ska placera ut två block som är två respektive fyra rutor. Täckningen t är då -+(+) =. Antalet olika permutationer är (0-+)!/((0-)!!) = 5!/(!!) = 0. Detta illustreras av raderna i figuren nedan........... Som ytterligare exempel kan vi ta det flertydiga nonogrammet från avsnitt ovan. Här har vi n = 0. Figuren nedan visar beräkningen av antalet möjliga ifyllningar f för varje rad, baserat på antalet block k och blockens täckning t.
t k f. 8.. 5... 5... 8 5.. 5. 8. 5 8 För raderna handlar det om totalt möjliga radifyllningar som måste verifieras mot kolumnerna. Detta antal kan dock växa kraftigt för större nonogram. Antag t.ex. att vi har en rad med 5 positioner och beskrivningen (.... ), dvs n = 5, k = 5 och t =. Det ger oss f = 00, och detta för bara en rad! Antag att en annan rad i samma nonogram har beskrivningen ( 9. ). Det innebär att n = 5, k = och t = vilket ger f =. Antalet möjliga ifyllningar växer alltså ganska drastiskt när kvoten t/n minskar, och tvärtom. 5. Lösa nonogram med datorprogram Kan man lösa nonogram med hjälp av ett datorprogram? Går det att implementera en nonogramlösare i Lisp? Ja, självklart! Det gäller bara att lösa följande delproblem: Hur ska man representera själva nonogrammet? Vilka abstrakta datatyper behövs? Vilken typ av nonogram vill man kunna klara av? Man kan begränsa sig till att enbart klara av enkla och entydiga nonogram, dvs man försöker aldrig gissa. Då klarar man inte av att lösa alla nonogram, men projektet kanske blir enklare. Hur ska lösningsalgoritmen som beskrevs ovan implementeras? Antagligen bör man försöka lösa några nonogram för hand först för att få en känsla för hur det fungerar. Löser man nonogram för hand kan man ju göra intelligenta gissningar om var man bör börja. Kan man få datorn att göra samma gissningar, t.ex. att börja med den rad som är mest ifylld? Och om man vill kunna lösa flertydiga nonogram, hur ska man kunna backa tillbaka om man har gissat fel? Ett hett tips när man ska testa sin nonogramlösare är att kompilera koden. Då kommer programmet att gå avsevärt mycket snabbare.