2025-01-27 21:47:35 +01:00
package flags
import (
"flag"
"fmt"
"log"
"os"
"runtime"
)
func ( flags * Flags ) ParseFlags ( ) {
// Define parameters
2025-01-27 23:46:26 +01:00
flag . StringVar ( & flags . Controller . Row1 , "row1" , "000000000" , "1st row of the sudoku puzzle." )
flag . StringVar ( & flags . Controller . Row2 , "row2" , "000000000" , "2nd row of the sudoku puzzle." )
flag . StringVar ( & flags . Controller . Row3 , "row3" , "000000000" , "4rd row of the sudoku puzzle." )
flag . StringVar ( & flags . Controller . Row4 , "row4" , "000000000" , "4th row of the sudoku puzzle." )
flag . StringVar ( & flags . Controller . Row5 , "row5" , "000000000" , "5th row of the sudoku puzzle." )
flag . StringVar ( & flags . Controller . Row6 , "row6" , "000000000" , "6th row of the sudoku puzzle." )
flag . StringVar ( & flags . Controller . Row7 , "row7" , "000000000" , "7th row of the sudoku puzzle." )
flag . StringVar ( & flags . Controller . Row8 , "row8" , "000000000" , "8th row of the sudoku puzzle." )
flag . StringVar ( & flags . Controller . Row9 , "row9" , "000000000" , "9th row of the sudoku puzzle." )
flag . IntVar ( & flags . Controller . NumCPUs , "numcpu" , runtime . NumCPU ( ) , "Number of CPU cores to assign to this task." )
flag . IntVar ( & flags . Controller . Split , "split" , 1 , "Split the tasks in n parts. This depends on the availability of the first row." )
flag . IntVar ( & flags . Controller . Part , "part" , 1 , "Process part x in n parts. Cannot be lower than 1, or higher than specified in split." )
2025-01-27 21:47:35 +01:00
// Parse the flags
flag . Parse ( )
// Process any changes to the CPU usage.
2025-01-27 23:46:26 +01:00
if flags . Controller . NumCPUs <= 0 {
2025-01-27 21:47:35 +01:00
log . Printf ( "ERROR: Number of CPU cores must be 1 or higher.\n\n" )
flags . printUsage ( )
os . Exit ( 1 )
}
2025-01-27 23:46:26 +01:00
if flags . Controller . NumCPUs != runtime . NumCPU ( ) {
runtime . GOMAXPROCS ( flags . Controller . NumCPUs )
2025-01-27 21:47:35 +01:00
}
// Process rows
2025-01-27 23:46:26 +01:00
if flags . Controller . Row1 == "000000000" || flags . Controller . Row2 == "000000000" || flags . Controller . Row3 == "000000000" || flags . Controller . Row4 == "000000000" || flags . Controller . Row5 == "000000000" || flags . Controller . Row6 == "000000000" || flags . Controller . Row7 == "000000000" || flags . Controller . Row8 == "000000000" || flags . Controller . Row9 == "000000000" {
2025-01-27 21:47:35 +01:00
log . Printf ( "ERROR: All parameters must be entered.\n\n" )
flags . printUsage ( )
os . Exit ( 1 )
}
// Validate the row (never trust user input)
2025-01-27 23:46:26 +01:00
flags . validateRow ( "row1" , flags . Controller . Row1 )
flags . validateRow ( "row2" , flags . Controller . Row2 )
flags . validateRow ( "row3" , flags . Controller . Row3 )
flags . validateRow ( "row4" , flags . Controller . Row4 )
flags . validateRow ( "row5" , flags . Controller . Row5 )
flags . validateRow ( "row6" , flags . Controller . Row6 )
flags . validateRow ( "row7" , flags . Controller . Row7 )
flags . validateRow ( "row8" , flags . Controller . Row8 )
flags . validateRow ( "row9" , flags . Controller . Row9 )
2025-01-27 21:47:35 +01:00
// Process workload splitting
// Ensure split and part are 1 or higher
2025-01-27 23:46:26 +01:00
if flags . Controller . Split <= 0 || flags . Controller . Part <= 0 {
2025-01-27 21:47:35 +01:00
log . Printf ( "ERROR: '-split' and '-part' need to be 1 or higher.\n" )
flags . printUsage ( )
os . Exit ( 1 )
}
// Ensure part is between 1 and split
2025-01-27 23:46:26 +01:00
if flags . Controller . Part > flags . Controller . Split {
2025-01-27 21:47:35 +01:00
log . Printf ( "ERROR: '-part' cannot be bigger than `-split`.\n" )
flags . printUsage ( )
os . Exit ( 1 )
}
}
func ( flags * Flags ) validateRow ( 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 )
flags . printUsage ( )
os . Exit ( 1 )
}
// 2. Ensure all digits are numbers
for _ , value := range row {
found = flags . validChar ( value )
}
if ! found {
log . Printf ( "ERROR: Invalid character of %s (%s), must be 9 numbers\n\n" , name , row )
flags . printUsage ( )
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 )
flags . printUsage ( )
os . Exit ( 1 )
}
}
func ( flags * Flags ) validChar ( char rune ) ( 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
}
func ( flags * Flags ) printUsage ( ) {
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 ( )
}