|
@@ -0,0 +1,120 @@
|
|
|
|
|
+package solver
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "flag"
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "log"
|
|
|
|
|
+ "os"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+func (solver *Solver) parse_flags() {
|
|
|
|
|
+
|
|
|
|
|
+ // Define variables
|
|
|
|
|
+ var row1 string
|
|
|
|
|
+ var row2 string
|
|
|
|
|
+ var row3 string
|
|
|
|
|
+ var row4 string
|
|
|
|
|
+ var row5 string
|
|
|
|
|
+ var row6 string
|
|
|
|
|
+ var row7 string
|
|
|
|
|
+ var row8 string
|
|
|
|
|
+ var row9 string
|
|
|
|
|
+
|
|
|
|
|
+ // Define parameters
|
|
|
|
|
+ flag.StringVar(&row1, "row1", "000000000", "1st row of the sudoku puzzle.")
|
|
|
|
|
+ flag.StringVar(&row2, "row2", "000000000", "2nd row of the sudoku puzzle.")
|
|
|
|
|
+ flag.StringVar(&row3, "row3", "000000000", "4rd row of the sudoku puzzle.")
|
|
|
|
|
+ flag.StringVar(&row4, "row4", "000000000", "4th row of the sudoku puzzle.")
|
|
|
|
|
+ flag.StringVar(&row5, "row5", "000000000", "5th row of the sudoku puzzle.")
|
|
|
|
|
+ flag.StringVar(&row6, "row6", "000000000", "6th row of the sudoku puzzle.")
|
|
|
|
|
+ flag.StringVar(&row7, "row7", "000000000", "7th row of the sudoku puzzle.")
|
|
|
|
|
+ flag.StringVar(&row8, "row8", "000000000", "8th row of the sudoku puzzle.")
|
|
|
|
|
+ flag.StringVar(&row9, "row9", "000000000", "9th row of the sudoku puzzle.")
|
|
|
|
|
+
|
|
|
|
|
+ // Print additional help data
|
|
|
|
|
+ flag.Usage = func() {
|
|
|
|
|
+ fmt.Fprintf(flag.CommandLine.Output(), "Usages of %s:\n", os.Args[0])
|
|
|
|
|
+ fmt.Fprintf(flag.CommandLine.Output(), "\nPut every row of a Sudoku puzzle as paramters.\nUse '0' for what is currently blank in the puzzle you wish to solve.\n\n")
|
|
|
|
|
+ fmt.Fprintf(flag.CommandLine.Output(), "Example: %s -row1 ... -row2 ... -row3 ... (etc)\n\n", os.Args[0])
|
|
|
|
|
+ flag.PrintDefaults()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Parse the flags
|
|
|
|
|
+ flag.Parse()
|
|
|
|
|
+
|
|
|
|
|
+ // Validate the row (never trust user input)
|
|
|
|
|
+ solver.validate_row("row1", row1)
|
|
|
|
|
+ solver.validate_row("row2", row2)
|
|
|
|
|
+ solver.validate_row("row3", row3)
|
|
|
|
|
+ solver.validate_row("row4", row4)
|
|
|
|
|
+ solver.validate_row("row5", row5)
|
|
|
|
|
+ solver.validate_row("row6", row6)
|
|
|
|
|
+ solver.validate_row("row7", row7)
|
|
|
|
|
+ solver.validate_row("row8", row8)
|
|
|
|
|
+ solver.validate_row("row9", row9)
|
|
|
|
|
+
|
|
|
|
|
+ // Put entries in into the struct
|
|
|
|
|
+ solver.row1 = row1
|
|
|
|
|
+ solver.row2 = row2
|
|
|
|
|
+ solver.row3 = row3
|
|
|
|
|
+ solver.row4 = row4
|
|
|
|
|
+ solver.row5 = row5
|
|
|
|
|
+ solver.row6 = row6
|
|
|
|
|
+ solver.row7 = row7
|
|
|
|
|
+ solver.row8 = row8
|
|
|
|
|
+ solver.row9 = row9
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (solver *Solver) validate_row(name string, row string) {
|
|
|
|
|
+
|
|
|
|
|
+ var found bool
|
|
|
|
|
+ var double bool
|
|
|
|
|
+ count := make(map[rune]int)
|
|
|
|
|
+
|
|
|
|
|
+ // 1. Make sure the row is 9 in length
|
|
|
|
|
+ if len(row) != 9 {
|
|
|
|
|
+ log.Printf("ERROR: Invalid length of %s; %s must be 9 numbers", name, row)
|
|
|
|
|
+ os.Exit(1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. Ensure all digits are numbers
|
|
|
|
|
+ for _, value := range row {
|
|
|
|
|
+ found = solver.valid_char(value)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if !found {
|
|
|
|
|
+ log.Printf("ERROR: Invalid character of %s; %s must be 9 numbers", name, row)
|
|
|
|
|
+ os.Exit(1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. Ensure all digits (except zero) are there only once
|
|
|
|
|
+ for _, digits := range row {
|
|
|
|
|
+ count[digits] = count[digits] + 1
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for key, value := range count {
|
|
|
|
|
+ if value > 1 && key != 48 {
|
|
|
|
|
+ double = true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if double {
|
|
|
|
|
+ log.Printf("ERROR: Double character of %s; %s numbers between 1 and 9 may only be entered once", name, row)
|
|
|
|
|
+ os.Exit(1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (solver *Solver) valid_char(char rune) bool {
|
|
|
|
|
+ var valid bool
|
|
|
|
|
+ decvals := [10]int{48, 49, 50, 51, 52, 53, 54, 55, 56, 57}
|
|
|
|
|
+
|
|
|
|
|
+ for _, value := range decvals {
|
|
|
|
|
+ if char == rune(value) {
|
|
|
|
|
+ valid = true
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return valid
|
|
|
|
|
+}
|