{"id":959,"date":"2014-11-27T21:40:29","date_gmt":"2014-11-27T18:40:29","guid":{"rendered":"http:\/\/spektraklet.wordpress.com\/?p=959"},"modified":"2018-03-15T15:10:18","modified_gmt":"2018-03-15T12:10:18","slug":"sudoku","status":"publish","type":"post","link":"https:\/\/spektrum.fi\/spektraklet\/sudoku\/","title":{"rendered":"Algoritmisk Sudokul\u00f6sning"},"content":{"rendered":"<p>Sudoku, eller \u201cNumber Place\u201d som det ursprungligen hette \u00e4r i dagens l\u00e4ge ett mycket v\u00e4lk\u00e4nt logiskt pussel:<\/p>\n<p><a href=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/rank3example1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-993\" src=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/rank3example1.png?w=300\" alt=\"rank3Example\" width=\"250\" height=\"250\" \/><\/a> <a href=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/rank3examplesolved1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-994\" src=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/rank3examplesolved1.png\" alt=\"rank3ExampleSolved\" width=\"250\" height=\"250\" \/><\/a><\/p>\n<p>Givet ett <img src='https:\/\/s0.wp.com\/latex.php?latex=9+%5Ctimes+9&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='9 \\times 9' title='9 \\times 9' class='latex' \/> rutf\u00e4lt delvis ifyllt av siffrorna <img src='https:\/\/s0.wp.com\/latex.php?latex=1-9&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='1-9' title='1-9' class='latex' \/> skall du fylla i resten av rutorna med siffrorna <img src='https:\/\/s0.wp.com\/latex.php?latex=1-9&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='1-9' title='1-9' class='latex' \/> s\u00e5 att varje siffra uppkommer endast en g\u00e5ng p\u00e5 varje rad\/kolumn\/liten ruta, vilka i exemplet omringas i bilden av de lite tjockare linjerna.<\/p>\n<p>Sudoku pussel kan hittas \u00f6verallt; m\u00e5nga tidningar (t.ex. Hbl) publicerar sudokun dagligen, dessutom kryllar bokaff\u00e4rerna av \u201dtraditionella\u201d och internet av elektroniska sudokun i varierande kvalitet. F\u00f6r de allra ivrigaste l\u00f6sarna ordnas det \u00e5rligen VM, med tusentals euron som pris. F\u00f6r den intresserade l\u00e4saren finns det i k\u00e4llorna ett par l\u00e4nkar om sudokuns historia, jag m\u00e5ste medge att jag hade trott att sudoku skulle h\u00e4rstamma fr\u00e5n Japan, men den moderna varianten av sudoku skapades (h\u00f6gst troligen) av en 74-\u00e5rig arkitekt fr\u00e5n USA.<\/p>\n<p>Det skulle kunna finnas ett antal olika aspekter att diskutera d\u00e5 det kommer till sudokun. Jag kommer att (igen) ta en datavetar-syn p\u00e5 det hela och unders\u00f6ka till vilken grad datorer kan anv\u00e4ndas f\u00f6r sudokul\u00f6sning. Det vill s\u00e4ga: hur sv\u00e5rt \u00e4r l\u00f6sning av sudokun f\u00f6r en dator och har m\u00e4nniskan n\u00e5gon chans klara sig mot dem? Mer specifikt s\u00e5 kommer jag att presentera tre olika algoritmer f\u00f6r sudokul\u00f6sning samt j\u00e4mf\u00f6ra dem med varandra.<\/p>\n<p><strong>Sudokul\u00f6sning med datorhj\u00e4lp<\/strong><\/p>\n<p>N\u00e4st g\u00e5r vi allts\u00e5 igenom tre alternativa algoritmer f\u00f6r att l\u00f6sa sudokun. F\u00f6r l\u00e4sbarhetens skull kommer jag inte att g\u00e5 in p\u00e5 detalj d\u00e5 det kommer till implementeringen av de mer komplicerade algoritmerna. Detaljerad f\u00f6rst\u00e5else f\u00f6r algoritmerna kr\u00e4vs inte i resten av texten och f\u00f6r de intresserade l\u00e4sarna finns det en bilaga med (lite) mer detalj.<\/p>\n<p>Algoritm 1:\u00a0 SimpleSolver<\/p>\n<p>Den f\u00f6rsta algoritmen vi unders\u00f6ker \u00e4r ocks\u00e5 den enklaste. Ifall jag skulle be 100 m\u00e4nniskor beskriva det simplaste s\u00e4ttet de kommer p\u00e5 f\u00f6r att l\u00f6sa sudokun, skulle de flesta h\u00f6gst troligen beskriva SimpleSolver. Det handlar n\u00e4mligen om att pr\u00f6va alla de (\u00e4ndligt m\u00e5nga) s\u00e4tten att fylla i de tomma rutorna. Algoritmen fungerar genom att g\u00e5 igenom alla tomma rutor en \u00e5t g\u00e5ngen och pr\u00f6va alla m\u00f6jliga siffror att s\u00e4tta i dem. Efter att ha fyllt rutan granskar algoritmen att alla sudokuregler fortfarande uppfylls. Om allt \u00e4r ok g\u00e5r algoritmen vidare till n\u00e4sta tomma ruta, annars pr\u00f6var algoritmen n\u00e4sta siffra. Om algoritmen tvingas pr\u00f6va alla siffror utan att kunna hitta en l\u00f6sning g\u00e5r den tillbaka till f\u00f6reg\u00e5ende tomma ruta och pr\u00f6var n\u00e4sta siffra.<\/p>\n<p>Med denna taktik kommer algoritmen i n\u00e5got skede att ha pr\u00f6vat alla m\u00f6jligheter och d\u00e4rmed ocks\u00e5 hittat l\u00f6sningen. SimpleSolver \u00e4r v\u00e4ldigt simpel, implementation av den brukar vara en av r\u00e4kne\u00f6vningarna under grundprogrammeringskurserna i Gumt\u00e4kt.<\/p>\n<p>Algoritm 2: DLXSudoku<\/p>\n<p>Till skillnad fr\u00e5n f\u00f6rsta algoritmen \u00e4r de tv\u00e5 andra algoritmerna f\u00f6r sudokul\u00f6sning ursprungligen inte skapade f\u00f6r sudokun. Ist\u00e4llet baserar de sig p\u00e5 id\u00e9n att omvandla sudoku problemet till n\u00e5got annat (v\u00e4lk\u00e4nt) problem och sedan l\u00f6sa det andra problemet ist\u00e4llet. Orsaken till att vilja g\u00f6ra s\u00e5h\u00e4r \u00e4r att det ofta \u00e4r l\u00e4ttare att omvandla problem \u00e4n att l\u00f6sa dem. S\u00e5 om vi kan hitta andra problem som n\u00e5gon annan (lite fiffigare) m\u00e4nniska har utvecklat effektiva l\u00f6sningsalgoritmer f\u00f6r, kan vi dra nytta av dessa algoritmer genom att omvandla v\u00e5rt problem. Detta \u00e4r ofta tidseffektivare \u00e4n att tillbringa en massa tid p\u00e5 att utveckla specialiserade algoritmer f\u00f6r just sudokun. Inom datavetenskap kallar man ofta denna process f\u00f6r en reduktion av ett problem till ett annat. V\u00e5r andra algoritm \u00e4r baserad p\u00e5 en reduktion av sudokun till exact cover problemet och l\u00f6sning av exact cover med hj\u00e4lp av Algoritm X implementerad med dancing links: DLXSudoku.<\/p>\n<p>Exact cover \u00e4r ett ganska abstrakt problem: Givet en matris best\u00e5ende av endast ettor och nollor \u00e4r uppgiften att v\u00e4lja ut en delm\u00e4ngd av raderna i matrisen s\u00e5 att det bland de rader vi v\u00e4ljer ut finns exakt en etta i varje kolumn (Obs! Detta \u00e4r inte den mest allm\u00e4nna formuleringen av exact cover, men tillr\u00e4cklig f\u00f6r v\u00e5rt behov). Ett sudoku problem kan relativt enkelt omvandlas till en exact cover matris :<\/p>\n<ul>\n<li>Varje tom ruta i sudokubr\u00e4det motsvaras av 9 rader i matrisen. Vi kallar dessa rader f\u00f6r <img src='https:\/\/s0.wp.com\/latex.php?latex=Rr%5C%23Cc%5C%231%2C+%5Cldots%2C+Rr%5C%23Cc%5C%239&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='Rr\\#Cc\\#1, \\ldots, Rr\\#Cc\\#9' title='Rr\\#Cc\\#1, \\ldots, Rr\\#Cc\\#9' class='latex' \/> d\u00e4r den tomma rutan i fr\u00e5ga finns p\u00e5 rad r kolumn c.<\/li>\n<li>Kolumnerna i matrisen representerar de olika sudoku reglerna:\n<ol>\n<li>Varje ruta i sudokubr\u00e4det skall f\u00e5 exakt 1 siffra<\/li>\n<li>Varje kolumn p\u00e5 sudokubr\u00e4det skall bli ifylld av exakt en av varje siffra<\/li>\n<li>Varje rad i sudokubr\u00e4det skall skall bli ifylld av exakt en av varje siffra.<\/li>\n<li>Varje liten ruta skall bli ifylld av exakt en av varje siffra.<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<p>Alla av dessa regler representeras av kolumnerna s\u00e5 att kolumnen inneh\u00e5ller en etta p\u00e5 alla rader som uppfyller regeln (se exempel nedan).<\/p>\n<p>Efter denna konstruktion kan vi l\u00f6sa exakt cover problemet och omvandla l\u00f6sningen till en l\u00f6sning av sudokut helt enkelt genom att fylla i sudokut enligt de rader Rr#Cc#x som vi valt ut till exact cover l\u00f6sningen. Notera specifikt att kolumnerna i exact cover matrisen som representerar kravet \u201dvarje ruta p\u00e5 sudokubr\u00e4det f\u00e5r exakt ett v\u00e4rde\u201d f\u00f6rs\u00e4krar oss om att exact cover l\u00f6sningen inneh\u00e5ller f\u00f6r varje rad r och kolumn c p\u00e5 sudoku br\u00e4det, exakt en rad Rr#Cc#i fr\u00e5n exact cover matrisen. F\u00f6r den intresserade l\u00e4saren finns det som bilaga till denna text en beskrivning p\u00e5 hur DLX fungerar. H\u00e4r n\u00f6jer vi oss med att n\u00e4mna att algoritmen har populariserats av Donald Knuth, som \u00e4ven har utvecklat det (inom naturvetenskaper) mycket anv\u00e4nda LateX typs\u00e4ttningssystemet.<\/p>\n<p><a href=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/rank2exampel1.png\"><img decoding=\"async\" loading=\"lazy\" class=\" size-full wp-image-995 aligncenter\" src=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/rank2exampel1.png\" alt=\"rank2Exampel\" width=\"225\" height=\"225\" \/><\/a><\/p>\n<p><strong>Exempel<\/strong>: <em>Vi reducerar <img src='https:\/\/s0.wp.com\/latex.php?latex=4+%5Ctimes+4&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='4 \\times 4' title='4 \\times 4' class='latex' \/>\u00a0 sudokut ovanf\u00f6r till exact cover. F\u00f6r detta sudoku f\u00e5r vi en exact cover matris med <img src='https:\/\/s0.wp.com\/latex.php?latex=8&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='8' title='8' class='latex' \/> (antalet tomma rutor) <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Ctimes+4&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\times 4' title='\\times 4' class='latex' \/> rader. Bilden nedan visar en del av den:<\/em><\/p>\n<p><em><a href=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/exactcover1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"  wp-image-996 aligncenter\" src=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/exactcover1.png?w=245\" alt=\"ExactCover\" width=\"345\" height=\"422\" \/><\/a> I bilden representerar f\u00f6rsta kolumnen kravet: &#8221;Rutan p\u00e5 rad 2 kolumn 1 m\u00e5ste f\u00e5 exakt 1 v\u00e4rde&#8221;. Vi ser att kolumnen inneh\u00e5ller en etta p\u00e5 varje rad vars val fyller i rutan och 0 annars. Andra kolumnen representerar kravet &#8221;N\u00e5gon ruta p\u00e5 rad tv\u00e5 m\u00e5ste inneh\u00e5lla en etta&#8221;, tredje kolumnen representerar: &#8221;F\u00f6rsta kolumnen m\u00e5ste inneh\u00e5lla en fyra&#8221; och fj\u00e4rde &#8221;lilla rutan uppe till h\u00f6ger m\u00e5ste inneh\u00e5lla en etta&#8221;, vi m\u00e4rker specifikt att fj\u00e4rde kolumnen inneh\u00e5ller en etta endast p\u00e5 f\u00f6rsta raden. Detta betyder att vi m\u00e5ste v\u00e4lja f\u00f6rsta raden till exact cover l\u00f6sningen vilket i sin tur betyder att rutan i kolumn 1 rad 2 kommer att inneh\u00e5lla en etta.<\/em><\/p>\n<p>Algoritm 3: SATSudoku<\/p>\n<p>Den sista av v\u00e5ra algoritmer reducerar sudoku till det kanske mest k\u00e4nda \u201dsv\u00e5ra\u201d problemet inom datavetenskap, n\u00e4mligen satisfiability (SAT). F\u00f6r att kunna beskriva SAT m\u00e5ste vi p\u00e5minna oss om logik kursen i gymnasiet och specifikt de delarna som handlade om propositionslogik.<\/p>\n<p>Propositionslogik \u00e4r ett v\u00e4ldigt enkelt logiskt \u201dspr\u00e5k\u201d d\u00e4r man formar formler genom att binda ihop sanningsvariabler (dvs. variabler som antingen kan vara sanna eller falska) med hj\u00e4lp av <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cland&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\land' title='\\land' class='latex' \/> (OCH), <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Clor&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\lor' title='\\lor' class='latex' \/>\u00a0 (ELLER) och <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cneg&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\neg' title='\\neg' class='latex' \/> (INTE). (Obs. det finns ett antal olika s\u00e4tt att definiera propositionslogik, vi anv\u00e4nder det simplaste m\u00f6jliga som r\u00e4cker f\u00f6r v\u00e5rt behov). Givet en propositionslogisk formel g\u00e5r SAT problemet ut p\u00e5 att hitta ett s\u00e4tt att ge sanningsv\u00e4rden (sant eller falskt) \u00e5t variablerna som g\u00f6r att hela formeln blir sann. Sanningsv\u00e4rdet f\u00f6r en formel definieras utg\u00e5ende fr\u00e5n sanningsv\u00e4rden f\u00f6r de delformler den inneh\u00e5ller:<\/p>\n<ul>\n<li>Om formeln endast best\u00e5r av en enda variabel \u00e4r dess sanningsv\u00e4rde lika med sanningsv\u00e4rdet f\u00f6r variabeln.<\/li>\n<li>Sanningsv\u00e4rdet f\u00f6r <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Clnot+A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\lnot A' title='\\lnot A' class='latex' \/> \u00e4r motsatsen till sanningsv\u00e4rdet f\u00f6r formeln <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/><\/li>\n<li>Formeln <img src='https:\/\/s0.wp.com\/latex.php?latex=A+%5Cland+B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A \\land B' title='A \\land B' class='latex' \/> \u00e4r sann ifall b\u00e5de formlerna <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> och <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/> \u00e4r sanna<\/li>\n<li>Formeln <img src='https:\/\/s0.wp.com\/latex.php?latex=A+%5Clor+B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A \\lor B' title='A \\lor B' class='latex' \/> \u00e4r sann ifall antingen <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> eller <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/> (eller b\u00e5da) \u00e4r sanna.<\/li>\n<\/ul>\n<p>D\u00e5 vi i denna text pratar om att l\u00f6sa SAT menar vi att hitta ett s\u00e4tt att ge v\u00e4rden \u00e5t variablerna i en given formel s\u00e5 att formeln blir sann. Vi kallar detta s\u00e4ttet f\u00f6r en &#8221;l\u00f6sning&#8221; av SAT. (Notera att detta inte \u00e4r en allm\u00e4n definition av SAT problemet, men tillr\u00e4cklig f\u00f6r oss.)<\/p>\n<p>SAT \u00e4r ett mycket v\u00e4lk\u00e4nt problem inom datavetenskap. I dagens l\u00e4ge existerar det effektiva algoritmer f\u00f6r att l\u00f6sa formler som best\u00e5r av hundratusentals variabler och miljontals delformler. F\u00f6r att kunna anv\u00e4nda dessa algoritmer f\u00f6r att l\u00f6sa sudokun m\u00e5ste vi fr\u00e5n ett givet sudokubr\u00e4de kunna forma en propositionsformel som till\u00e5ter oss omvandla en l\u00f6sning p\u00e5 SAT problemet till en l\u00f6sning p\u00e5 sudoku problemet.<\/p>\n<p>F\u00f6r varje ruta, s\u00e4g p\u00e5 rad r kolumn c, introducerar vi 9 sanningsvariabler: <img src='https:\/\/s0.wp.com\/latex.php?latex=v%5E%7Brc%7D_1%2C+%5Cldots%2C+v%5E%7Brc%7D_9&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='v^{rc}_1, \\ldots, v^{rc}_9' title='v^{rc}_1, \\ldots, v^{rc}_9' class='latex' \/>. Meningen med dessa variabler \u00e4r: \u201d<img src='https:\/\/s0.wp.com\/latex.php?latex=v%5E%7Brc%7D_k&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='v^{rc}_k' title='v^{rc}_k' class='latex' \/> \u00e4r sann om och endast om rutan p\u00e5 rad r kolumn c f\u00e5r v\u00e4rdet k i sudokul\u00f6sningen\u201d. V\u00e5r formel kommer att best\u00e5 av 5 olika delformler, fyra olika beskrivningar p\u00e5 de olika sudokureglerna och en som beskriver de siffror som \u00e4r f\u00e4rdigt ifyllda:<\/p>\n<p>1) Varje ruta skall f\u00e5 exakt ett v\u00e4rde. F\u00f6r en fixerad ruta p\u00e5 rad r kolumn c beskrivs detta krav av en logisk representation av: <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Csum_%7Bj%3D1%7D%5E9+v%5E%7Brc%7D_j+%3D+1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\sum_{j=1}^9 v^{rc}_j = 1' title='\\sum_{j=1}^9 v^{rc}_j = 1' class='latex' \/>. Det finns olika s\u00e4tt att representera detta som propositionslogik. Ett av de simplaste \u00e4r att anv\u00e4nda formeln: <img src='https:\/\/s0.wp.com\/latex.php?latex=v%5E%7Brc%7D_1+%5Clor+v%5E%7Brc%7D_2+%5Clor+ldots+%5Clor+v%5E%7Brc%7D_9+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='v^{rc}_1 \\lor v^{rc}_2 \\lor ldots \\lor v^{rc}_9 ' title='v^{rc}_1 \\lor v^{rc}_2 \\lor ldots \\lor v^{rc}_9 ' class='latex' \/> f\u00f6r att se till att rutan f\u00e5r\u00a0<strong>minst<\/strong> ett v\u00e4rde och <img src='https:\/\/s0.wp.com\/latex.php?latex=27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='27' title='27' class='latex' \/> formler av formen: <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Clnot+%28v%5E%7Brc%7D_i+%5Cland+v%5E%7Brc%7D_j%29+%5Cquad+%5Cforall+i+%3C+j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\lnot (v^{rc}_i \\land v^{rc}_j) \\quad \\forall i &lt; j' title='\\lnot (v^{rc}_i \\land v^{rc}_j) \\quad \\forall i &lt; j' class='latex' \/> f\u00f6r att se till att den f\u00e5r <strong>h\u00f6gst<\/strong> ett v\u00e4rde. I v\u00e5r implementation anv\u00e4nder vi oss av ett lite annorlunda s\u00e4tt att representera samma sak (kallas f\u00f6r sequential counter). F\u00f6r den intresserade l\u00e4saren finns det referenser.<\/p>\n<p>2) Varje rad skall f\u00e5 en av varje v\u00e4rde. F\u00f6r en fixerad rad R beskrivs detta av (del)formeln:<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cbigwedge_%7Bk%3D1%7D%5E9+%5Cleft%28%5Csum_%7Bc%3D1%7D%5E9+v%5E%7BRc%7D_k+%3D+1%5Cright%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\bigwedge_{k=1}^9 \\left(\\sum_{c=1}^9 v^{Rc}_k = 1\\right)' title='\\bigwedge_{k=1}^9 \\left(\\sum_{c=1}^9 v^{Rc}_k = 1\\right)' class='latex' \/>\n<p>som omvandlas till propositionslogik precis som i punkt 1.<\/p>\n<p>3) Varje kolumn skall f\u00e5 en av varje v\u00e4rde. F\u00f6r en fixerad column C beskrivs detta av formeln:<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cbigwedge_%7Bk%3D1%7D%5E9+%5Cleft%28+%5Csum_%7Br%3D1%7D%5E9+v%5E%7BrC%7D_k+%3D+1+%5Cright%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\bigwedge_{k=1}^9 \\left( \\sum_{r=1}^9 v^{rC}_k = 1 \\right)' title='\\bigwedge_{k=1}^9 \\left( \\sum_{r=1}^9 v^{rC}_k = 1 \\right)' class='latex' \/>\n<p>4) Varje liten ruta skall f\u00e5 en av varje v\u00e4rde. F\u00f6r t.ex. lilla rutan l\u00e4ngst upp till v\u00e4nster beskrivs detta av formeln:<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cbigwedge_%7Bk%3D1%7D%5E9+%28v%5E%7B11%7D_k+%2B+v%5E%7B12%7D_k+%2B+v%5E%7B13%7D_k+%2B+v%5E%7B21%7D_k+%2B+v%5E%7B22%7D_k%2Bv%5E%7B23%7D_k%2Bv%5E%7B31%7D_k%2Bv%5E%7B32%7D_k%2Bv%5E%7B33%7D_k+%3D+1%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\bigwedge_{k=1}^9 (v^{11}_k + v^{12}_k + v^{13}_k + v^{21}_k + v^{22}_k+v^{23}_k+v^{31}_k+v^{32}_k+v^{33}_k = 1)' title='\\bigwedge_{k=1}^9 (v^{11}_k + v^{12}_k + v^{13}_k + v^{21}_k + v^{22}_k+v^{23}_k+v^{31}_k+v^{32}_k+v^{33}_k = 1)' class='latex' \/>\n<p>5) Varje redan f\u00e4rdigt ifylld ruta motsvaras av en formel som tvingar motsvarande variabel att s\u00e4ttas till sant. S\u00e5 ifall rutan p\u00e5 rad r kolumn c har f\u00e4rdigt ifyllt v\u00e4rdet k l\u00e4gger vi med delformeln <img src='https:\/\/s0.wp.com\/latex.php?latex=v%5E%7Brc%7D_k&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='v^{rc}_k' title='v^{rc}_k' class='latex' \/> till hela formeln.<\/p>\n<p>V\u00e5r sista algoritm f\u00f6r sudokul\u00f6sning bygger upp ett SAT problem s\u00e5h\u00e4r och ger den \u00e5t en SAT algoritm. S\u00e5 l\u00e4nge ursprungliga sudokut har en l\u00f6sning kommer SAT algoritmen att hitta en l\u00f6sning p\u00e5 SAT problemet. Sedan omvandlas\u00a0 SAT l\u00f6sningen till en sudoku l\u00f6sning: rutan p\u00e5 rad r kolum c i sudokubr\u00e4det fylls i med det v\u00e4rde k f\u00f6r vilket variabeln <img src='https:\/\/s0.wp.com\/latex.php?latex=v%5E%7Brc%7D_k&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='v^{rc}_k' title='v^{rc}_k' class='latex' \/> \u00e4r sann i SAT l\u00f6sningen. Delformeln vi satt med i punkt 1 h\u00e4r ovan f\u00f6rs\u00e4krar oss om att det finns exakt en s\u00e5dan f\u00f6r varje tom ruta.<\/p>\n<p><a href=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/rank2exampel1.png\"><img decoding=\"async\" loading=\"lazy\" class=\" size-full wp-image-995 aligncenter\" src=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/rank2exampel1.png\" alt=\"rank2Exampel\" width=\"225\" height=\"225\" \/><\/a><\/p>\n<p><em><strong>Exempel<\/strong>: Vi forts\u00e4tter med samma exempel som tidigare. Fullst\u00e4ndiga propositionsformeln som beskriver detta exempel \u00e4r f\u00f6r l\u00e5ng f\u00f6r att skrivas ner f\u00f6r hand. Men h\u00e4r f\u00f6ljer en del illustrerande exempel\u00a0\u00a0\u00a0<\/em><\/p>\n<ol>\n<li><em> Rutan p\u00e5 rad 2 kolumn 1 skall f\u00e5 exakt ett v\u00e4rde: <img src='https:\/\/s0.wp.com\/latex.php?latex=%28v%5E%7B21%7D_1+%5Clor+v%5E%7B21%7D_2+%5Clor+v%5E%7B21%7D_3+%5Clor+v%5E%7B21%7D_4%29+%5Cland+%5Clnot+%28v%5E%7B21%7D_1+%5Cland+v%5E%7B21%7D_2%29+%5Cland+%5Clnot+%28v%5E%7B21%7D_1+%5Cland+v%5E%7B21%7D_3%29+%5Cland+%5Clnot+%28v%5E%7B21%7D_1+%5Cland+v%5E%7B21%7D_4%29+%5Cland+%5Clnot+%28v%5E%7B21%7D_2+%5Cland+v%5E%7B21%7D_3%29+%5Cland+%5Clnot+%28v%5E%7B21%7D_2+%5Cland+v%5E%7B21%7D_4%29+%5Cland+%5Clnot+%28v%5E%7B21%7D_3+%5Cland+v%5E%7B21%7D_4%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='(v^{21}_1 \\lor v^{21}_2 \\lor v^{21}_3 \\lor v^{21}_4) \\land \\lnot (v^{21}_1 \\land v^{21}_2) \\land \\lnot (v^{21}_1 \\land v^{21}_3) \\land \\lnot (v^{21}_1 \\land v^{21}_4) \\land \\lnot (v^{21}_2 \\land v^{21}_3) \\land \\lnot (v^{21}_2 \\land v^{21}_4) \\land \\lnot (v^{21}_3 \\land v^{21}_4)' title='(v^{21}_1 \\lor v^{21}_2 \\lor v^{21}_3 \\lor v^{21}_4) \\land \\lnot (v^{21}_1 \\land v^{21}_2) \\land \\lnot (v^{21}_1 \\land v^{21}_3) \\land \\lnot (v^{21}_1 \\land v^{21}_4) \\land \\lnot (v^{21}_2 \\land v^{21}_3) \\land \\lnot (v^{21}_2 \\land v^{21}_4) \\land \\lnot (v^{21}_3 \\land v^{21}_4)' class='latex' \/>.<\/em><\/li>\n<li><em>\u00a0Kolumn 1 m\u00e5ste inneh\u00e5lla en etta: <img src='https:\/\/s0.wp.com\/latex.php?latex=%28v%5E%7B11%7D_1+%5Clor+v%5E%7B21%7D_1+%5Clor+v%5E%7B31%7D_1+%5Clor+v%5E%7B41%7D_1%29+%5Cland+%5Clnot+%28v%5E%7B11%7D_1+%5Cland+v%5E%7B21%7D_1%29+%5Cland+%5Clnot+%28v%5E%7B11%7D_1+%5Cland+v%5E%7B31%7D_1%29+%5Cland+%5Clnot+%28v%5E%7B11%7D_1+%5Cland+v%5E%7B41%7D_1%29+%5Cland+%5Clnot+%28v%5E%7B21%7D_1+%5Cland+v%5E%7B31%7D_1%29+%5Cland+%5Clnot+%28v%5E%7B21%7D_1+%5Cland+v%5E%7B41%7D_1%29+%5Cland+%5Clnot+%28v%5E%7B31%7D_1+%5Cland+v%5E%7B41%7D_1%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='(v^{11}_1 \\lor v^{21}_1 \\lor v^{31}_1 \\lor v^{41}_1) \\land \\lnot (v^{11}_1 \\land v^{21}_1) \\land \\lnot (v^{11}_1 \\land v^{31}_1) \\land \\lnot (v^{11}_1 \\land v^{41}_1) \\land \\lnot (v^{21}_1 \\land v^{31}_1) \\land \\lnot (v^{21}_1 \\land v^{41}_1) \\land \\lnot (v^{31}_1 \\land v^{41}_1)' title='(v^{11}_1 \\lor v^{21}_1 \\lor v^{31}_1 \\lor v^{41}_1) \\land \\lnot (v^{11}_1 \\land v^{21}_1) \\land \\lnot (v^{11}_1 \\land v^{31}_1) \\land \\lnot (v^{11}_1 \\land v^{41}_1) \\land \\lnot (v^{21}_1 \\land v^{31}_1) \\land \\lnot (v^{21}_1 \\land v^{41}_1) \\land \\lnot (v^{31}_1 \\land v^{41}_1)' class='latex' \/>.<\/em><\/li>\n<li><em>Rad 1 m\u00e5ste inneh\u00e5lla en tv\u00e5: <img src='https:\/\/s0.wp.com\/latex.php?latex=%28v%5E%7B11%7D_2+%5Clor+v%5E%7B12%7D_2+%5Clor+v%5E%7B13%7D_2+%5Clor+v%5E%7B14%7D_2%29+%5Cland+%5Clnot+%28v%5E%7B11%7D_2+%5Cland+v%5E%7B12%7D_2%29+%5Cland+%5Clnot+%28v%5E%7B11%7D_2+%5Cland+v%5E%7B13%7D_2%29+%5Cland+%5Clnot+%28v%5E%7B11%7D_2+%5Cland+v%5E%7B14%7D_2%29+%5Cland+%5Clnot+%28v%5E%7B12%7D_2+%5Cland+v%5E%7B13%7D_2%29+%5Cland+%5Clnot+%28v%5E%7B12%7D_2+%5Cland+v%5E%7B14%7D_2%29+%5Cland+%5Clnot+%28v%5E%7B13%7D_2+%5Cland+v%5E%7B14%7D_2%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='(v^{11}_2 \\lor v^{12}_2 \\lor v^{13}_2 \\lor v^{14}_2) \\land \\lnot (v^{11}_2 \\land v^{12}_2) \\land \\lnot (v^{11}_2 \\land v^{13}_2) \\land \\lnot (v^{11}_2 \\land v^{14}_2) \\land \\lnot (v^{12}_2 \\land v^{13}_2) \\land \\lnot (v^{12}_2 \\land v^{14}_2) \\land \\lnot (v^{13}_2 \\land v^{14}_2)' title='(v^{11}_2 \\lor v^{12}_2 \\lor v^{13}_2 \\lor v^{14}_2) \\land \\lnot (v^{11}_2 \\land v^{12}_2) \\land \\lnot (v^{11}_2 \\land v^{13}_2) \\land \\lnot (v^{11}_2 \\land v^{14}_2) \\land \\lnot (v^{12}_2 \\land v^{13}_2) \\land \\lnot (v^{12}_2 \\land v^{14}_2) \\land \\lnot (v^{13}_2 \\land v^{14}_2)' class='latex' \/>.<\/em><\/li>\n<li><em>Vissa rutor \u00e4r f\u00e4rdigt ifyllda: <img src='https:\/\/s0.wp.com\/latex.php?latex=v%5E%7B11%7D_3+%5Cland+v%5E%7B12%7D_4+%5Cland+v%5E%7B13%7D_1+%5Cland+v%5E%7B22%7D_2+%5Cland+v%5E%7B33%7D_2+%5Cland+v%5E%7B42%7D_1+%5Cland+v%5E%7B43%7D_4+%5Cland+v%5E%7B44%7D_3&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='v^{11}_3 \\land v^{12}_4 \\land v^{13}_1 \\land v^{22}_2 \\land v^{33}_2 \\land v^{42}_1 \\land v^{43}_4 \\land v^{44}_3' title='v^{11}_3 \\land v^{12}_4 \\land v^{13}_1 \\land v^{22}_2 \\land v^{33}_2 \\land v^{42}_1 \\land v^{43}_4 \\land v^{44}_3' class='latex' \/>.<\/em><\/li>\n<\/ol>\n<p>Bilagan till denna artikel g\u00e5r in p\u00e5 (lite mer) detalj om hur en SAT algoritm oftast fungerar.<\/p>\n<p><strong>Vilken \u00e4r b\u00e4st?<\/strong><\/p>\n<p>Nu \u00e4r det dags f\u00f6r den mest intressanta fr\u00e5gan; vilken \u00e4r b\u00e4st? F\u00f6r att kunna testa detta fick jag hj\u00e4lp av Toffe som implementera SimpleSolvern och Lasse som implementera DLXSudoku. Sj\u00e4lv implementerade jag SATSudoku. Tack till b\u00e5de Toffe och Lasse!<\/p>\n<p>Innan vi g\u00e5r till resultaten vill jag p\u00e5peka att skillnaderna vi kommer att se i dessa algoritmer inte beror p\u00e5 implementationerna, resultaten kan inte och skall inte anv\u00e4ndas f\u00f6r att j\u00e4mf\u00f6ra v\u00e5ra kodningskunskaper.<\/p>\n<p>Jag valde p\u00e5 m\u00e5f\u00e5 ut <img src='https:\/\/s0.wp.com\/latex.php?latex=3&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='3' title='3' class='latex' \/> sudokun av storlek <img src='https:\/\/s0.wp.com\/latex.php?latex=9+%5Ctimes+9&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='9 \\times 9' title='9 \\times 9' class='latex' \/> och tog tid p\u00e5 hur l\u00e4nge var och en av v\u00e5ra algoritmer tog p\u00e5 sig f\u00f6r att l\u00f6sa dem. Resultaten finns nedan:<\/p>\n<p><a href=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/sudokueasy.png\"><img decoding=\"async\" loading=\"lazy\" class=\"  wp-image-968 aligncenter\" src=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/sudokueasy.png?w=300\" alt=\"SudokuEasy\" width=\"361\" height=\"65\" \/><\/a><\/p>\n<p>Det var ju lite tr\u00e5kigt inte sant? Till och med den simplaste algoritmen l\u00f6ser alla 3 p\u00e5 under 1.5s, de mer avancerade l\u00f6sarna tar under en tiondels sekund p\u00e5 sig. Detta illustrerar orsaken till varf\u00f6r jag bara hade tre sudokun; faktum \u00e4r att de allra flesta normala sudokun \u00e4r s\u00e5 gott som triviala f\u00f6r en dator. Det g\u00e5r att designa problem som v\u00e5r SimpleSudoku inte skulle kunna l\u00f6sa, men redan genom att ha SimpleSudoku\u00a0 pr\u00f6va siffror i slumpm\u00e4ssig ordning ist\u00e4llet f\u00f6r storleksordning s\u00e5 klarar \u00e4ven den av s\u00e5 gott som alla <img src='https:\/\/s0.wp.com\/latex.php?latex=9+%5Ctimes+9&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='9 \\times 9' title='9 \\times 9' class='latex' \/> sudokun snabbare \u00e4n vad det skulle ta f\u00f6r m\u00e4nniskan att skriva ner en f\u00e4rdig l\u00f6sning. S\u00e5 det ser inte s\u00e5 hemskt lovande ut f\u00f6r oss m\u00e4nniskor.<\/p>\n<p>Det verkar allts\u00e5 klart att om man beh\u00f6ver f\u00e5 m\u00e5nga sudokun l\u00f6st snabbt \u00e4r det mer tidseffektivt att koda en l\u00f6sare \u00e4n att l\u00f6sa dem sj\u00e4lv. Dock kan man efter dessa resultat\u00a0 fr\u00e5ga sig varf\u00f6r man \u00f6ver huvudtaget borde s\u00e4tta ner tid p\u00e5 att implementera n\u00e5got som helst mer avancerat \u00e4n SimpleSudoku?<\/p>\n<p>Ifall man bara \u00e4r intresserad av <img src='https:\/\/s0.wp.com\/latex.php?latex=9+%5Ctimes+9&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='9 \\times 9' title='9 \\times 9' class='latex' \/> sudokun \u00e4r svaret: man borde inte. Men, om vi till\u00e5ter st\u00f6rre sudokun blir saker och ting intressantare. Forskningsresultat inom sudokul\u00f6sning (ja, det finns s\u00e5dana) pratar ofta om ordningen (rank) av ett sudoku. En normal sudoku \u00e4r av ordning 3 och allm\u00e4nt s\u00e5 skall en sudoku av ordning <img src='https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' \/> l\u00f6sas p\u00e5 ett <img src='https:\/\/s0.wp.com\/latex.php?latex=n%5E2+%5Ctimes+n%5E2&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n^2 \\times n^2' title='n^2 \\times n^2' class='latex' \/> br\u00e4de. S\u00e5 en <img src='https:\/\/s0.wp.com\/latex.php?latex=4+%5Ctimes+4&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='4 \\times 4' title='4 \\times 4' class='latex' \/> sudoku \u00e4r av ordning <img src='https:\/\/s0.wp.com\/latex.php?latex=2&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2' title='2' class='latex' \/> och en <img src='https:\/\/s0.wp.com\/latex.php?latex=16+%5Ctimes+16&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='16 \\times 16' title='16 \\times 16' class='latex' \/> sudoku \u00e4r av ordning <img src='https:\/\/s0.wp.com\/latex.php?latex=4&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='4' title='4' class='latex' \/>. Alla av v\u00e5ra algoritmer kan anv\u00e4ndas f\u00f6r att l\u00f6sa sudokun av vilken ordning som helst. Dessutom borde st\u00f6rre sudokun vara b\u00e4ttre f\u00f6r att j\u00e4mf\u00f6ra algoritmer, intuitivt k\u00e4nns det ju ganska klart att ett st\u00f6rre sudoku borde vara sv\u00e5rare \u00e4n ett mindre.<\/p>\n<p><a href=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/sudokuhard11.png\"><img decoding=\"async\" loading=\"lazy\" class=\"  wp-image-970 aligncenter\" src=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/11\/sudokuhard11.png?w=300\" alt=\"SudokuHard\" width=\"342\" height=\"327\" \/><\/a><\/p>\n<p>Resultaten finns ovan och nu b\u00f6rjar vi p\u00e5 riktigt m\u00e4rka skillnader i algoritmerna. SimpleSolvern klarade inte av en enda av dessa problem p\u00e5 under en timme (gr\u00e4nsen p\u00e5 l\u00f6sningstiden). D\u00e4remot klarar sig b\u00e5de SATSudoku och DLXSudoku ganska v\u00e4l, speciellt p\u00e5 &#8221;enkla&#8221; sudokun. Av dessa tv\u00e5 klarar sig SATSudoku lite b\u00e4ttre \u00e4n DLX: den klarar av en ordning st\u00f6rre &#8221;l\u00e4tt&#8221; problem och en ordning st\u00f6rre &#8221;sv\u00e5rt&#8221; problem.<\/p>\n<p>Vad l\u00e4r vi oss av detta? Jo, om du bara vill l\u00f6sa ett enda normal stort sudoku \u00e4r det fiffigare att ta papper och penna \u00e4n b\u00f6rja koda. Skall du l\u00f6sa 1000 normala sudokun kan du be datorn g\u00f6ra det p\u00e5 det enklaste m\u00f6jliga s\u00e4ttet. Skall du l\u00f6sa ett enkelt <img src='https:\/\/s0.wp.com\/latex.php?latex=15%5E2+%3D+225+%5Ctimes+225&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='15^2 = 225 \\times 225' title='15^2 = 225 \\times 225' class='latex' \/> sudoku, s\u00e5 g\u00e5r det ocks\u00e5 att fixas, dock med lite mer m\u00f6da. Men om du vill l\u00f6sa ett sv\u00e5rt <img src='https:\/\/s0.wp.com\/latex.php?latex=49+%5Ctimes+49&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='49 \\times 49' title='49 \\times 49' class='latex' \/> sudoku? D\u00e5 \u00e4r det dags att ta fram pennan igen, skriva ett stort &#8221;L\u00d6S SJ\u00c4LV&#8221; p\u00e5 hela br\u00e4det, och ta en \u00f6l ist\u00e4llet.<\/p>\n<p>Slutligen vill jag l\u00e4mna er med <a href=\"http:\/\/www.cse.unsw.edu.au\/~fpt09\/comp\/puzzle15a.sudoku\" target=\"_blank\">det st\u00f6rsta<\/a> sudokut som v\u00e5ra algoritmer klarade av och <a href=\"http:\/\/www.cse.unsw.edu.au\/~fpt09\/comp\/puzzle07b.sudoku\" target=\"_blank\">det minsta<\/a> som de inte klarade. Om n\u00e5gon av er f\u00e5r n\u00e5gondera l\u00f6st kan ni l\u00e4mna en kommentar s\u00e5 s\u00e4tter jag med er i resultaten.<\/p>\n<p>Jeremias<\/p>\n<p>BILAGA:<\/p>\n<p><a href=\"http:\/\/spektrum.fi\/spektraklet\/wp-content\/uploads\/2014\/12\/algodescriptions11.pdf\">Algorithm X, Conflict Driven Clause Learning and Dancing Links for Sudokusolving. <\/a><\/p>\n<p>K\u00e4llor:<\/p>\n<ul>\n<li><strong><a href=\"http:\/\/en.wikipedia.org\/wiki\/Latin_square#cite_ref-8\">^<\/a><\/strong> <a href=\"http:\/\/en.wikipedia.org\/wiki\/Charles_Colbourn\">C. Colbourn<\/a> (1984). &#8221;The complexity of completing partial latin squares&#8221;. <em>Discrete Applied Mathematics<\/em> <strong>8<\/strong>: 25\u201330. <a href=\"http:\/\/en.wikipedia.org\/wiki\/Digital_object_identifier\">doi<\/a>:<a href=\"http:\/\/dx.doi.org\/10.1016%2F0166-218X%2884%2990075-1\">10.1016\/0166-218X(84)90075-1<\/a>.<\/li>\n<li><span class=\"this-person\">Carsten Sinz<\/span>: <span class=\"title\">Towards an Optimal CNF Encoding of Boolean Cardinality Constraints.<\/span> <a href=\"http:\/\/www.informatik.uni-trier.de\/%7Eley\/db\/conf\/cp\/cp2005.html#Sinz05\">CP 2005<\/a>: 827-831<\/li>\n<li>http:\/\/www.worldpuzzle.org\/championships\/wsc\/<\/li>\n<li><a href=\"http:\/\/plus.maths.org\/content\/os\/issue38\/features\/aiden\/index\">http:\/\/plus.maths.org\/content\/os\/issue38\/features\/aiden\/index<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Sudoku, eller \u201cNumber Place\u201d som det ursprungligen hette \u00e4r i dagens l\u00e4ge ett mycket v\u00e4lk\u00e4nt logiskt pussel: Givet ett rutf\u00e4lt delvis ifyllt av siffrorna skall du fylla i resten av rutorna med siffrorna s\u00e5 att varje siffra uppkommer endast en g\u00e5ng p\u00e5 varje rad\/kolumn\/liten ruta, vilka i exemplet omringas i bilden av de lite tjockare &hellip; <a href=\"https:\/\/spektrum.fi\/spektraklet\/sudoku\/\" class=\"more-link\">Forts\u00e4tt l\u00e4sa <span class=\"screen-reader-text\">Algoritmisk Sudokul\u00f6sning<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[83,5],"tags":[53,61],"_links":{"self":[{"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/posts\/959"}],"collection":[{"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/comments?post=959"}],"version-history":[{"count":1,"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/posts\/959\/revisions"}],"predecessor-version":[{"id":1777,"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/posts\/959\/revisions\/1777"}],"wp:attachment":[{"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/media?parent=959"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/categories?post=959"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spektrum.fi\/spektraklet\/wp-json\/wp\/v2\/tags?post=959"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}