Просмотр исходного кода

Give each function its own file.

Sacha Ligthert 1 год назад
Родитель
Сommit
b83d6bdde4

+ 0 - 0
export/flat.go → export/PrintFlatSolutions.go


+ 1 - 1
export/human-readable.go → export/PrintHumanReadableSolutions.go

@@ -6,7 +6,7 @@ import (
 )
 
 // Print solutions into a human friendly format for in the console.
-func (export *Export) PrintHumanSolutions() {
+func (export *Export) PrintHumanReadableSolutions() {
 	for solutionIndex, solution := range export.Controller.Solutions {
 		log.Printf("\nSolution #%d:", solutionIndex+1)
 		fmt.Println("╔═══════════╗")

+ 0 - 70
flags/parse.go → flags/ParseFlags.go

@@ -2,7 +2,6 @@ package flags
 
 import (
 	"flag"
-	"fmt"
 	"log"
 	"os"
 	"runtime"
@@ -83,72 +82,3 @@ func (flags *Flags) ParseFlags() {
 	}
 
 }
-
-// Validate if a row is properly set.
-// This check for:
-// - Correct length
-// - Correct numbers
-// - Numbers only present once
-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)
-	}
-
-}
-
-// Validate if the char provided is 0-9
-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
-}
-
-// Print help information for the end-user
-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()
-}

+ 28 - 0
flags/printUsage.go

@@ -0,0 +1,28 @@
+package flags
+
+import (
+	"flag"
+	"fmt"
+	"os"
+)
+
+// Validate if the char provided is 0-9
+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
+}
+
+// Print help information for the end-user
+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()
+}

+ 54 - 0
flags/validateRow.go

@@ -0,0 +1,54 @@
+package flags
+
+import (
+	"log"
+	"os"
+)
+
+// Validate if a row is properly set.
+// This check for:
+// - Correct length
+// - Correct numbers
+// - Numbers only present once
+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)
+	}
+
+}

+ 1 - 1
main.go

