Objective Caml Sudoku

Davide Ciambelli
Davide CiambelliConsultant um Like Reply

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.

Università degli Studi di Perugia

LAUREA SPECIALISTICA IN INFORMATICA


      Anno Accademico 2007/2008




   Programmazione Avanzata
               Progetto:

               OSudoku

               Studenti:

            Manfucci Andrea

            Ciambelli Davide

                                       1
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
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
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

Recomendados

Problema 2 (indirizzo pni) von
Problema 2 (indirizzo pni)Problema 2 (indirizzo pni)
Problema 2 (indirizzo pni)Deiesy
962 views3 Folien
Certificazione esami triennale von
Certificazione esami triennaleCertificazione esami triennale
Certificazione esami triennaleDavide Ciambelli
280 views2 Folien
Social Network Analysis for Journalists Using the Twitter API von
Social Network Analysis for Journalists Using the Twitter APISocial Network Analysis for Journalists Using the Twitter API
Social Network Analysis for Journalists Using the Twitter APIDavide Ciambelli
1.5K views1 Folie
Google analytics platform principles certificate von
Google analytics platform principles certificateGoogle analytics platform principles certificate
Google analytics platform principles certificateDavide Ciambelli
407 views1 Folie
Instance-based learning and Numeric prediction von
Instance-based learning and Numeric predictionInstance-based learning and Numeric prediction
Instance-based learning and Numeric predictionDavide Ciambelli
433 views23 Folien
Dossier Dharma Initiative von
Dossier Dharma InitiativeDossier Dharma Initiative
Dossier Dharma InitiativeDavide Ciambelli
360 views2 Folien

Más contenido relacionado

Más de Davide Ciambelli

SEMrush SEO Fundamentals Exam von
SEMrush SEO Fundamentals ExamSEMrush SEO Fundamentals Exam
SEMrush SEO Fundamentals ExamDavide Ciambelli
210 views1 Folie
Google Analytics for Beginners von
Google Analytics for BeginnersGoogle Analytics for Beginners
Google Analytics for BeginnersDavide Ciambelli
144 views1 Folie
Advanced Google Analytics von
Advanced Google Analytics Advanced Google Analytics
Advanced Google Analytics Davide Ciambelli
109 views1 Folie
Ecommerce Analytics: From Data to Decision von
Ecommerce Analytics: From Data to DecisionEcommerce Analytics: From Data to Decision
Ecommerce Analytics: From Data to DecisionDavide Ciambelli
95 views1 Folie
Google Tag Manager Fundamentals von
Google Tag Manager Fundamentals Google Tag Manager Fundamentals
Google Tag Manager Fundamentals Davide Ciambelli
111 views1 Folie
Eccellenze in digitale von
Eccellenze in digitaleEccellenze in digitale
Eccellenze in digitaleDavide Ciambelli
65 views1 Folie

Más de Davide Ciambelli(20)

Ecommerce Analytics: From Data to Decision von Davide Ciambelli
Ecommerce Analytics: From Data to DecisionEcommerce Analytics: From Data to Decision
Ecommerce Analytics: From Data to Decision
Davide Ciambelli95 views
Abilitazione all'utilizzo dei dispositivi DAE von Davide Ciambelli
Abilitazione all'utilizzo dei dispositivi DAEAbilitazione all'utilizzo dei dispositivi DAE
Abilitazione all'utilizzo dei dispositivi DAE
Davide Ciambelli249 views
Guida introduttiva di Google all’ottimizzazione per motori di ricerca (SEO) von Davide Ciambelli
Guida introduttiva di Google  all’ottimizzazione per motori di ricerca (SEO)Guida introduttiva di Google  all’ottimizzazione per motori di ricerca (SEO)
Guida introduttiva di Google all’ottimizzazione per motori di ricerca (SEO)
Davide Ciambelli690 views
The 2009 Simulated Car Racing Championship von Davide Ciambelli
The 2009 Simulated Car Racing ChampionshipThe 2009 Simulated Car Racing Championship
The 2009 Simulated Car Racing Championship
Davide Ciambelli1.5K views
Linux Bash Shell Cheat Sheet for Beginners von Davide Ciambelli
Linux Bash Shell Cheat Sheet for BeginnersLinux Bash Shell Cheat Sheet for Beginners
Linux Bash Shell Cheat Sheet for Beginners
Davide Ciambelli3.6K views
Sistema elaboratore in multiprogrammazione von Davide Ciambelli
Sistema elaboratore in multiprogrammazioneSistema elaboratore in multiprogrammazione
Sistema elaboratore in multiprogrammazione
Davide Ciambelli443 views
Pool di macchine Condor con utilizzo di Checkpoint Server von Davide Ciambelli
Pool di macchine Condor con utilizzo di Checkpoint ServerPool di macchine Condor con utilizzo di Checkpoint Server
Pool di macchine Condor con utilizzo di Checkpoint Server
Davide Ciambelli673 views

Objective Caml Sudoku

  • 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. 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. 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. 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