Objective Caml Sudoku

526 views

Published on

Sudoku in Objective Caml. Sudoku è un gioco di logica nel quale al giocatore o solutore viene proposta una griglia di 9×9 celle, ciascuna delle quali può contenere un numero da 1 a 9, oppure essere vuota; la griglia è suddivisa in 9 righe orizzontali, 9 colonne verticali e, da bordi in neretto, in 9 "sottogriglie", chiamate regioni, di 3×3 celle contigue. Scopo del gioco è quello di riempire le caselle bianche con numeri da 1 a 9, in modo tale che in ogni riga, colonna e regione siano presenti tutte le cifre da 1 a 9 e, pertanto, senza ripetizioni.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
526
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Objective Caml Sudoku

  1. 1. Università degli Studi di Perugia LAUREA SPECIALISTICA IN INFORMATICA Anno Accademico 2007/2008 Programmazione Avanzata Progetto: OSudoku Studenti: Manfucci Andrea Ciambelli Davide 1
  2. 2. Introduzione Sudoku è un gioco di logica nel quale al giocatore o solutore viene proposta una griglia di 9×9 celle, ciascuna delle quali può contenere un numero da 1 a 9, oppure essere vuota; la griglia è suddivisa in 9 righe orizzontali, 9 colonne verticali e, da bordi in neretto, in 9 "sottogriglie", chiamate regioni, di 3×3 celle contigue. Scopo del gioco è quello di riempire le caselle bianche con numeri da 1 a 9, in modo tale che in ogni riga, colonna e regione siano presenti tutte le cifre da 1 a 9 e, pertanto, senza ripetizioni. Problema Data una istanza di Sudoku (griglia proposta o matrice incompleta) trasformarla in modo da ottenere una matrice completa (matrice priva di celle bianche). Studio della soluzione Come primo passo andiamo a definire le strutture dati per l'implementazione del programma. Il programma è composto da 6 funzioni principali: Definzione Matrice:  let matrice = Array.init 9 (fun _ ­> input_line stdin) Tipo: val matrice : string array =     [|"520083070"; "308070000"; "170000003"; "060004700"; "403701506"; "001600040";  "600000017"; "000010205"; "010260034"|]  La scacchiera del Sudoku è rappresentata da un array di stringhe mantenuto in una variabile globale matrice. Inizialmente il programma legge 9 linee di input composte da 9 caratteri ciascuna per riempire la scacchiera con i valori classici del Sudoku (numeri da 1 a 9). Ad ogni cella vuota corrisponde uno zero. Definizione Stampa: let stampa() = Array.iter print_endline matrice;; Tipo: val stampa : unit ­> unit = <fun>  Questa è la funzione che permette di visualizzare in output sia la matrice di partenza che quella risultante. Da notare le parentesi su stampa perchè nonostante sia senza parametri gli viene passato implicitamente l'array matrice. 2
  3. 3. Definzione Controllo: let rec controllo ?(i=0) colonna riga n =    i<9 && (matrice.(riga).[i] = n  || matrice.(i).[colonna] = n   || matrice.(riga/3*3 + i/3).[colonna/3*3 + i mod 3] = n  || controllo ~i:(i+1) colonna riga n);; Tipo: val controllo : ?i:int ­> int ­> int ­> char ­> bool = <fun>  Questa è una delle funzioni più importanti del programma perchè verifica se il numero che si vuole inserire nella scacchiera rispetta i vincoli del gioco (relativi all'unicità del numero in questione su una singola colonna, una singola riga e all'interno della sottogriglia 3x3). La funzione controllo accetta in ingresso due parametri di tipo intero (colonna e riga) e un char n che rappresenta il numero da controllare. Definizione Ferma: let rec ferma fx corretto inf sup = if (inf = sup) then corretto  else ferma fx (fx corretto inf) (inf+1) sup Tipo: val ferma : ('a ­> int ­> 'a) ­> 'a ­> int ­> int ­> 'a = <fun>  La funzione ferma permette l'inserimento di un numero nella scacchiera sostituendo il numero precedentemente inserito poiché errato. La funzione accetta in input 4 parametri: una funzione fx, un char che rappresenta il numero al passo precedente, due interi inf ed sup e restituisce il numero corretto da inserire nella scacchiera. Definizione Cerca: let rec cerca ?(colonna=0) ?(riga=0) f soluzioni = match colonna, riga with      9, riga ­> cerca ~colonna:0 ~riga:(riga+1) f soluzioni    | 0, 9 ­> f soluzioni    | colonna, riga ­>        if matrice.(riga).[colonna] <> '0' then cerca ~colonna:(colonna+1)  ~riga f soluzioni  else ferma (fun attuale n_intero ­>                  let n_char = Char.chr (n_intero + 48)  in if controllo colonna riga n_char then attuale  else (matrice.(riga).[colonna] <­ n_char;                     let back = cerca ~colonna:(colonna+1) ~riga f attuale  in matrice.(riga).[colonna] <­ '0'; back)) soluzioni 1 10;; Tipo: val cerca : ?colonna:int ­> ?riga:int ­> ('a ­> 'a) ­> 'a ­> 'a = <fun>  3
  4. 4. Cerca è la funzione che esamina tutte le posizioni della scacchiera in successione provando i numeri da 1 a 9 in ogni cella vuota. Verifica tre possibili casi: ● il caso in cui la riga è finita e quindi effettua la ricorsione sulla riga successiva; ● il caso in cui la scacchiera è stata visionata completamente e quindi si è trovata una soluzione; ● l'ultimo caso è quello generale in cui riga e colonna hanno dei valori diversi dai precedenti. Definizione: let () = Printf.printf "%d soluzione(i)n" (cerca (fun i ­>  stampa(); i+1) 0);; Quest'ultima funzione è quella relativa alle chiamate di cerca e stampa che mostrano in sostanza tutte le possibili soluzioni del gioco. Esempio Il programma da noi realizzato, una volta lanciato, attende in input una griglia del tipo: 520083070 308070000 170000003 060004700 403701506 001600040 600000017 000010205 010260034 dove a celle vuote corrisponde il valore 0. L'output proveniente da questa particolare griglia è il seguente: 526483179 348179652 179526483 265834791 483791526 791652348 652348917 834917265 917265834 Si può notare facilmente che la griglia restituita dal programma è una soluzione corretta del gioco. 4

×