| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- package solver
- import (
- "flag"
- "fmt"
- "log"
- "os"
- "runtime"
- )
- 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
- var split int
- var part int
- // 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.")
- flag.IntVar(&solver.numcpus, "numcpu", runtime.NumCPU(), "Number of CPU cores to assign to this task.")
- flag.IntVar(&split, "split", 1, "Split the tasks in n parts. This depends on the availability of the first row.")
- flag.IntVar(&part, "part", 1, "Process part x in n parts. Cannot be lower than 1, or higher than specified in split.")
- // Parse the flags
- flag.Parse()
- // Process any changes to the CPU usage.
- if solver.numcpus <= 0 {
- log.Printf("ERROR: Number of CPU cores must be 1 or higher.\n\n")
- solver.print_Usage()
- os.Exit(1)
- }
- if solver.numcpus != runtime.NumCPU() {
- runtime.GOMAXPROCS(solver.numcpus)
- }
- // Process rows
- if row1 == "000000000" || row2 == "000000000" || row3 == "000000000" || row4 == "000000000" || row5 == "000000000" || row6 == "000000000" || row7 == "000000000" || row8 == "000000000" || row9 == "000000000" {
- log.Printf("ERROR: All parameters must be entered.\n\n")
- solver.print_Usage()
- os.Exit(1)
- }
- // 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
- // Process workload splitting
- // Ensure split and part are 1 or higher
- if split <= 0 || part <= 0 {
- log.Printf("ERROR: '-split' and '-part' need to be 1 or higher.\n")
- solver.print_Usage()
- os.Exit(1)
- }
- // Ensure part is between 1 and split
- if part > split {
- log.Printf("ERROR: '-part' cannot be bigger than `-split`.\n")
- solver.print_Usage()
- os.Exit(1)
- }
- solver.split = split
- solver.part = part
- }
- 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\n\n", name, row)
- solver.print_Usage()
- 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\n\n", name, row)
- solver.print_Usage()
- 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\n\n", name, row)
- solver.print_Usage()
- 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
- }
- func (solver *Solver) print_Usage() {
- fmt.Fprintf(flag.CommandLine.Output(), "Usage 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()
- }
|