SlideShare ist ein Scribd-Unternehmen logo
1 von 4
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Mehr von Davide Ciambelli

SEMrush SEO Fundamentals Exam
SEMrush SEO Fundamentals ExamSEMrush SEO Fundamentals Exam
SEMrush SEO Fundamentals ExamDavide Ciambelli
 
Google Analytics for Beginners
Google Analytics for BeginnersGoogle Analytics for Beginners
Google Analytics for BeginnersDavide Ciambelli
 
Advanced Google Analytics
Advanced Google Analytics Advanced Google Analytics
Advanced Google Analytics Davide Ciambelli
 
Ecommerce Analytics: From Data to Decision
Ecommerce Analytics: From Data to DecisionEcommerce Analytics: From Data to Decision
Ecommerce Analytics: From Data to DecisionDavide Ciambelli
 
Google Tag Manager Fundamentals
Google Tag Manager Fundamentals Google Tag Manager Fundamentals
Google Tag Manager Fundamentals Davide Ciambelli
 
Abilitazione all'utilizzo dei dispositivi DAE
Abilitazione all'utilizzo dei dispositivi DAEAbilitazione all'utilizzo dei dispositivi DAE
Abilitazione all'utilizzo dei dispositivi DAEDavide Ciambelli
 
Google Tag Manager Fundamentals
Google Tag Manager FundamentalsGoogle Tag Manager Fundamentals
Google Tag Manager FundamentalsDavide Ciambelli
 
Un viaggio chiamato LibreUmbria
Un viaggio chiamato LibreUmbriaUn viaggio chiamato LibreUmbria
Un viaggio chiamato LibreUmbriaDavide 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)
Guida introduttiva di Google all’ottimizzazione per motori di ricerca (SEO)Davide Ciambelli
 
Dharma Initiative pass card
Dharma Initiative pass cardDharma Initiative pass card
Dharma Initiative pass cardDavide Ciambelli
 
Qnap turbo nas hardware manual
Qnap turbo nas hardware manualQnap turbo nas hardware manual
Qnap turbo nas hardware manualDavide Ciambelli
 
Z750 manuale di assemblaggio
Z750 manuale di assemblaggioZ750 manuale di assemblaggio
Z750 manuale di assemblaggioDavide Ciambelli
 
The 2009 Simulated Car Racing Championship
The 2009 Simulated Car Racing ChampionshipThe 2009 Simulated Car Racing Championship
The 2009 Simulated Car Racing ChampionshipDavide Ciambelli
 
Linux Bash Shell Cheat Sheet for Beginners
Linux Bash Shell Cheat Sheet for BeginnersLinux Bash Shell Cheat Sheet for Beginners
Linux Bash Shell Cheat Sheet for BeginnersDavide Ciambelli
 
Sistema elaboratore in multiprogrammazione
Sistema elaboratore in multiprogrammazioneSistema elaboratore in multiprogrammazione
Sistema elaboratore in multiprogrammazioneDavide Ciambelli
 
Cutting stock bidimensionale
Cutting stock bidimensionaleCutting stock bidimensionale
Cutting stock bidimensionaleDavide Ciambelli
 
Pool di macchine Condor con utilizzo di Checkpoint Server
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 ServerDavide Ciambelli
 

Mehr von Davide Ciambelli (20)

SEMrush SEO Fundamentals Exam
SEMrush SEO Fundamentals ExamSEMrush SEO Fundamentals Exam
SEMrush SEO Fundamentals Exam
 
Google Analytics for Beginners
Google Analytics for BeginnersGoogle Analytics for Beginners
Google Analytics for Beginners
 
Advanced Google Analytics
Advanced Google Analytics Advanced Google Analytics
Advanced Google Analytics
 
Ecommerce Analytics: From Data to Decision
Ecommerce Analytics: From Data to DecisionEcommerce Analytics: From Data to Decision
Ecommerce Analytics: From Data to Decision
 
Google Tag Manager Fundamentals
Google Tag Manager Fundamentals Google Tag Manager Fundamentals
Google Tag Manager Fundamentals
 
Eccellenze in digitale
Eccellenze in digitaleEccellenze in digitale
Eccellenze in digitale
 
Abilitazione all'utilizzo dei dispositivi DAE
Abilitazione all'utilizzo dei dispositivi DAEAbilitazione all'utilizzo dei dispositivi DAE
Abilitazione all'utilizzo dei dispositivi DAE
 
Google Tag Manager Fundamentals
Google Tag Manager FundamentalsGoogle Tag Manager Fundamentals
Google Tag Manager Fundamentals
 
Certificazione AdWords
Certificazione AdWordsCertificazione AdWords
Certificazione AdWords
 
Un viaggio chiamato LibreUmbria
Un viaggio chiamato LibreUmbriaUn viaggio chiamato LibreUmbria
Un viaggio chiamato LibreUmbria
 
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)
Guida introduttiva di Google all’ottimizzazione per motori di ricerca (SEO)
 
Il codice da lopins
Il codice da lopinsIl codice da lopins
Il codice da lopins
 
Dharma Initiative pass card
Dharma Initiative pass cardDharma Initiative pass card
Dharma Initiative pass card
 
Qnap turbo nas hardware manual
Qnap turbo nas hardware manualQnap turbo nas hardware manual
Qnap turbo nas hardware manual
 
Z750 manuale di assemblaggio
Z750 manuale di assemblaggioZ750 manuale di assemblaggio
Z750 manuale di assemblaggio
 
The 2009 Simulated Car Racing Championship
The 2009 Simulated Car Racing ChampionshipThe 2009 Simulated Car Racing Championship
The 2009 Simulated Car Racing Championship
 
Linux Bash Shell Cheat Sheet for Beginners
Linux Bash Shell Cheat Sheet for BeginnersLinux Bash Shell Cheat Sheet for Beginners
Linux Bash Shell Cheat Sheet for Beginners
 
Sistema elaboratore in multiprogrammazione
Sistema elaboratore in multiprogrammazioneSistema elaboratore in multiprogrammazione
Sistema elaboratore in multiprogrammazione
 
Cutting stock bidimensionale
Cutting stock bidimensionaleCutting stock bidimensionale
Cutting stock bidimensionale
 
Pool di macchine Condor con utilizzo di Checkpoint Server
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
 

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