Bläddra i källkod

Working, with go routines. Didn't improve performance.

Sacha Ligthert 1 år sedan
förälder
incheckning
b89d2d29c6
7 ändrade filer med 437 tillägg och 285 borttagningar
  1. 2 276
      main.go
  2. 47 9
      notes.txt
  3. 69 0
      solver/blocks.go
  4. 220 0
      solver/processing.go
  5. 42 0
      solver/solver.go
  6. 28 0
      solver/stash.go
  7. 29 0
      solver/types.go

+ 2 - 276
main.go

@@ -1,281 +1,7 @@
 package main
 
-import (
-	"encoding/csv"
-	"fmt"
-	"io"
-	"log"
-	"os"
-	"strconv"
-)
+import "gitea.ligthert.net/golang/sudoku-funpark/solver"
 
 func main() {
-
-	blocks := load_blocks()
-	// fmt.Println("Total blocks:", len(blocks))
-
-	// Parse parameters
-	// Turn parameters into rows
-	row1 := "769104802"
-	row2 := "154800060"
-	row3 := "002700150"
-	row4 := "600900308"
-	row5 := "045328670"
-	row6 := "328670945"
-	row7 := "597410280"
-	row8 := "006283090"
-	row9 := "200590006"
-
-	// Find rows that fit with the entered rows
-	rows1 := find_blocks(blocks, row1)
-	rows2 := find_blocks(blocks, row2)
-	rows3 := find_blocks(blocks, row3)
-	rows4 := find_blocks(blocks, row4)
-	rows5 := find_blocks(blocks, row5)
-	rows6 := find_blocks(blocks, row6)
-	rows7 := find_blocks(blocks, row7)
-	rows8 := find_blocks(blocks, row8)
-	rows9 := find_blocks(blocks, row9)
-
-	// fmt.Println(rows1)
-	// fmt.Println(rows2)
-	// fmt.Println(rows3)
-	// fmt.Println(rows4)
-	// fmt.Println(rows5)
-	// fmt.Println(rows6)
-	// fmt.Println(rows7)
-	// fmt.Println(rows8)
-	// fmt.Println(rows9)
-
-	// fmt.Println("len(rows1):", len(rows1))
-	// fmt.Println("len(rows2):", len(rows2))
-	// fmt.Println("len(rows3):", len(rows3))
-	// fmt.Println("len(rows4):", len(rows4))
-	// fmt.Println("len(rows5):", len(rows5))
-	// fmt.Println("len(rows6):", len(rows6))
-	// fmt.Println("len(rows7):", len(rows7))
-	// fmt.Println("len(rows8):", len(rows8))
-	// fmt.Println("len(rows9):", len(rows9))
-
-	fmt.Println("Number of iterations:", len(rows1)*len(rows2)*len(rows3)*len(rows4)*len(rows5)*len(rows6)*len(rows7)*len(rows8)*len(rows9))
-	iter := len(rows1) * len(rows2) * len(rows3) * len(rows4) * len(rows5) * len(rows6) * len(rows7) * len(rows8) * len(rows9)
-
-	solutions := check_combinations(rows1, rows2, rows3, rows4, rows5, rows6, rows7, rows8, rows9, iter)
-
-	fmt.Println(solutions)
-
-}
-
-func check_combinations(rows1 []int, rows2 []int, rows3 []int, rows4 []int, rows5 []int, rows6 []int, rows7 []int, rows8 []int, rows9 []int, iter int) []string {
-	var combinations []string
-	var counter int
-	var percentage float32
-
-	for rows1_index := range rows1 {
-		for rows2_index := range rows2 {
-			for rows3_index := range rows3 {
-				for rows4_index := range rows4 {
-					for rows5_index := range rows5 {
-						for rows6_index := range rows6 {
-							for rows7_index := range rows7 {
-								for rows8_index := range rows8 {
-									for rows9_index := range rows9 {
-										if validate_combination(rows1[rows1_index], rows2[rows2_index], rows3[rows3_index], rows4[rows4_index], rows5[rows5_index], rows6[rows6_index], rows7[rows7_index], rows8[rows8_index], rows9[rows9_index]) {
-											combinations = append(combinations, render_combination(rows1[rows1_index], rows2[rows2_index], rows3[rows3_index], rows4[rows4_index], rows5[rows5_index], rows6[rows6_index], rows7[rows7_index], rows8[rows8_index], rows9[rows9_index]))
-										}
-										counter = counter + 1
-										if counter%1000000 == 0 {
-											percentage = (float32(counter) / (float32(iter) / 100))
-											fmt.Println("Processing:", percentage, "%")
-										}
-									}
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-
-	return combinations
-}
-
-func validate_combination(row1 int, row2 int, row3 int, row4 int, row5 int, row6 int, row7 int, row8 int, row9 int) bool {
-	var retval bool
-	retval = true
-
-	row1s := strconv.Itoa(row1)
-	row2s := strconv.Itoa(row2)
-	row3s := strconv.Itoa(row3)
-	row4s := strconv.Itoa(row4)
-	row5s := strconv.Itoa(row5)
-	row6s := strconv.Itoa(row6)
-	row7s := strconv.Itoa(row7)
-	row8s := strconv.Itoa(row8)
-	row9s := strconv.Itoa(row9)
-
-	for index := range 9 {
-		if row1s[index] == row2s[index] || row1s[index] == row3s[index] || row1s[index] == row4s[index] || row1s[index] == row5s[index] || row1s[index] == row6s[index] || row1s[index] == row7s[index] || row1s[index] == row8s[index] || row1s[index] == row9s[index] {
-			retval = false
-		}
-
-		if row2s[index] == row1s[index] || row2s[index] == row3s[index] || row2s[index] == row4s[index] || row2s[index] == row5s[index] || row2s[index] == row6s[index] || row2s[index] == row7s[index] || row2s[index] == row8s[index] || row2s[index] == row9s[index] {
-			retval = false
-		}
-
-		if row3s[index] == row1s[index] || row3s[index] == row2s[index] || row3s[index] == row4s[index] || row3s[index] == row5s[index] || row3s[index] == row6s[index] || row3s[index] == row7s[index] || row3s[index] == row8s[index] || row3s[index] == row9s[index] {
-			retval = false
-		}
-
-		if row4s[index] == row1s[index] || row4s[index] == row2s[index] || row4s[index] == row3s[index] || row4s[index] == row5s[index] || row4s[index] == row6s[index] || row4s[index] == row7s[index] || row4s[index] == row8s[index] || row4s[index] == row9s[index] {
-			retval = false
-		}
-
-		if row5s[index] == row1s[index] || row5s[index] == row2s[index] || row5s[index] == row3s[index] || row5s[index] == row4s[index] || row5s[index] == row6s[index] || row5s[index] == row7s[index] || row5s[index] == row8s[index] || row5s[index] == row9s[index] {
-			retval = false
-		}
-
-		if row6s[index] == row1s[index] || row6s[index] == row2s[index] || row6s[index] == row3s[index] || row6s[index] == row4s[index] || row6s[index] == row5s[index] || row6s[index] == row7s[index] || row6s[index] == row8s[index] || row6s[index] == row9s[index] {
-			retval = false
-		}
-
-		if row7s[index] == row1s[index] || row7s[index] == row2s[index] || row7s[index] == row3s[index] || row7s[index] == row4s[index] || row5s[index] == row6s[index] || row7s[index] == row6s[index] || row7s[index] == row8s[index] || row7s[index] == row9s[index] {
-			retval = false
-		}
-
-		if row8s[index] == row1s[index] || row8s[index] == row2s[index] || row8s[index] == row3s[index] || row8s[index] == row4s[index] || row8s[index] == row5s[index] || row8s[index] == row6s[index] || row8s[index] == row7s[index] || row8s[index] == row9s[index] {
-			retval = false
-		}
-
-		if row9s[index] == row1s[index] || row9s[index] == row2s[index] || row9s[index] == row3s[index] || row9s[index] == row4s[index] || row9s[index] == row5s[index] || row9s[index] == row6s[index] || row9s[index] == row7s[index] || row9s[index] == row8s[index] {
-			retval = false
-		}
-
-	}
-
-	return retval
-}
-
-func render_combination(row1 int, row2 int, row3 int, row4 int, row5 int, row6 int, row7 int, row8 int, row9 int) string {
-
-	row1s := strconv.Itoa(row1)
-	row2s := strconv.Itoa(row2)
-	row3s := strconv.Itoa(row3)
-	row4s := strconv.Itoa(row4)
-	row5s := strconv.Itoa(row5)
-	row6s := strconv.Itoa(row6)
-	row7s := strconv.Itoa(row7)
-	row8s := strconv.Itoa(row8)
-	row9s := strconv.Itoa(row9)
-
-	// combination = row1s + "\n" + row2s + "\n" + row3s + "\n" + row4s + "\n" + row5s + "\n" + row6s + "\n" + row7s + "\n" + row8s + "\n" + row9s + "\n"
-
-	return row1s + "\n" + row2s + "\n" + row3s + "\n" + row4s + "\n" + row5s + "\n" + row6s + "\n" + row7s + "\n" + row8s + "\n" + row9s + "\n"
-}
-
-func find_blocks(blocks []int, row string) []int {
-	// Declare selection
-	var selection []int
-	var curr_blocks []int
-
-	// fmt.Println(row)
-	for letter := range row {
-
-		if len(selection) == 0 {
-			curr_blocks = blocks
-		} else {
-			curr_blocks = selection
-			selection = nil
-		}
-
-		// fmt.Println("Letter:", row[letter])
-		// fmt.Println("len(curr_blocks):", len(curr_blocks))
-		// fmt.Println("curr_blocks[0]:", curr_blocks[0])
-
-		for block := range curr_blocks {
-
-			curr_row := strconv.Itoa(curr_blocks[block])
-
-			if row[letter] == curr_row[letter] {
-				found_row, _ := strconv.Atoi(curr_row)
-				selection = append(selection, found_row)
-			}
-			if row[letter] == '0' {
-				found_row, _ := strconv.Atoi(curr_row)
-				selection = append(selection, found_row)
-			}
-
-		} // End for-loop
-
-	} // End for-loop
-
-	// Return selection
-	return selection
-}
-
-func load_blocks() []int {
-	var blocks []int
-
-	file, err := os.Open("blocks.csv")
-	if err != nil {
-		panic(err)
-	}
-	defer file.Close()
-
-	r := csv.NewReader(file)
-	for {
-		record, err := r.Read()
-		if err == io.EOF {
-			break
-		}
-		if err != nil {
-			log.Fatal(err)
-		}
-
-		block, _ := strconv.Atoi(record[0])
-		blocks = append(blocks, block)
-	}
-
-	return blocks
-}
-
-func generate_blocks() []int {
-
-	var blocks []int
-	decvals := [9]int{49, 50, 51, 52, 53, 54, 55, 56, 57}
-
-	for counter := 123456789; counter <= 987654321; counter++ {
-
-		// Convert number to string ([]byte)
-		digits := strconv.Itoa(counter)
-
-		// Check if every number is only represented only once
-		var valid bool
-		valid = true
-		for decval := range decvals {
-			var count int
-			for digit := range digits {
-				if digits[digit] == byte(decvals[decval]) {
-					count = count + 1
-				}
-			}
-
-			if count != 1 {
-				valid = false
-			}
-		}
-
-		if valid {
-			blocks = append(blocks, counter)
-		}
-	}
-
-	return blocks
-
-}
-
-func print_block(block int) {
-	digits := strconv.Itoa(block)
-	fmt.Printf("%c %c %c\n%c %c %c\n%c %c %c\n\n", digits[0], digits[1], digits[2], digits[3], digits[4], digits[5], digits[6], digits[7], digits[8])
+	solver.Run()
 }

+ 47 - 9
notes.txt

@@ -31,12 +31,50 @@ Compat Matrix
 // 	fmt.Println(blocks[i])
 // }
 
-// block1 := 714365289
-// block2 := 365289714
-// block3 := 289714365
-// block4 := 173456892
-// block5 := 456893173
-// block6 := 892173546
-// block7 := 647531928
-// block8 := 531928647
-// block9 := 928647531
+row1 := "769104802"
+row2 := "154800060"
+row3 := "002700150"
+row4 := "600900308"
+row5 := "045328670"
+row6 := "328670945"
+row7 := "597410280"
+row8 := "006283090"
+row9 := "200590006"
+
+row1 := "769154832"
+row2 := "154832769"
+row3 := "832769154"
+row4 := "671945328"
+row5 := "945328671"
+row6 := "328671945"
+row7 := "597416283"
+row8 := "416284597"
+row9 := "283597416"
+
+	// for rows1_index := range solver.row1s {
+	// 	for rows2_index := range solver.row2s {
+	// 		for rows3_index := range solver.row3s {
+	// 			for rows4_index := range solver.row4s {
+	// 				for rows5_index := range solver.row5s {
+	// 					for rows6_index := range solver.row6s {
+	// 						for rows7_index := range solver.row7s {
+	// 							for rows8_index := range solver.row8s {
+	// 								for rows9_index := range solver.row9s {
+	// 									go solver.routine_validator(rows1_index, rows2_index, rows3_index, rows4_index, rows5_index, rows6_index, rows7_index, rows8_index, rows9_index)
+	// 									// if solver.validate_combination(solver.row1s[rows1_index], solver.row2s[rows2_index], solver.row3s[rows3_index], solver.row4s[rows4_index], solver.row5s[rows5_index], solver.row6s[rows6_index], solver.row7s[rows7_index], solver.row8s[rows8_index], solver.row9s[rows9_index]) {
+	// 									// 	solver.solutions = append(solver.solutions, solver.render_combination(solver.row1s[rows1_index], solver.row2s[rows2_index], solver.row3s[rows3_index], solver.row4s[rows4_index], solver.row5s[rows5_index], solver.row6s[rows6_index], solver.row7s[rows7_index], solver.row8s[rows8_index], solver.row9s[rows9_index]))
+	// 									// }
+	// 									// solver.counter = solver.counter + 1
+	// 									// if solver.counter%1000000 == 0 {
+	// 									// 	percentage = (float32(solver.counter) / (float32(solver.iter) / 100))
+	// 									// 	fmt.Println("Processing:", percentage, "%; Procs:", runtime.NumGoroutine())
+	// 									// }
+	// 								}
+	// 							}
+	// 						}
+	// 					}
+	// 				}
+	// 			}
+	// 		}
+	// 	}
+	// }

+ 69 - 0
solver/blocks.go

@@ -0,0 +1,69 @@
+package solver
+
+import (
+	"encoding/csv"
+	"io"
+	"log"
+	"os"
+	"strconv"
+)
+
+func (solver *Solver) load_blocks() {
+	var blocks []int
+
+	file, err := os.Open("blocks.csv")
+	if err != nil {
+		panic(err)
+	}
+	defer file.Close()
+
+	r := csv.NewReader(file)
+	for {
+		record, err := r.Read()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		block, _ := strconv.Atoi(record[0])
+		blocks = append(blocks, block)
+	}
+	solver.blocks = blocks
+}
+
+func (solver *Solver) generate_blocks() []int {
+
+	var blocks []int
+	decvals := [9]int{49, 50, 51, 52, 53, 54, 55, 56, 57}
+
+	for counter := 123456789; counter <= 987654321; counter++ {
+
+		// Convert number to string ([]byte)
+		digits := strconv.Itoa(counter)
+
+		// Check if every number is only represented only once
+		var valid bool
+		valid = true
+		for decval := range decvals {
+			var count int
+			for digit := range digits {
+				if digits[digit] == byte(decvals[decval]) {
+					count = count + 1
+				}
+			}
+
+			if count != 1 {
+				valid = false
+			}
+		}
+
+		if valid {
+			blocks = append(blocks, counter)
+		}
+	}
+
+	return blocks
+
+}

+ 220 - 0
solver/processing.go

@@ -0,0 +1,220 @@
+package solver
+
+import (
+	"fmt"
+	"runtime"
+	"strconv"
+)
+
+func (solver *Solver) find_blocks(row *string, rows *[]int) {
+	// Declare selection
+	var selection []int
+	var curr_blocks []int
+	func_row := *row
+
+	// fmt.Println(row)
+	for letter := range func_row {
+
+		if len(selection) == 0 {
+			curr_blocks = solver.blocks
+		} else {
+			curr_blocks = selection
+			selection = nil
+		}
+
+		for block := range curr_blocks {
+
+			curr_row := strconv.Itoa(curr_blocks[block])
+
+			if func_row[letter] == curr_row[letter] {
+				found_row, _ := strconv.Atoi(curr_row)
+				selection = append(selection, found_row)
+			}
+			if func_row[letter] == '0' {
+				found_row, _ := strconv.Atoi(curr_row)
+				selection = append(selection, found_row)
+			}
+
+		} // End for-loop
+
+	} // End for-loop
+
+	*rows = selection
+}
+
+func (solver *Solver) check_combinations() {
+	// for rows1_index := range solver.row1s {
+	// 	solver.wg.Add(1)
+	// 	go solver.routine_row1(rows1_index)
+	// }
+	// solver.wg.Wait()
+
+	for rows1_index := range solver.row1s {
+		for rows2_index := range solver.row2s {
+			for rows3_index := range solver.row3s {
+				for rows4_index := range solver.row4s {
+					for rows5_index := range solver.row5s {
+						for rows6_index := range solver.row6s {
+							for rows7_index := range solver.row7s {
+								for rows8_index := range solver.row8s {
+									defer solver.wg.Done()
+									solver.wg.Add(1)
+									go solver.routine_row8(rows1_index, rows2_index, rows3_index, rows4_index, rows5_index, rows6_index, rows7_index, rows8_index)
+									// for rows9_index := range solver.row9s {
+									//   go solver.routine_validator(rows1_index, rows2_index, rows3_index, rows4_index, rows5_index, rows6_index, rows7_index, rows8_index, rows9_index)
+									// // }
+									// }
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+func (solver *Solver) routine_row1(index1 int) {
+	defer solver.wg.Done()
+	for index2 := range solver.row2s {
+		solver.wg.Add(1)
+		go solver.routine_row2(index1, index2)
+	}
+}
+
+func (solver *Solver) routine_row2(index1 int, index2 int) {
+	defer solver.wg.Done()
+	for index3 := range solver.row3s {
+		solver.wg.Add(1)
+		go solver.routine_row3(index1, index2, index3)
+	}
+}
+
+func (solver *Solver) routine_row3(index1 int, index2 int, index3 int) {
+	defer solver.wg.Done()
+	for index4 := range solver.row4s {
+		solver.wg.Add(1)
+		go solver.routine_row4(index1, index2, index3, index4)
+	}
+}
+
+func (solver *Solver) routine_row4(index1 int, index2 int, index3 int, index4 int) {
+	defer solver.wg.Done()
+	for index5 := range solver.row5s {
+		solver.wg.Add(1)
+		go solver.routine_row5(index1, index2, index3, index4, index5)
+	}
+}
+
+func (solver *Solver) routine_row5(index1 int, index2 int, index3 int, index4 int, index5 int) {
+	defer solver.wg.Done()
+	for index6 := range solver.row6s {
+		solver.wg.Add(1)
+		go solver.routine_row6(index1, index2, index3, index4, index5, index6)
+	}
+}
+
+func (solver *Solver) routine_row6(index1 int, index2 int, index3 int, index4 int, index5 int, index6 int) {
+	defer solver.wg.Done()
+	for index7 := range solver.row7s {
+		solver.wg.Add(1)
+		go solver.routine_row7(index1, index2, index3, index4, index5, index6, index7)
+	}
+}
+
+func (solver *Solver) routine_row7(index1 int, index2 int, index3 int, index4 int, index5 int, index6 int, index7 int) {
+	defer solver.wg.Done()
+	for index8 := range solver.row8s {
+		solver.wg.Add(1)
+		go solver.routine_row8(index1, index2, index3, index4, index5, index6, index7, index8)
+	}
+}
+
+func (solver *Solver) routine_row8(index1 int, index2 int, index3 int, index4 int, index5 int, index6 int, index7 int, index8 int) {
+	defer solver.wg.Done()
+	for index9 := range solver.row9s {
+		solver.wg.Add(1)
+		go solver.routine_row9(index1, index2, index3, index4, index5, index6, index7, index8, index9)
+	}
+}
+
+func (solver *Solver) routine_row9(index1 int, index2 int, index3 int, index4 int, index5 int, index6 int, index7 int, index8 int, index9 int) {
+	defer solver.wg.Done()
+	solver.wg.Add(1)
+	go solver.routine_validator(index1, index2, index3, index4, index5, index6, index7, index8, index9)
+}
+
+func (solver *Solver) routine_validator(rows1_index int, rows2_index int, rows3_index int, rows4_index int, rows5_index int, rows6_index int, rows7_index int, rows8_index int, rows9_index int) {
+
+	var percentage float32
+
+	if solver.validate_combination(solver.row1s[rows1_index], solver.row2s[rows2_index], solver.row3s[rows3_index], solver.row4s[rows4_index], solver.row5s[rows5_index], solver.row6s[rows6_index], solver.row7s[rows7_index], solver.row8s[rows8_index], solver.row9s[rows9_index]) {
+		solver.solutions = append(solver.solutions, solver.render_combination(solver.row1s[rows1_index], solver.row2s[rows2_index], solver.row3s[rows3_index], solver.row4s[rows4_index], solver.row5s[rows5_index], solver.row6s[rows6_index], solver.row7s[rows7_index], solver.row8s[rows8_index], solver.row9s[rows9_index]))
+	}
+
+	solver.counter = solver.counter + 1
+
+	if solver.counter%1000000 == 0 {
+		percentage = (float32(solver.counter) / (float32(solver.iter) / 100))
+		fmt.Println("Processing:", percentage, "%; Procs:", runtime.NumGoroutine())
+	}
+
+	solver.wg.Done()
+
+}
+
+func (solver *Solver) validate_combination(row1 int, row2 int, row3 int, row4 int, row5 int, row6 int, row7 int, row8 int, row9 int) bool {
+	var retval bool
+	retval = true
+
+	row1s := strconv.Itoa(row1)
+	row2s := strconv.Itoa(row2)
+	row3s := strconv.Itoa(row3)
+	row4s := strconv.Itoa(row4)
+	row5s := strconv.Itoa(row5)
+	row6s := strconv.Itoa(row6)
+	row7s := strconv.Itoa(row7)
+	row8s := strconv.Itoa(row8)
+	row9s := strconv.Itoa(row9)
+
+	for index := range 9 {
+		if row1s[index] == row2s[index] || row1s[index] == row3s[index] || row1s[index] == row4s[index] || row1s[index] == row5s[index] || row1s[index] == row6s[index] || row1s[index] == row7s[index] || row1s[index] == row8s[index] || row1s[index] == row9s[index] {
+			retval = false
+		}
+
+		if row2s[index] == row1s[index] || row2s[index] == row3s[index] || row2s[index] == row4s[index] || row2s[index] == row5s[index] || row2s[index] == row6s[index] || row2s[index] == row7s[index] || row2s[index] == row8s[index] || row2s[index] == row9s[index] {
+			retval = false
+		}
+
+		if row3s[index] == row1s[index] || row3s[index] == row2s[index] || row3s[index] == row4s[index] || row3s[index] == row5s[index] || row3s[index] == row6s[index] || row3s[index] == row7s[index] || row3s[index] == row8s[index] || row3s[index] == row9s[index] {
+			retval = false
+		}
+
+		if row4s[index] == row1s[index] || row4s[index] == row2s[index] || row4s[index] == row3s[index] || row4s[index] == row5s[index] || row4s[index] == row6s[index] || row4s[index] == row7s[index] || row4s[index] == row8s[index] || row4s[index] == row9s[index] {
+			retval = false
+		}
+
+		if row5s[index] == row1s[index] || row5s[index] == row2s[index] || row5s[index] == row3s[index] || row5s[index] == row4s[index] || row5s[index] == row6s[index] || row5s[index] == row7s[index] || row5s[index] == row8s[index] || row5s[index] == row9s[index] {
+			retval = false
+		}
+
+		if row6s[index] == row1s[index] || row6s[index] == row2s[index] || row6s[index] == row3s[index] || row6s[index] == row4s[index] || row6s[index] == row5s[index] || row6s[index] == row7s[index] || row6s[index] == row8s[index] || row6s[index] == row9s[index] {
+			retval = false
+		}
+
+		if row7s[index] == row1s[index] || row7s[index] == row2s[index] || row7s[index] == row3s[index] || row7s[index] == row4s[index] || row5s[index] == row6s[index] || row7s[index] == row6s[index] || row7s[index] == row8s[index] || row7s[index] == row9s[index] {
+			retval = false
+		}
+
+		if row8s[index] == row1s[index] || row8s[index] == row2s[index] || row8s[index] == row3s[index] || row8s[index] == row4s[index] || row8s[index] == row5s[index] || row8s[index] == row6s[index] || row8s[index] == row7s[index] || row8s[index] == row9s[index] {
+			retval = false
+		}
+
+		if row9s[index] == row1s[index] || row9s[index] == row2s[index] || row9s[index] == row3s[index] || row9s[index] == row4s[index] || row9s[index] == row5s[index] || row9s[index] == row6s[index] || row9s[index] == row7s[index] || row9s[index] == row8s[index] {
+			retval = false
+		}
+
+	}
+
+	return retval
+}

+ 42 - 0
solver/solver.go

@@ -0,0 +1,42 @@
+package solver
+
+import (
+	"fmt"
+	"sync"
+)
+
+func Run() {
+	solver := Solver{}
+	solver.row1 = "769104802"
+	solver.row2 = "154800060"
+	solver.row3 = "002700150"
+	solver.row4 = "600900308"
+	solver.row5 = "045328670"
+	solver.row6 = "328670945"
+	solver.row7 = "597410280"
+	solver.row8 = "006283090"
+	solver.row9 = "200590006"
+	solver.wg = sync.WaitGroup{}
+
+	solver.load_blocks()
+	fmt.Println("Total blocks:", len(solver.blocks))
+
+	// Find rows that fit with the entered rows
+	solver.find_blocks(&solver.row1, &solver.row1s)
+	solver.find_blocks(&solver.row2, &solver.row2s)
+	solver.find_blocks(&solver.row3, &solver.row3s)
+	solver.find_blocks(&solver.row4, &solver.row4s)
+	solver.find_blocks(&solver.row5, &solver.row5s)
+	solver.find_blocks(&solver.row6, &solver.row6s)
+	solver.find_blocks(&solver.row7, &solver.row7s)
+	solver.find_blocks(&solver.row8, &solver.row8s)
+	solver.find_blocks(&solver.row9, &solver.row9s)
+
+	solver.iter = len(solver.row1s) * len(solver.row2s) * len(solver.row3s) * len(solver.row4s) * len(solver.row5s) * len(solver.row6s) * len(solver.row7s) * len(solver.row8s) * len(solver.row9s)
+	fmt.Println("Number of iterations:", solver.iter)
+
+	solver.check_combinations()
+
+	fmt.Println(solver.solutions)
+
+}

+ 28 - 0
solver/stash.go

@@ -0,0 +1,28 @@
+package solver
+
+import (
+	"fmt"
+	"strconv"
+)
+
+func (solver *Solver) render_combination(row1 int, row2 int, row3 int, row4 int, row5 int, row6 int, row7 int, row8 int, row9 int) string {
+
+	row1s := strconv.Itoa(row1)
+	row2s := strconv.Itoa(row2)
+	row3s := strconv.Itoa(row3)
+	row4s := strconv.Itoa(row4)
+	row5s := strconv.Itoa(row5)
+	row6s := strconv.Itoa(row6)
+	row7s := strconv.Itoa(row7)
+	row8s := strconv.Itoa(row8)
+	row9s := strconv.Itoa(row9)
+
+	// combination = row1s + "\n" + row2s + "\n" + row3s + "\n" + row4s + "\n" + row5s + "\n" + row6s + "\n" + row7s + "\n" + row8s + "\n" + row9s + "\n"
+
+	return row1s + "\n" + row2s + "\n" + row3s + "\n" + row4s + "\n" + row5s + "\n" + row6s + "\n" + row7s + "\n" + row8s + "\n" + row9s + "\n"
+}
+
+func (solver *Solver) print_block(block int) {
+	digits := strconv.Itoa(block)
+	fmt.Printf("%c %c %c\n%c %c %c\n%c %c %c\n\n", digits[0], digits[1], digits[2], digits[3], digits[4], digits[5], digits[6], digits[7], digits[8])
+}

+ 29 - 0
solver/types.go

@@ -0,0 +1,29 @@
+package solver
+
+import "sync"
+
+type Solver struct {
+	blocks    []int
+	row1      string
+	row2      string
+	row3      string
+	row4      string
+	row5      string
+	row6      string
+	row7      string
+	row8      string
+	row9      string
+	row1s     []int
+	row2s     []int
+	row3s     []int
+	row4s     []int
+	row5s     []int
+	row6s     []int
+	row7s     []int
+	row8s     []int
+	row9s     []int
+	iter      int
+	counter   int
+	solutions []string
+	wg        sync.WaitGroup
+}