#!/usr/local/bin/rebol -si REBOL [ Title: "Sudoku Solver" Date: 01-12-2007 Name: "SudoSolver" Version: 0.5.0 File: %sudoSolver.r Author: "Franck Le Bihan" Email: "franck_at_romarin_dot_org" Purpose: "Try to solve any Sudoku" Credits: ["- Tango Desktop project for Icons..." "http://tango-project.org" "- Brett Handley for focus management..." "http://www.rebol.org/cgi-bin/cgiwrap/rebol/ml-display-message.r?m=rmlNKSQ" "- Rebol french community at forum Rebol..." "http://www.codeur.org/forum/forum.php?ID=1700" ] license: [ "- Tango Icons : Creative Commons Attribution Share-Alike license..." "http://creativecommons.org/licenses/by-sa/2.5/" "- Code : BSD License Copyright (c) 2006, Franck Le Bihan..." "http://www.rebol.com/docs/bsd-mit-license.html" ] History: [ 0.1.0 ["Release - First release" "Franck" 20-12-05] 0.2.0 ["Release - Gui improvement" "Franck" 27-12-05] 0.3.0 ["Release - Optimisation" "Franck" 27-12-05] 0.3.1 ["Internal Release - New feature : Print" "Franck" 29-12-05] 0.3.2 ["Internal Release - Reduce size of script" "Franck" 29-12-05] 0.3.5 ["Release - Gui improvement" "Franck" 05-01-06] 0.3.6 ["Internal Release - Reduce size of script" "Franck" 05-01-06] 0.3.5 ["Release - About window" "Franck" 09-01-06] 0.4.0 ["Release" "Franck" 01-01-07] 0.5.0 ["Release - Correct a bug when Grid is incorrect" "Franck" 01-12-07] ] ] comment { mindex: index? find table1/2 "6" remove at table1/2 mindex } ; language (to-do) __SOLVING: "Solving ... Pass #" __SOLVING1: "Solving ..." ; Gestion du focus trouvé ds la ML Rebol ;Brett Handley (brett) ;20-Sep-2003/0:13:03+10:00 ;#31171 focus: func [ "Focuses key events on a specific face." face /no-show /local tmp-face tmp-value ] bind [ attempt [ if in face 'pre-focus [ if all [ not unset? set/any 'tmp-value face/pre-focus face not tmp-value ] [exit] ] ] if not unfocus [exit] if not face [exit] view*/focal-face: face if not string? face/text [ face/text: either face/text [form face/text] [copy ""] ] if none? face/line-list [ if face/para [face/para/scroll: 0x0] view*/caret: tail face/text ] if flag-face? face field [hilight-all face] if in face 'post-focus [face/post-focus face] if not no-show [show face] ] in ctx-text 'view* unfocus: func [ "Removes the current key event focus." /local tmp-face tmp-value ] bind [ tmp-face: view*/focal-face ; My addition if all [tmp-face in tmp-face 'pre-unfocus] [ ; Call the pre-unfocus function, Cancel the focus if false/none. if all [ not unset? set/any 'tmp-value tmp-face/pre-unfocus tmp-face not tmp-value ] [ ; This will mean that unfocus is cancelled. return none ] ] view*/focal-face: none view*/caret: none unlight-text ; My post-unfocus addition if all [tmp-face in tmp-face 'post-unfocus] [ tmp-face/post-unfocus tmp-face ] if tmp-face [show tmp-face] ; Another addition. Send back a true if we did unfocus. any [tmp-face true] ] in ctx-text 'view* ; les styles stylize/master [ mfield: field bold 32x32 240.240.240 font[size: 25 color: 0.0.0 align: 'center ] para [margin: -1x-4] edge [color: 'black effect: 'none size: 1x1] colors [240.240.240 240.240.240] with [ feel: make feel [ engage: func [face action event] [ switch action [ down [ either equal? face system/view/focal-face [unlight-text] [focus/no-show face] system/view/caret: offset-to-caret face event/offset show face ] over [ if not-equal? system/view/caret offset-to-caret face event/offset [ if not system/view/highlight-start [system/view/highlight-start: system/view/caret] system/view/highlight-end: system/view/caret: offset-to-caret face event/offset show face ] ] key [ if any [all[event/key >= #"0" event/key <= #"9" 1 > length? face/text] ;Return Delete Backspace Tab event/key = #"^M" event/key = #"^~" event/key = #"^H" event/key = #"^-" event/key = 'left event/key = 'right] [ctx-text/edit-text face event get in face 'action] ; ] ] ] ] post-focus: func [face] [face/edge/color: orange face/edge/size: 3x3] pre-unfocus: func [face] [face/edge/color: black face/edge/size: 1x1] ] micon: icon 48x64 mlogo: image logo.gif [attempt [browse http://rebol.com]] mbox: box 0x24 effect [merge gradmul gradient 1x0 0.0.0 50.70.140] [attempt [browse http://rebol.com]] ] ; ; Les icones icones: do [ inew: load to-binary decompress 64#{ eJylzHk81PkfB/DPdwYz45xxtn4JzWCNcowhVu4lRxHNuI8clV0/w8ixip3oh8WK UDmiyDWOHfe5GhryiNHmmMKwaFBGudo2UTM//fb3x/6/r/f7v9fr8RROCxcB2sne 0R5AEAQcDg4Il4Ci3Q/fXQTgzBmABwAgwf8i5ALbL6t/lC/IPzUgYT/AIIE+0IdD RwEMA8ExkHAQKAMAg8HB34ISF0HCRcUOOis0gOAwEZiYKELyrwkEg4uIYsQQSHUg i5KTN7B2C6Im39w6SiDGNI8vKSgdwuJMvnUPvTywnVJe8UWHAPzg/6aLiiFEYEjU QWeEAbAvPIQU///gLx2IIWTVDazljrqRgqiXk5HyCopEo5t5zdvlA+PCWSB5AMIw cAywBA/3LCdUEOfkEx81vpQcqD9f2HWkPJU+Znjq0bgB9r1WM1ZhDaLEsW2tKViq m61XFynVpCb9iYPj0ZeMCoZugdzUq6dEV7MIE4ki32+9WhurBlPkCiNKdhr8AoOR 3e1si8yrZinvkWOCi+ojp46v/CZBkKNFeiTNC9SaWuULmhw2s2RYex60F729wcA3 oo3wbNJRg0jZVDU0vCw72BprThs+/w1UwWlvd+O4ZJjV1S+RzgOgYkZLevqf/VL5 Q2dC/kyyeSkf2emf3/YhTgjSwg2Z93pYzJ8aYkhLXYzfXZI4/OwUU+9IbZ770+dd PkJgyiHcd+mvQm1uGDPFoK54xZUty/T9LWPmPfR941Gyh2T53sOrZeE+y1leNxeh hU/bnJwqIUAzEnWm4+gdMaTn69WLfedmpTbCZpbahohNNt/75aciL+38HN04egRe GxwTH46dq7+gcHkUF2VzAV0PQrFadw49+U0XwWx+FsEWZNfZKw6QE+3SqUMujeTq CijLgSauWYbX9HeXMmVxxzNq/vyRze7UrI1TYr0kFPZq9O+IauJYHEkDzzun6MTq yiGqg7qj9ioK5wdfU7QoO3yJEBrUnFrgI4WTZs2Kj5j+WCov67ojlSEi13yiM7qD Pz9r211PIpYx8n9JZNShUIiGhdWPJdyexYD5T1a70OBnwZxXz1ZrLGVEWv3Z55ma ORL3xly3b+IEZsyOeK1l8XqqaDr5vJIOe4xcMDXhe7sHn6B9+HSQ/uj8tf5VuEpv SM1raaMre9ohvzxIj/0XJFc9+VHHG2PgOslRkB09zSyOPpJ5yznLqKD17PfKi06e ZwMwOIvg3iOe59QfaCmaP3u88Giws0XHlseNxPQHvy6+u+w1WyRlXeTuEzDJCssA 9gT5ulvOpvdjl9n50obUitS4bkafRttw+hFbXumZtOcRQa072M8+eozXY4GRlga8 dd6kjufKFE2Ulk+PZW23q6KFAO7tldHE3fpkITWUc0hzSTBhOgt0fq3+xMTvY9rT 9ksfL05vWPODh/s6dnZ39ynSK+gBeOQec0aQVBKFuPrGnzHoLOUxO9/RRekoLn/F +hp6kIjGpW4lHIbZO1xQ+zgSZfD4RktFWmxtVe4wfvfGYOhh/e2v4J9VZCKoL/hF nlUNY8Nu8pvhla4j/BibO7qVvZnvcvSifjir4YFyokK603PGSqF0K1yjCqXdgume T6afrKlyojr7ZGi+wO1k5f1bN15zOS9uQ7J+omk8xCahp+mYi/5kCorbfaX8SczN Da3etxveAdh91+RfTRaXis2zQ30TO+2O+3obHuNE1+mj0IWnVI85L+RKV0rmAajj 9nZgrKNyC4WmycdY4R/oTPG06B9eD8TYfCN1idQQGOPe9uZ9n0RpLe762+O+kyED rBQEVtXj56QKM1q8OLNKytuTeMtnTLlUD7+WQFclantTod13rcYBPn3pZaPd3Rka NUVxFl6rzrEd62FsJfQ65YQd2YAUqi1Rm5mZD3slXXQ6XAHF/yPBjlZvG3Ht99pl v6o2DdTMmJHRuxRr447lNwgliYiRNLxy2DI9G+fw0dsrl5RmLuNqb16WrecxTjYn beSaYS3IaUi15BzV9eHToig1LoeW49/Jo9+YED/BDd9LCozP4T5aPzEZUXisRMuO +D5yYc/160puuGDjifG2Ekzgyc1mU0rYgz52f1ywDtnfu5cnIyDyWyJ5QbyHc5R9 j/n1XAFPCIzy+QplDL0x6pttztu1MJtz5ZJznWlGk2Ef+FmaFpuREqgBRY6e40UD joVDcGJu7RpPemXqpKf/6JXBu75K5niTWfLxr64WTZsRrksG3SFYIlrd/f3Zapnq voXFd4uv4J3oyaZnhUDLWeWkTiCfzq+uIe40lGOjhqKtNJLhOOiujExZjo9aMXJV zn78dqyaMcHKT24hUDjzX3ngA0I+BwAA } iopen: load to-binary decompress 64#{ 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 } isave: load to-binary decompress 64#{ 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 w7uEFST1O4wlrL6JCAbGI2I4nPMPqBor1gka7/+sSrm+9dwn8sC4XkaA2cnd9oVO CRbWHt/aO/u5jRLVdcX3ov5KKlV2DZR5lUUnDvf6O6ve7/vdWNyhs+VAbe1wz5A1 Qbsvt84DicDtoeG7bqmYpdekvT+2ZDdFjXKD45Js1mtGybXLRlfe3Ptyw0d+p1an f2g+2FJFqjSSyHpLEMtptEx4EuYoZK+qu6gfg9sgtJo8rs26tboTUhG2Rx4h+fTp U9wwpg1ly80BwRw3DOMbF1jvySaxE2HtHaU6Qbl4y8BLb92dQPxd438v2eCnK3W+ xowjOXfj3Wt1GhgZgp+h80tYv4xNY3oVVUiOnIYk3duzmf/kujZuSnyNrOQC0z+5 QF6n8C4q3gse5TpIo16gLRxz8+1rZUpkW9n4xy38zen5HvbBVlhBeLYbcUh4tUCa GDOFZzM461+jTDM317JMxhUojqak6xe2tYqzsspGWVllpLzO0i/keg92ipha2k6N pBtp61shbEyM9crNZxWxYW5MDjk3IygwziP7ekauyJ26ENwbt/JX3lpq/Y3vKZHT g9vwcYfGH23feppbVhsrj7MI1rW7J+YoLvXJRkJkxAsNLhA8nFpVbbm+sp2y02d6 fNSH0NJHj3Re8P48l4Bo6LdsuVnKoeJkDgfFyqQrOohdZdTSI9KCkbXuFkMpXCCd gDqx0D8XojisXeLUe5OMxpHoj74H8O12RNC9YZSmPcsWdKOncnlLzZ6uThw6Egen WhaqbLeVWYD872DhaNoV5ZHd+RNeJQG+fvGxgR30B2gkbXiDZRfUuRP5QUbgyYCb LowkXXnt2WnqVJdI4uS5NqveYS24uCYMGbGSF2B1DhWU1FijaFJ9s8xvpgxYHpfi 14yJZpazH4W+0GYA5Mlsk5Q0+Ocf4sapXOY/GSilvj4KAAA= } iprint: load 64#{ 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 plA2KNb8WDwAAAAASUVORK5CYII= } ihelp: load to-binary decompress 64#{ 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 } iquit: load 64#{ iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhk iAAAB69JREFUaIHtmEtsG8cZx3+zD+6SpmS4li1VMRQYQQzE9bsGahRoD0HQW4Cc cmmLoIfmkhTRxUFgIHCAGHAQIMqhSC9FUKAP95AejJzaumjspmmS1pEdB5FlO5bs WhZFS6KoRA8uuTOTAznUcrkkRclBLv6ADzv7mN3/b75vZnYGHti3a2IjlSzL+rXW +hcbrb9J00KI3ymlfsUmBMizZ89as7OzzMzMIKUkDEMqlUq9HIYhSimklCilCMMQ KSVaa5RSdQdQSnH+/PmWHxOiUea9e/cUYAM4GwSwPM8jlUqRTqepVCpYloVlWYRh WC9LKRFCIKWsC1FKIYSou9YarTWWZSUKjos33zeFjQJg2zaO49TF2raNUqrhXGuN bdsN9YxwU9ZaN4mNH9vZhgFc18VxnLpQ41GLn5toGAilVP0ZE4FW4lvBbBjAiHdd twEgSXS8HE0vU6dd67eLxKYAXNdtSB8TDVhr/Wi+m/yP9wnHcZpSaz3iNwXgum49 jeKtGDVzz7btJhgpZb3jJwGsJ402DADVVDAArT4QFW3SJg4YH5ni79p0Cv0JrgG/ /Cn8Ky7MQCQJTzqPCzNQrTpxpxSy2t41Ztt70g89dOH3cDQuKgpihlbjJsVMhzdH 46ZO9B1Jx+j96HyxbgDXdQs/eustnR0cbIJYD0wcLHrNiIrWT/LoM91HAHAzGfHD 115L9/T3n98dE9wuzAYm7vFotIpCUiQ2BKArFUShIH7w6quZU9u3szo21tTySZ5k rVq2U8tvDqBcJpiYQBSL4scvv0z+xRcJb9zoCLBeqKQWj19L6gMOwBnIef39A1rK FSEEem0IAK0Rtp3W5TI6CAiuXyc1NMT3n3+e/77yCrzwAuLhh7sC6O3tZdeuXczN zZHL5QiCoO080HEYtWDx2MmTAynfz2BZVeG1F2qq/9w6CFBBAFJSGh8ntXs3R599 lv+NjFAeHu4KAqoT4eDgIFu3bmV8fLwJoKt5QIGUc3Ms3biBXFwEx0HYNlgWIhoy rdFKVSE+/xzvkUc48swzfDIyQjA8DENDDQJa+fLyMufOnWNoaIi9e/fS39/fBNhq 3ohbXZ0ql9HlcvUYBHVXpRLKHEuleiR0ELD62We4QcChp58mNTKCuHVrXR1XCMHO nTvp6+vD8zwmJiY6duCOw6gul+vCdFRw1GvXdRDUgVevXMGTkgNPPok/MoJ1+/a6 Ou7g4CAHDhxgdHSUpaWltiPPuoZRFQToSqWhhXUNIhqF6H1zXLl0CV9rvvfEE3hv vNESwng2m+Xw4cOMjY1x+/ZtPM9r2fpJME19wERAl0qEhQJqdbUKoBTCsrDSaaxs FmvLlhqtqvYFpdBSgpSsXLpEZt8+9j/+OFdOn2bl5EnUjh1NwlzX5ejRo0xNTXH5 8mV83yedTjf8C3XqC4kA5XyeytgYlVwu8UEA4TjYW7di9/YifB9hWWgpqxCVCurL L1nJ56u/1rE/TOMDAwPMz88zOjpKKpXCdd0G4UkQ6wKQX32FDsOW4gF0GBLOzxPO z1cv1MKLZZE5coTZyUkm796lfOoUescOiCwfjU9PT9fXAZlMBq11wzIzaSjtOIwC oBTEloMdTSlwHDKHDlEoFLiVyxGcOAEDA/UIJJkQAs/zkFI2ie92PljrA2HYNYBw HNIHD1JYWOBWLsfKSy9BreWjAjqNSEnPxgE6pZDQUnYFIByH9P79LBSLTM7MsHT8 OLqvDxFZda13Zm4H2g7aAAjAU+k0/rFjpMrltRlX67o7ts3S+++jw7Aqft8+CsUi k/k8C8PDiO3bsSIdN2lU2QxENFJNABKuj7/33ncRYknXthu11uZJAXzn4LFj9Zb3 H3uMQrHIrdlZ7j33HKKvDyeypZI0BN4PgFZ9QP8cniIMU0CSu3+Av6pKpR/bxn/0 UQqLi/y/UGDp+HHUli04kVaPTzxJ2yubjUITACAjHlKdoU0NXQ2Ixt+zh4ViUY/d uSN633wTp6cHd2mpYYUV/3ir7ZZoSmwmCmZeDoEKUK55UPMSsCpAIyXFYlFN3rmz eBJI796N7/sN+0PRxbzruusSt7KywsWLF9s+E/+tiEfAWKUWARWJhAPYAvTc1JTO 5fOL5+GpGbhgdqU9z2ta9yZNTnFXSnH16lWuX78W2xci0autn5xCUVO1Vrdq9xzA 0jCYy+e5Aj95G24CpFIpfN+nVCrVdxdM67QT77oud6YmGB39kFKphO0I3Nhvc6vU SrJWG1sqkk4Ap0vwzuvwqXkgk0mjlGJ1dbXFKxpFZDIZ7k7f5MOP/kFxcR4hBCnf pEX74decR4+dABrsZ3AiSVwn4QDZbJaF4jTn/nmG6Vx1weOnqyLj4k2dThBdAySL bHevunBfLS1w4YM/8sXNUYQQeL4RZP6TZEPqxYUnle8bQCvhPT09ICr85+O/cOnT vzUIjwpac9V0vZXwbwzAtLjvO3xy+V0+Hn2HMCzjpVsL6qbcDmLjAKIa8m3btrEl m2Hs2t/54KO3KVeWcRxw3fZ7PN0ek8RvGCCVSiGAnp4sNyf/zbvnfsPych5hg2e3 /uhmyvcVANBTuVFx8cpvmV+4BoCXbj0yfQPXu1x5xcyyrD/XXvKteCqVOrMpgAf2 wNbsayq8tOJH+DD8AAAAAElFTkSuQmCC } iemoti: load to-binary decompress 64#{ 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 XNZ/ATVRTuDKCQAA } ifleche: load 64#{ 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 RK5CYII= } isudo: load 64#{ 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 N/sHlUqJZVP1FiwAAAAASUVORK5CYII= } ] ; ; Sauve la grille f_Save: func [myface] [ grille: copy [] file: request-file/title/filter/only/save/keep "Save your grid..." "Save" ["*.txt"] if not none? file [ foreach sub-face myface/pane [ insert tail grille get-face sub-face ] if error? try [save file grille] [alert "File is locked. I can't save it !!!"] ] ] ; ; charge la grille f_Load: func [myface] [ grille: copy [] file: request-file/title/filter/only/keep "Select your grid file..." "Choose" ["*.txt"] if not none? file [ grille: load file grilleidx: 1 foreach item grille [ attempt [ set-face myface/pane/:grilleidx/font/color: black set-face myface/pane/:grilleidx/edge/color: black set-face myface/pane/:grilleidx/edge/size: 1x1 set-face myface/pane/:grilleidx item ] grilleidx: grilleIdx + 1 ] ] ] ; ; Initialise la grille f_Reset: func [myface] [ clear-face myface foreach sub-face myface/pane [sub-face/font/color: black] ] ; ; Charge en table la grille f_Charge: func [myface] [ grid: to-hash copy [] gridtmp: to-hash copy [] i: 0 foreach sub-face myface/pane [ i: i + 1 insert tail gridtmp get-face sub-face if i > 8 [ insert/only tail grid gridtmp gridtmp: copy [] i: 0 ] if empty? get-face sub-face [ sub-face/font/color: blue ] ] unset gridtmp return grid ] ; ; Go f_go: func [mode myface] [ if error? try [ quiet?: either (mode = "quiet") [true] [false] set-face info __SOLVING1 startTime: now/time/precise grid: f_Charge myface f_Compute quiet? myface grid finishTime: now/time/precise tmp: (finishtime - starttime) tmp: (tmp/hour * 3600) + (tmp/minute * 60) + tmp/second munit: either (tmp > 1) [" seconds"] [" second"] mpass: either (pass > 1) [" passes"] [" pass"] mXtrapol: either (Xtrapol > 1) [" extrapolations"] [" extrapolation"] emoti/image: iemoti show emoti set-face info rejoin ["Done in " tmp munit ", " pass mpass ", " Xtrapol mXtrapol] ][ set-face info "Error !!!" alert "I have a problem... Please check the grid" ] ] ; ; Verbose/quiet mode f_compute: func [quiet? myface grid] [ pass: 0 Xtrapol: 0 quiet: copy[quiet?] grid: f_Logic quiet myface grid if (not finished? grid) [grid: f_Compute5 quiet? myface grid] if quiet? [ idx: 0 foreach item Grid [ foreach item1 item [ idx: idx + 1 if (empty? get-face myface/pane/:idx) [set-face myface/pane/:idx item1] ] ] ] ] f_Logic: func [quiet myface grid] [ until [ pass: pass + 1 if (not quiet?) [set-face info join __SOLVING pass] SolvedCells: 0 grid: f_Compute1 quiet? myface grid if (not finished? grid) [grid: f_Compute2 quiet? myface grid] if (not finished? grid) [grid: f_Compute3 quiet? myface grid] if (not finished? grid) [grid: f_Compute4 quiet? myface grid] equal? SolvedCells 0 ] pass: pass - 1 ; on ne compte pas le dernier passage qui ne positionne aucun chiffre return grid ] ; ; 1 => les lignes f_compute1: func [quiet? myface grid] [ savCol: savLigne: 0 trouve: true forever [ if (not trouve) [break] trouve: false for ligne 1 9 1 [ for num 1 9 1 [ cpteur: 0 for col 1 9 1 [ if empty? grid/:ligne/:col [ if (insertOk? grid ligne col num) [ cpteur: cpteur + 1 savCol: copy to-string col if (not quiet?) [savCell: copy to-string (((ligne - 1) * 9) + col)] ] ] ] if cpteur = 1 [ grid/:ligne/(to-integer :savCol): to-string num if (not quiet?) [set-face myface/pane/(to-integer :savCell) to-string num] solvedCells: solvedCells + 1 trouve: true ] savCol: savLigne: 0 ] ] ] return grid ] ; ; 2 => les colonnes f_compute2: func [quiet? myface grid] [ savCell: savLigne: 0 trouve: true forever [ if (not trouve) [break] trouve: false for col 1 9 1 [ for num 1 9 1 [ cpteur: 0 for ligne 1 9 1 [ if empty? grid/:ligne/:col [ if (insertOk? grid ligne col num) [ cpteur: cpteur + 1 savLigne: copy to-string ligne if (not quiet?) [savCell: copy to-string (((ligne - 1) * 9) + col)] ] ] ] if cpteur = 1 [ savLigne: to-integer savLigne grid/:savLigne/:col: to-string num if (not quiet?) [set-face myface/pane/(to-integer :savCell) to-string num] solvedCells: solvedCells + 1 trouve: true ] savCell: savLigne: 0 ] ] ] return grid ] ; ; 3 => les régions f_compute3: func [quiet? myface grid] [ savCol: savCell: savLigne: 0 trouve: true forever [ if (not trouve) [break] trouve: false for boucle 1 9 3 [ for num 1 9 1 [ cpteur: 0 for ligne boucle (boucle + 2) 1 [ for col boucle (boucle + 2) 1 [ if empty? grid/:ligne/:col [ if (insertOk? grid ligne col num) [ cpteur: cpteur + 1 savCol: copy to-string col savLigne: copy to-string ligne if (not quiet?) [savCell: copy to-string (((ligne - 1) * 9) + col)] ] ] ] ] if cpteur = 1 [ savLigne: to-integer savLigne grid/:savLigne/(to-integer :savCol): to-string num if (not quiet?) [set-face myface/pane/(to-integer :savCell) to-string num] solvedCells: solvedCells + 1 trouve: true ] savCell: savCol: savLigne: 0 ] ] ] return grid ] ; ; 4 => les cellules f_compute4: func [quiet? myface grid] [ trouve: true forever [ if (not trouve) [break] trouve: false idx: 0 for ligne 1 9 1 [ for col 1 9 1 [ if (not quiet?) [idx: idx + 1] if empty? grid/:ligne/:col [ cpteur: 0 for num 1 9 1 [ if (insertOk? grid ligne col num) [ cpteur: cpteur + 1 either (cpteur = 1) [ grid/:ligne/:col: to-string num if (not quiet?) [set-face myface/pane/:idx num] ] [ grid/:ligne/:col: "" if (not quiet?) [set-face myface/pane/:idx ""] break ] ] ] if (cpteur = 1) [trouve: true solvedCells: solvedCells + 1] ] ] ] ] return grid ] ; ; 5 => les différentes possibilités f_compute5: func [quiet? myface grid] [ theGrid: to-hash copy [] theNum: to-hash copy [] theCol: to-hash copy [] theLigne: to-hash copy [] theCell: to-hash copy [] ligne: col: num: 0 while [not finished? grid] [ ligne: ligne + 1 while [col < 9] [ col: col + 1 if empty? grid/:ligne/:col [ while [num < 9] [ num: num + 1 if (insertOk? grid ligne col num) [ append/only theGrid copy/deep grid grid/:ligne/:col: copy to-string num append theLigne copy to-string (ligne) append theNum copy to-string num append theCol copy to-string (col - 1) if (not quiet?) [ savCell: copy to-string (((ligne - 1) * 9) + col) append theCell copy savCell set-face myface/pane/(to-integer :savCell) to-string num ] Xtrapol: Xtrapol + 1 grid: f_Logic true myface grid if (finished? grid) [return grid] num: 0 break ] ] if (num = 9) [ Xtrapol: Xtrapol - 1 grid: last theGrid remove back tail theGrid col: to-integer last theCol remove back tail theCol Ligne: to-integer last theLigne remove back tail theLigne num: to-integer last theNum remove back tail theNum if (not quiet?) [ savCell: to-integer last theCell remove back tail theCell set-face myface/pane/(to-integer :savCell) " " ] ] ] ] col: 0 if (ligne = 9) [ligne: col: num: 0] ] return grid ] ; Insertion possible insertOk?: func [grid ligne col num] [ if (found? find grid/:ligne to-string num) [return false] for i 1 9 1 [if (found? find grid/:i/:col to-string num) [return false]] lig1: 7 if ligne < 7 [lig1: 4] if ligne < 4 [lig1: 1] col1: 7 if col < 7 [col1: 4] if col < 4 [col1: 1] ligmax: lig1 + 2 colmax: col1 + 2 for i lig1 ligmax 1 [for i1 col1 colmax 1 [if (found? find grid/:i/:i1 to-string num) [return false]]] return true ] ; ; cases vides ? finished?: func [grid] [ for x 1 9 1 [for y 1 9 1 [if (not-equal? length? grid/:x/:y 1) [return false]]] return true ] ; ; Impression f_Print: func [face] [ tmpDir: get-env "temp" if none? tmpdir [tmpDir: make-dir join system/user/home %temp] if ((equal? (last tmpdir) #"/") or (equal? (last tmpDir) #"\")) [remove back tail tmpDir] tmpPic: to-file to-rebol-file to-local-file join tmpDir "/tmpPic.png" save/png tmpPic to-image thePanel tmpHtml: to-file to-rebol-file to-local-file join tmpDir "/tmpHtml.html" write tmpHtml rejoin [{^/
^/