@@ -48,7 +48,7 @@ func main() {
 	// Print the valid solutions
 	switch controller.Output {
 	case "human":
-		export.PrintHumanSolutions()
+		export.PrintHumanReadableSolutions()
 	case "flat":
 		export.PrintFlatSolutions()
 	}

+ 24 - 0
solver/CheckCombinations.go

@@ -0,0 +1,24 @@
+package solver
+
+// Iterate through all combination of blocks and validate them.
+func (solver *Solver) CheckCombinations() {
+	for rows1Index := range solver.row1s {
+		for rows2Index := range solver.row2s {
+			for rows3Index := range solver.row3s {
+				for rows4Index := range solver.row4s {
+					for rows5Index := range solver.row5s {
+						for rows6Index := range solver.row6s {
+							for rows7Index := range solver.row7s {
+								for rows8Index := range solver.row8s {
+									for rows9Index := range solver.row9s {
+										go solver.validator(rows1Index, rows2Index, rows3Index, rows4Index, rows5Index, rows6Index, rows7Index, rows8Index, rows9Index)
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}

+ 0 - 0
solver/blocks.go → solver/LoadBlocks.go


+ 27 - 0
solver/PopulateBlocks.go

@@ -0,0 +1,27 @@
+package solver
+
+import (
+	"log"
+	"time"
+)
+
+// Find all possible blocks that can be used to find a solution.
+func (solver *Solver) PopulateBlocks() {
+
+	defer solver.timeTrack(time.Now(), "Populated blocks")
+	log.Println("Populating blocks")
+
+	solver.findBlocks(&solver.Controller.Row1, &solver.row1s)
+	solver.findBlocks(&solver.Controller.Row2, &solver.row2s)
+	solver.findBlocks(&solver.Controller.Row3, &solver.row3s)
+	solver.findBlocks(&solver.Controller.Row4, &solver.row4s)
+	solver.findBlocks(&solver.Controller.Row5, &solver.row5s)
+	solver.findBlocks(&solver.Controller.Row6, &solver.row6s)
+	solver.findBlocks(&solver.Controller.Row7, &solver.row7s)
+	solver.findBlocks(&solver.Controller.Row8, &solver.row8s)
+	solver.findBlocks(&solver.Controller.Row9, &solver.row9s)
+
+	// This calculates and stores the total number of solutions to validate.
+	solver.Iter = uint64(len(solver.row1s)) * uint64(len(solver.row2s)) * uint64(len(solver.row3s)) * uint64(len(solver.row4s)) * uint64(len(solver.row5s)) * uint64(len(solver.row6s)) * uint64(len(solver.row7s)) * uint64(len(solver.row8s)) * uint64(len(solver.row9s))
+
+}

+ 23 - 0
solver/SelectWorkload.go

@@ -0,0 +1,23 @@
+package solver
+
+import (
+	"log"
+	"os"
+	"strconv"
+	"time"
+)
+
+// Renders workload for an agent.
+// Checks if this feature can be used, otherwise exits.
+// Modify solver.row1s so it limits the workload to what is only desired
+func (solver *Solver) SelectWorkload() {
+	if solver.Controller.Split > len(solver.row1s) {
+		log.Println("ERROR: Unable to divide the workload in " + strconv.Itoa(solver.Controller.Split) + " parts, when only " + strconv.Itoa(len(solver.row1s)) + " are available.\n\n")
+		os.Exit(1)
+	}
+	defer solver.timeTrack(time.Now(), "Workload set")
+	log.Println("Setting workload")
+	log.Println("We are agent " + strconv.Itoa(solver.Controller.Part) + " of " + strconv.Itoa(solver.Controller.Split))
+	workloads := solver.splitWorkload()
+	solver.setWorkload(workloads)
+}

+ 103 - 0
solver/Tracker.go

@@ -0,0 +1,103 @@
+package solver
+
+import (
+	"log"
+	"strconv"
+	"time"
+)
+
+// Keep track and output progress.
+// Calculate rates, display percentages, estimate the ETA till completion.
+func (solver *Solver) Tracker() {
+
+	// Add time tracking
+	defer solver.timeTrack(time.Now(), "Validated solutions")
+	log.Println("Validating solutions")
+
+	// Determine if the main-loop is done
+	var done bool
+
+	// Tracking progress in percentages
+	var percentage float32
+	// Tracking progress in validated solutions
+	var track int
+
+	// Tracking the rate, starting point
+	var rateStart uint64
+	// Tracking the rate, difference between previous iterations
+	var rateDiff uint64
+
+	// Tracking duration
+	var timerStart = time.Now()
+
+	// Estimation how long it will take
+	var est_fin string
+
+	// While not needed for rateDiff anymore, it makes estimation calculations more accurate. ☹️
+	time.Sleep(time.Second)
+
+	// for solver.Iter != solver.counter { // Start for-loop
+	for !done {
+
+		// Determine how far we are.
+		percentage = (float32(solver.counter.Load()) / (float32(solver.Iter) / 100))
+
+		// Reset the loop
+		rateDiff = solver.counter.Load() - rateStart
+
+		if track <= int(percentage) || rateDiff == 0 { // Start if-statement
+
+			// Make sure something happened, making rateStart the only reliable variable
+			if solver.Iter == solver.counter.Load() {
+				percentage = 100
+				solver.counter.Store(solver.Iter)
+				done = true
+			}
+
+			timer_elapsed := time.Since(timerStart)
+			solver.rates = append(solver.rates, rateDiff)
+			rate_avg := solver.calcAVG()
+
+			// Estimate when this is finished
+			if rateDiff == 0 {
+				est_fin = "N/A"
+			} else {
+				duration_int := (solver.Iter - solver.counter.Load()) / rate_avg
+				duration_string := strconv.Itoa(int(duration_int)) + "s"
+				est, err := time.ParseDuration(duration_string)
+				if err != nil {
+					est_fin = "parse error"
+				} else {
+					est_fin = est.String()
+				}
+			}
+
+			// Printing the progress
+			log.Println("Processing: " + strconv.Itoa(int(percentage)) + "% (" + strconv.FormatUint(solver.counter.Load(), 10) + "/" + strconv.Itoa(int(solver.Iter)) + "); Rate: " + strconv.FormatUint(rateDiff, 10) + "/sec for " + timer_elapsed.String() + "; Time left (est.): " + est_fin)
+
+			// After we are done printing, exit this for-loop
+			if percentage == 100 {
+				break
+			}
+
+			// Wrap up the loop or break
+			if int(percentage) > track {
+				track = int(percentage)
+			} else {
+				track = track + 1
+			}
+
+			timerStart = time.Now()
+
+		}
+
+		// Resert the rate counter
+		rateStart = solver.counter.Load()
+
+		// Sleep for a second
+		if solver.Iter != solver.counter.Load() {
+			time.Sleep(1 * time.Second)
+		}
+	} // End for-loop
+
+}

+ 14 - 0
solver/calcAVG.go

@@ -0,0 +1,14 @@
+package solver
+
+// Calculate the average rate in a stored slice of rates.
+func (solver *Solver) calcAVG() (avg uint64) {
+	var avgSum uint64
+
+	for _, value := range solver.rates {
+		avgSum += uint64(value)
+	}
+
+	avg = avgSum / uint64(len(solver.rates))
+
+	return
+}

+ 37 - 0
solver/findBlocks.go

@@ -0,0 +1,37 @@
+package solver
+
+// The actual function that finds the blocks matching the partial blocks.
+func (solver *Solver) findBlocks(row *string, rows *[]string) {
+	// Declare selection
+	var selection []string
+	var currBlocks []string
+	funcRow := *row
+
+	for letter := range funcRow {
+
+		if len(selection) == 0 {
+			currBlocks = solver.Controller.Blocks
+		} else {
+			currBlocks = selection
+			selection = nil
+		}
+
+		for _, block := range currBlocks {
+
+			currRow := block
+
+			if funcRow[letter] == currRow[letter] {
+				foundRow := currRow
+				selection = append(selection, foundRow)
+			}
+			if funcRow[letter] == '0' {
+				foundRow := currRow
+				selection = append(selection, foundRow)
+			}
+
+		} // End for-loop
+
+	} // End for-loop
+
+	*rows = selection
+}

+ 0 - 253
solver/processing.go

@@ -1,253 +0,0 @@
-package solver
-
-import (
-	"log"
-	"strconv"
-	"time"
-)
-
-// Find all possible blocks that can be used to find a solution.
-func (solver *Solver) PopulateBlocks() {
-
-	defer solver.timeTrack(time.Now(), "Populated blocks")
-	log.Println("Populating blocks")
-
-	solver.findBlocks(&solver.Controller.Row1, &solver.row1s)
-	solver.findBlocks(&solver.Controller.Row2, &solver.row2s)
-	solver.findBlocks(&solver.Controller.Row3, &solver.row3s)
-	solver.findBlocks(&solver.Controller.Row4, &solver.row4s)
-	solver.findBlocks(&solver.Controller.Row5, &solver.row5s)
-	solver.findBlocks(&solver.Controller.Row6, &solver.row6s)
-	solver.findBlocks(&solver.Controller.Row7, &solver.row7s)
-	solver.findBlocks(&solver.Controller.Row8, &solver.row8s)
-	solver.findBlocks(&solver.Controller.Row9, &solver.row9s)
-
-	// This calculates and stores the total number of solutions to validate.
-	solver.Iter = uint64(len(solver.row1s)) * uint64(len(solver.row2s)) * uint64(len(solver.row3s)) * uint64(len(solver.row4s)) * uint64(len(solver.row5s)) * uint64(len(solver.row6s)) * uint64(len(solver.row7s)) * uint64(len(solver.row8s)) * uint64(len(solver.row9s))
-
-}
-
-// The actual function that finds the blocks matching the partial blocks.
-func (solver *Solver) findBlocks(row *string, rows *[]string) {
-	// Declare selection
-	var selection []string
-	var currBlocks []string
-	funcRow := *row
-
-	for letter := range funcRow {
-
-		if len(selection) == 0 {
-			currBlocks = solver.Controller.Blocks
-		} else {
-			currBlocks = selection
-			selection = nil
-		}
-
-		for _, block := range currBlocks {
-
-			currRow := block
-
-			if funcRow[letter] == currRow[letter] {
-				foundRow := currRow
-				selection = append(selection, foundRow)
-			}
-			if funcRow[letter] == '0' {
-				foundRow := currRow
-				selection = append(selection, foundRow)
-			}
-
-		} // End for-loop
-
-	} // End for-loop
-
-	*rows = selection
-}
-
-// Iterate through all combination of blocks and validate them.
-func (solver *Solver) CheckCombinations() {
-	for rows1Index := range solver.row1s {
-		for rows2Index := range solver.row2s {
-			for rows3Index := range solver.row3s {
-				for rows4Index := range solver.row4s {
-					for rows5Index := range solver.row5s {
-						for rows6Index := range solver.row6s {
-							for rows7Index := range solver.row7s {
-								for rows8Index := range solver.row8s {
-									for rows9Index := range solver.row9s {
-										go solver.validator(rows1Index, rows2Index, rows3Index, rows4Index, rows5Index, rows6Index, rows7Index, rows8Index, rows9Index)
-									}
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-// Validate the provided rows and verify it is a valid solution.
-func (solver *Solver) validator(rows1Index int, rows2Index int, rows3Index int, rows4Index int, rows5Index int, rows6Index int, rows7Index int, rows8Index int, rows9Index int) {
-
-	solver.counter.Add(1)
-
-	if solver.validateCombination(solver.row1s[rows1Index], solver.row2s[rows2Index], solver.row3s[rows3Index], solver.row4s[rows4Index], solver.row5s[rows5Index], solver.row6s[rows6Index], solver.row7s[rows7Index], solver.row8s[rows8Index], solver.row9s[rows9Index]) {
-		solver.Controller.Solutions = append(solver.Controller.Solutions, []string{solver.row1s[rows1Index], solver.row2s[rows2Index], solver.row3s[rows3Index], solver.row4s[rows4Index], solver.row5s[rows5Index], solver.row6s[rows6Index], solver.row7s[rows7Index], solver.row8s[rows8Index], solver.row9s[rows9Index]})
-	}
-
-}
-
-// Keep track and output progress.
-// Calculate rates, display percentages, estimate the ETA till completion.
-func (solver *Solver) Tracker() {
-
-	// Add time tracking
-	defer solver.timeTrack(time.Now(), "Validated solutions")
-	log.Println("Validating solutions")
-
-	// Determine if the main-loop is done
-	var done bool
-
-	// Tracking progress in percentages
-	var percentage float32
-	// Tracking progress in validated solutions
-	var track int
-
-	// Tracking the rate, starting point
-	var rateStart uint64
-	// Tracking the rate, difference between previous iterations
-	var rateDiff uint64
-
-	// Tracking duration
-	var timerStart = time.Now()
-
-	// Estimation how long it will take
-	var est_fin string
-
-	// While not needed for rateDiff anymore, it makes estimation calculations more accurate. ☹️
-	time.Sleep(time.Second)
-
-	// for solver.Iter != solver.counter { // Start for-loop
-	for !done {
-
-		// Determine how far we are.
-		percentage = (float32(solver.counter.Load()) / (float32(solver.Iter) / 100))
-
-		// Reset the loop
-		rateDiff = solver.counter.Load() - rateStart
-
-		if track <= int(percentage) || rateDiff == 0 { // Start if-statement
-
-			// Make sure something happened, making rateStart the only reliable variable
-			if solver.Iter == solver.counter.Load() {
-				percentage = 100
-				solver.counter.Store(solver.Iter)
-				done = true
-			}
-
-			timer_elapsed := time.Since(timerStart)
-			solver.rates = append(solver.rates, rateDiff)
-			rate_avg := solver.calcAVG()
-
-			// Estimate when this is finished
-			if rateDiff == 0 {
-				est_fin = "N/A"
-			} else {
-				duration_int := (solver.Iter - solver.counter.Load()) / rate_avg
-				duration_string := strconv.Itoa(int(duration_int)) + "s"
-				est, err := time.ParseDuration(duration_string)
-				if err != nil {
-					est_fin = "parse error"
-				} else {
-					est_fin = est.String()
-				}
-			}
-
-			// Printing the progress
-			log.Println("Processing: " + strconv.Itoa(int(percentage)) + "% (" + strconv.FormatUint(solver.counter.Load(), 10) + "/" + strconv.Itoa(int(solver.Iter)) + "); Rate: " + strconv.FormatUint(rateDiff, 10) + "/sec for " + timer_elapsed.String() + "; Time left (est.): " + est_fin)
-
-			// After we are done printing, exit this for-loop
-			if percentage == 100 {
-				break
-			}
-
-			// Wrap up the loop or break
-			if int(percentage) > track {
-				track = int(percentage)
-			} else {
-				track = track + 1
-			}
-
-			timerStart = time.Now()
-
-		}
-
-		// Resert the rate counter
-		rateStart = solver.counter.Load()
-
-		// Sleep for a second
-		if solver.Iter != solver.counter.Load() {
-			time.Sleep(1 * time.Second)
-		}
-	} // End for-loop
-
-}
-
-// Validate combination
-func (solver *Solver) validateCombination(row1 string, row2 string, row3 string, row4 string, row5 string, row6 string, row7 string, row8 string, row9 string) (retval bool) {
-	retval = true
-
-	for index := range 9 {
-		if row1[index] == row2[index] || row1[index] == row3[index] || row1[index] == row4[index] || row1[index] == row5[index] || row1[index] == row6[index] || row1[index] == row7[index] || row1[index] == row8[index] || row1[index] == row9[index] {
-			retval = false
-		}
-
-		if row2[index] == row1[index] || row2[index] == row3[index] || row2[index] == row4[index] || row2[index] == row5[index] || row2[index] == row6[index] || row2[index] == row7[index] || row2[index] == row8[index] || row2[index] == row9[index] {
-			retval = false
-		}
-
-		if row3[index] == row1[index] || row3[index] == row2[index] || row3[index] == row4[index] || row3[index] == row5[index] || row3[index] == row6[index] || row3[index] == row7[index] || row3[index] == row8[index] || row3[index] == row9[index] {
-			retval = false
-		}
-
-		if row4[index] == row1[index] || row4[index] == row2[index] || row4[index] == row3[index] || row4[index] == row5[index] || row4[index] == row6[index] || row4[index] == row7[index] || row4[index] == row8[index] || row4[index] == row9[index] {
-			retval = false
-		}
-
-		if row5[index] == row1[index] || row5[index] == row2[index] || row5[index] == row3[index] || row5[index] == row4[index] || row5[index] == row6[index] || row5[index] == row7[index] || row5[index] == row8[index] || row5[index] == row9[index] {
-			retval = false
-		}
-
-		if row6[index] == row1[index] || row6[index] == row2[index] || row6[index] == row3[index] || row6[index] == row4[index] || row6[index] == row5[index] || row6[index] == row7[index] || row6[index] == row8[index] || row6[index] == row9[index] {
-			retval = false
-		}
-
-		if row7[index] == row1[index] || row7[index] == row2[index] || row7[index] == row3[index] || row7[index] == row4[index] || row5[index] == row6[index] || row7[index] == row6[index] || row7[index] == row8[index] || row7[index] == row9[index] {
-			retval = false
-		}
-
-		if row8[index] == row1[index] || row8[index] == row2[index] || row8[index] == row3[index] || row8[index] == row4[index] || row8[index] == row5[index] || row8[index] == row6[index] || row8[index] == row7[index] || row8[index] == row9[index] {
-			retval = false
-		}
-
-		if row9[index] == row1[index] || row9[index] == row2[index] || row9[index] == row3[index] || row9[index] == row4[index] || row9[index] == row5[index] || row9[index] == row6[index] || row9[index] == row7[index] || row9[index] == row8[index] {
-			retval = false
-		}
-
-	}
-
-	return retval
-}
-
-// Calculate the average rate in a stored slice of rates.
-func (solver *Solver) calcAVG() (avg uint64) {
-	var avgSum uint64
-
-	for _, value := range solver.rates {
-		avgSum += uint64(value)
-	}
-
-	avg = avgSum / uint64(len(solver.rates))
-
-	return
-}

+ 21 - 0
solver/setWorkload.go

@@ -0,0 +1,21 @@
+package solver
+
+// Set the workload by setting solver.row1s
+func (solver *Solver) setWorkload(agents []int) {
+	var start int = 0
+	var finish int = 0
+	for key, value := range agents {
+		if key == solver.Controller.Part-1 {
+			finish = start + value
+			break
+		} else {
+			start += value
+		}
+	}
+
+	// Set the shortened set of instructions
+	solver.row1s = solver.row1s[start:finish]
+
+	// Recalculate how much we need to grind through
+	solver.Iter = uint64(len(solver.row1s)) * uint64(len(solver.row2s)) * uint64(len(solver.row3s)) * uint64(len(solver.row4s)) * uint64(len(solver.row5s)) * uint64(len(solver.row6s)) * uint64(len(solver.row7s)) * uint64(len(solver.row8s)) * uint64(len(solver.row9s))
+}

+ 0 - 61
solver/split.go

@@ -1,61 +0,0 @@
-package solver
-
-import (
-	"log"
-	"os"
-	"strconv"
-	"time"
-)
-
-// Renders workload for an agent.
-// Checks if this feature can be used, otherwise exits.
-// Modify solver.row1s so it limits the workload to what is only desired
-func (solver *Solver) SelectWorkload() {
-	if solver.Controller.Split > len(solver.row1s) {
-		log.Println("ERROR: Unable to divide the workload in " + strconv.Itoa(solver.Controller.Split) + " parts, when only " + strconv.Itoa(len(solver.row1s)) + " are available.\n\n")
-		os.Exit(1)
-	}
-	defer solver.timeTrack(time.Now(), "Workload set")
-	log.Println("Setting workload")
-	log.Println("We are agent " + strconv.Itoa(solver.Controller.Part) + " of " + strconv.Itoa(solver.Controller.Split))
-	workloads := solver.splitWorkload()
-	solver.setWorkload(workloads)
-}
-
-// Determine how workload should be split among the agents
-func (solver *Solver) splitWorkload() []int {
-	agents := make([]int, solver.Controller.Split)
-	var tracker int
-	var tasks int = len(solver.row1s)
-
-	for tasks != 0 {
-		agents[tracker] += 1
-		tasks -= 1
-		tracker += 1
-		if tracker == solver.Controller.Split {
-			tracker = 0
-		}
-	}
-
-	return agents
-}
-
-// Set the workload by setting solver.row1s
-func (solver *Solver) setWorkload(agents []int) {
-	var start int = 0
-	var finish int = 0
-	for key, value := range agents {
-		if key == solver.Controller.Part-1 {
-			finish = start + value
-			break
-		} else {
-			start += value
-		}
-	}
-
-	// Set the shortened set of instructions
-	solver.row1s = solver.row1s[start:finish]
-
-	// Recalculate how much we need to grind through
-	solver.Iter = uint64(len(solver.row1s)) * uint64(len(solver.row2s)) * uint64(len(solver.row3s)) * uint64(len(solver.row4s)) * uint64(len(solver.row5s)) * uint64(len(solver.row6s)) * uint64(len(solver.row7s)) * uint64(len(solver.row8s)) * uint64(len(solver.row9s))
-}

+ 19 - 0
solver/splitWorkload.go

@@ -0,0 +1,19 @@
+package solver
+
+// Determine how workload should be split among the agents
+func (solver *Solver) splitWorkload() []int {
+	agents := make([]int, solver.Controller.Split)
+	var tracker int
+	var tasks int = len(solver.row1s)
+
+	for tasks != 0 {
+		agents[tracker] += 1
+		tasks -= 1
+		tracker += 1
+		if tracker == solver.Controller.Split {
+			tracker = 0
+		}
+	}
+
+	return agents
+}

+ 0 - 0
solver/timers.go → solver/timeTrack.go


+ 47 - 0
solver/validateCombination.go

@@ -0,0 +1,47 @@
+package solver
+
+// Validate combination
+func (solver *Solver) validateCombination(row1 string, row2 string, row3 string, row4 string, row5 string, row6 string, row7 string, row8 string, row9 string) (retval bool) {
+	retval = true
+
+	for index := range 9 {
+		if row1[index] == row2[index] || row1[index] == row3[index] || row1[index] == row4[index] || row1[index] == row5[index] || row1[index] == row6[index] || row1[index] == row7[index] || row1[index] == row8[index] || row1[index] == row9[index] {
+			retval = false
+		}
+
+		if row2[index] == row1[index] || row2[index] == row3[index] || row2[index] == row4[index] || row2[index] == row5[index] || row2[index] == row6[index] || row2[index] == row7[index] || row2[index] == row8[index] || row2[index] == row9[index] {
+			retval = false
+		}
+
+		if row3[index] == row1[index] || row3[index] == row2[index] || row3[index] == row4[index] || row3[index] == row5[index] || row3[index] == row6[index] || row3[index] == row7[index] || row3[index] == row8[index] || row3[index] == row9[index] {
+			retval = false
+		}
+
+		if row4[index] == row1[index] || row4[index] == row2[index] || row4[index] == row3[index] || row4[index] == row5[index] || row4[index] == row6[index] || row4[index] == row7[index] || row4[index] == row8[index] || row4[index] == row9[index] {
+			retval = false
+		}
+
+		if row5[index] == row1[index] || row5[index] == row2[index] || row5[index] == row3[index] || row5[index] == row4[index] || row5[index] == row6[index] || row5[index] == row7[index] || row5[index] == row8[index] || row5[index] == row9[index] {
+			retval = false
+		}
+
+		if row6[index] == row1[index] || row6[index] == row2[index] || row6[index] == row3[index] || row6[index] == row4[index] || row6[index] == row5[index] || row6[index] == row7[index] || row6[index] == row8[index] || row6[index] == row9[index] {
+			retval = false
+		}
+
+		if row7[index] == row1[index] || row7[index] == row2[index] || row7[index] == row3[index] || row7[index] == row4[index] || row5[index] == row6[index] || row7[index] == row6[index] || row7[index] == row8[index] || row7[index] == row9[index] {
+			retval = false
+		}
+
+		if row8[index] == row1[index] || row8[index] == row2[index] || row8[index] == row3[index] || row8[index] == row4[index] || row8[index] == row5[index] || row8[index] == row6[index] || row8[index] == row7[index] || row8[index] == row9[index] {
+			retval = false
+		}
+
+		if row9[index] == row1[index] || row9[index] == row2[index] || row9[index] == row3[index] || row9[index] == row4[index] || row9[index] == row5[index] || row9[index] == row6[index] || row9[index] == row7[index] || row9[index] == row8[index] {
+			retval = false
+		}
+
+	}
+
+	return retval
+}

+ 12 - 0
solver/validator.go

@@ -0,0 +1,12 @@
+package solver
+
+// Validate the provided rows and verify it is a valid solution.
+func (solver *Solver) validator(rows1Index int, rows2Index int, rows3Index int, rows4Index int, rows5Index int, rows6Index int, rows7Index int, rows8Index int, rows9Index int) {
+
+	solver.counter.Add(1)
+
+	if solver.validateCombination(solver.row1s[rows1Index], solver.row2s[rows2Index], solver.row3s[rows3Index], solver.row4s[rows4Index], solver.row5s[rows5Index], solver.row6s[rows6Index], solver.row7s[rows7Index], solver.row8s[rows8Index], solver.row9s[rows9Index]) {
+		solver.Controller.Solutions = append(solver.Controller.Solutions, []string{solver.row1s[rows1Index], solver.row2s[rows2Index], solver.row3s[rows3Index], solver.row4s[rows4Index], solver.row5s[rows5Index], solver.row6s[rows6Index], solver.row7s[rows7Index], solver.row8s[rows8Index], solver.row9s[rows9Index]})
+	}
+
+}