Compare commits
	
		
			11 Commits
		
	
	
		
			v20250126
			...
			7084a62962
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7084a62962 | |||
| 8d2cca657b | |||
| 56ebe616ab | |||
| fc555fa581 | |||
| 0e3aa42b78 | |||
| c72bc6b0e5 | |||
| c73c88679a | |||
| 81b44e1702 | |||
| c8f897cf8d | |||
| c0525c2bc8 | |||
| 3f6ba6e9dc | 
							
								
								
									
										20
									
								
								.gitea/workflows/demo.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								.gitea/workflows/demo.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					name: Gitea Actions Demo
 | 
				
			||||||
 | 
					run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀
 | 
				
			||||||
 | 
					on: [push]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  Explore-Gitea-Actions:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					      - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event."
 | 
				
			||||||
 | 
					      - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!"
 | 
				
			||||||
 | 
					      - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}."
 | 
				
			||||||
 | 
					      - name: Check out repository code
 | 
				
			||||||
 | 
					        uses: actions/checkout@v4
 | 
				
			||||||
 | 
					      - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner."
 | 
				
			||||||
 | 
					      - run: echo "🖥️ The workflow is now ready to test your code on the runner."
 | 
				
			||||||
 | 
					      - name: List files in the repository
 | 
				
			||||||
 | 
					        run: |
 | 
				
			||||||
 | 
					          ls ${{ gitea.workspace }}
 | 
				
			||||||
 | 
					      - run: echo "🍏 This job's status is ${{ job.status }}."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2,9 +2,17 @@
 | 
				
			|||||||
# See https://pre-commit.com/hooks.html for more hooks
 | 
					# See https://pre-commit.com/hooks.html for more hooks
 | 
				
			||||||
repos:
 | 
					repos:
 | 
				
			||||||
-   repo: https://github.com/pre-commit/pre-commit-hooks
 | 
					-   repo: https://github.com/pre-commit/pre-commit-hooks
 | 
				
			||||||
    rev: v3.2.0
 | 
					    rev: v5.0.0
 | 
				
			||||||
    hooks:
 | 
					    hooks:
 | 
				
			||||||
    -   id: trailing-whitespace
 | 
					    -   id: trailing-whitespace
 | 
				
			||||||
    -   id: end-of-file-fixer
 | 
					    -   id: end-of-file-fixer
 | 
				
			||||||
    -   id: check-yaml
 | 
					    -   id: check-yaml
 | 
				
			||||||
    -   id: check-added-large-files
 | 
					    -   id: check-added-large-files
 | 
				
			||||||
 | 
					-   repo: https://github.com/dnephin/pre-commit-golang
 | 
				
			||||||
 | 
					    rev: v0.5.1
 | 
				
			||||||
 | 
					    hooks:
 | 
				
			||||||
 | 
					      - id: go-fmt
 | 
				
			||||||
 | 
					      - id: go-imports
 | 
				
			||||||
 | 
					      - id: no-go-testing
 | 
				
			||||||
 | 
					      - id: golangci-lint
 | 
				
			||||||
 | 
					      - id: go-unit-tests
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							@@ -9,10 +9,19 @@ _(This was a learning project to get a better grasp of Golang. But more importan
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
I wrote [a blog post](https://blog.ligthert.net/posts/exploration-fun-and-process-cycles-of-sudoku/) about this.
 | 
					I wrote [a blog post](https://blog.ligthert.net/posts/exploration-fun-and-process-cycles-of-sudoku/) about this.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Features
 | 
				
			||||||
 | 
					* Worlds least efficient Sudoku solver
 | 
				
			||||||
 | 
					* Ability to assign a number of CPU cores to this task
 | 
				
			||||||
 | 
					* Split workloads among several computers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Usage
 | 
					## Usage
 | 
				
			||||||
To use the sudoku solver, run the binary with all the parameters available:
 | 
					To use the sudoku solver, run the binary with all the parameters available:
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
Usage of ./sudoku-funpark:
 | 
					Usage of ./sudoku-funpark:
 | 
				
			||||||
 | 
					  -numcpu int
 | 
				
			||||||
 | 
					    	Number of CPU cores to assign to this task. (default 12)
 | 
				
			||||||
 | 
					  -part int
 | 
				
			||||||
 | 
					    	Process part x in n parts. Cannot be lower than 1, or higher than specified in split. (default 1)
 | 
				
			||||||
  -row1 string
 | 
					  -row1 string
 | 
				
			||||||
    	1st row of the sudoku puzzle. (default "000000000")
 | 
					    	1st row of the sudoku puzzle. (default "000000000")
 | 
				
			||||||
  -row2 string
 | 
					  -row2 string
 | 
				
			||||||
@@ -31,6 +40,8 @@ Usage of ./sudoku-funpark:
 | 
				
			|||||||
    	8th row of the sudoku puzzle. (default "000000000")
 | 
					    	8th row of the sudoku puzzle. (default "000000000")
 | 
				
			||||||
  -row9 string
 | 
					  -row9 string
 | 
				
			||||||
    	9th row of the sudoku puzzle. (default "000000000")
 | 
					    	9th row of the sudoku puzzle. (default "000000000")
 | 
				
			||||||
 | 
					  -split int
 | 
				
			||||||
 | 
					    	Split the tasks in n parts. This depends on the availability of the first row. (default 1)
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Instead of using the 3x3 blocks with 3x3 digits, it uses horizontal rows from top to bottom.
 | 
					Instead of using the 3x3 blocks with 3x3 digits, it uses horizontal rows from top to bottom.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,7 @@ tasks:
 | 
				
			|||||||
    silent: true
 | 
					    silent: true
 | 
				
			||||||
  precommit:
 | 
					  precommit:
 | 
				
			||||||
    cmds:
 | 
					    cmds:
 | 
				
			||||||
 | 
					      - pre-commit autoupdate
 | 
				
			||||||
      - pre-commit run --all
 | 
					      - pre-commit run --all
 | 
				
			||||||
    silent: true
 | 
					    silent: true
 | 
				
			||||||
  lint:
 | 
					  lint:
 | 
				
			||||||
@@ -33,3 +34,7 @@ tasks:
 | 
				
			|||||||
      - rm {{.BUILD_DIR}}/* || true
 | 
					      - rm {{.BUILD_DIR}}/* || true
 | 
				
			||||||
      - go tool dist list | grep -v android | grep -v ios | grep -v wasip1 | awk -F '/' '{printf "echo Compiling %s/%s; env CGO_ENABLED=1 GOOS=%s GOARCH=%s go build -o {{.BUILD_DIR}}/{{.APP}}.%s-%s\n",$1,$2,$1,$2,$1,$2 }' | sh
 | 
					      - go tool dist list | grep -v android | grep -v ios | grep -v wasip1 | awk -F '/' '{printf "echo Compiling %s/%s; env CGO_ENABLED=1 GOOS=%s GOARCH=%s go build -o {{.BUILD_DIR}}/{{.APP}}.%s-%s\n",$1,$2,$1,$2,$1,$2 }' | sh
 | 
				
			||||||
      - for i in `ls {{.BUILD_DIR}}/*windows*`; do mv -v $i $i.exe; done
 | 
					      - for i in `ls {{.BUILD_DIR}}/*windows*`; do mv -v $i $i.exe; done
 | 
				
			||||||
 | 
					  gource:
 | 
				
			||||||
 | 
					    cmds:
 | 
				
			||||||
 | 
					      - gource --auto-skip-seconds 1 --key -r 60
 | 
				
			||||||
 | 
					    silent: true
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ import (
 | 
				
			|||||||
//go:embed blocks.csv
 | 
					//go:embed blocks.csv
 | 
				
			||||||
var f embed.FS
 | 
					var f embed.FS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) load_blocks() {
 | 
					func (solver *Solver) loadBlocks() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer solver.timeTrack(time.Now(), "Loaded blocks")
 | 
						defer solver.timeTrack(time.Now(), "Loaded blocks")
 | 
				
			||||||
	log.Println("Loading blocks")
 | 
						log.Println("Loading blocks")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ import (
 | 
				
			|||||||
	"runtime"
 | 
						"runtime"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) parse_flags() {
 | 
					func (solver *Solver) parseFlags() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Define variables
 | 
						// Define variables
 | 
				
			||||||
	var row1 string
 | 
						var row1 string
 | 
				
			||||||
@@ -33,7 +33,7 @@ func (solver *Solver) parse_flags() {
 | 
				
			|||||||
	flag.StringVar(&row7, "row7", "000000000", "7th 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(&row8, "row8", "000000000", "8th row of the sudoku puzzle.")
 | 
				
			||||||
	flag.StringVar(&row9, "row9", "000000000", "9th 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(&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(&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.")
 | 
						flag.IntVar(&part, "part", 1, "Process part x in n parts. Cannot be lower than 1, or higher than specified in split.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,33 +41,33 @@ func (solver *Solver) parse_flags() {
 | 
				
			|||||||
	flag.Parse()
 | 
						flag.Parse()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Process any changes to the CPU usage.
 | 
						// Process any changes to the CPU usage.
 | 
				
			||||||
	if solver.numcpus <= 0 {
 | 
						if solver.numCPUs <= 0 {
 | 
				
			||||||
		log.Printf("ERROR: Number of CPU cores must be 1 or higher.\n\n")
 | 
							log.Printf("ERROR: Number of CPU cores must be 1 or higher.\n\n")
 | 
				
			||||||
		solver.print_Usage()
 | 
							solver.printUsage()
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if solver.numcpus != runtime.NumCPU() {
 | 
						if solver.numCPUs != runtime.NumCPU() {
 | 
				
			||||||
		runtime.GOMAXPROCS(solver.numcpus)
 | 
							runtime.GOMAXPROCS(solver.numCPUs)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Process rows
 | 
						// Process rows
 | 
				
			||||||
	if row1 == "000000000" || row2 == "000000000" || row3 == "000000000" || row4 == "000000000" || row5 == "000000000" || row6 == "000000000" || row7 == "000000000" || row8 == "000000000" || row9 == "000000000" {
 | 
						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")
 | 
							log.Printf("ERROR: All parameters must be entered.\n\n")
 | 
				
			||||||
		solver.print_Usage()
 | 
							solver.printUsage()
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Validate the row (never trust user input)
 | 
						// Validate the row (never trust user input)
 | 
				
			||||||
	solver.validate_row("row1", row1)
 | 
						solver.validateRow("row1", row1)
 | 
				
			||||||
	solver.validate_row("row2", row2)
 | 
						solver.validateRow("row2", row2)
 | 
				
			||||||
	solver.validate_row("row3", row3)
 | 
						solver.validateRow("row3", row3)
 | 
				
			||||||
	solver.validate_row("row4", row4)
 | 
						solver.validateRow("row4", row4)
 | 
				
			||||||
	solver.validate_row("row5", row5)
 | 
						solver.validateRow("row5", row5)
 | 
				
			||||||
	solver.validate_row("row6", row6)
 | 
						solver.validateRow("row6", row6)
 | 
				
			||||||
	solver.validate_row("row7", row7)
 | 
						solver.validateRow("row7", row7)
 | 
				
			||||||
	solver.validate_row("row8", row8)
 | 
						solver.validateRow("row8", row8)
 | 
				
			||||||
	solver.validate_row("row9", row9)
 | 
						solver.validateRow("row9", row9)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Put entries in into the struct
 | 
						// Put entries in into the struct
 | 
				
			||||||
	solver.row1 = row1
 | 
						solver.row1 = row1
 | 
				
			||||||
@@ -84,14 +84,14 @@ func (solver *Solver) parse_flags() {
 | 
				
			|||||||
	// Ensure split and part are 1 or higher
 | 
						// Ensure split and part are 1 or higher
 | 
				
			||||||
	if split <= 0 || part <= 0 {
 | 
						if split <= 0 || part <= 0 {
 | 
				
			||||||
		log.Printf("ERROR: '-split' and '-part' need to be 1 or higher.\n")
 | 
							log.Printf("ERROR: '-split' and '-part' need to be 1 or higher.\n")
 | 
				
			||||||
		solver.print_Usage()
 | 
							solver.printUsage()
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Ensure part is between 1 and split
 | 
						// Ensure part is between 1 and split
 | 
				
			||||||
	if part > split {
 | 
						if part > split {
 | 
				
			||||||
		log.Printf("ERROR: '-part' cannot be bigger than `-split`.\n")
 | 
							log.Printf("ERROR: '-part' cannot be bigger than `-split`.\n")
 | 
				
			||||||
		solver.print_Usage()
 | 
							solver.printUsage()
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -100,7 +100,7 @@ func (solver *Solver) parse_flags() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) validate_row(name string, row string) {
 | 
					func (solver *Solver) validateRow(name string, row string) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var found bool
 | 
						var found bool
 | 
				
			||||||
	var double bool
 | 
						var double bool
 | 
				
			||||||
@@ -109,18 +109,18 @@ func (solver *Solver) validate_row(name string, row string) {
 | 
				
			|||||||
	// 1. Make sure the row is 9 in length
 | 
						// 1. Make sure the row is 9 in length
 | 
				
			||||||
	if len(row) != 9 {
 | 
						if len(row) != 9 {
 | 
				
			||||||
		log.Printf("ERROR: Invalid length of %s (%s), must be 9 numbers\n\n", name, row)
 | 
							log.Printf("ERROR: Invalid length of %s (%s), must be 9 numbers\n\n", name, row)
 | 
				
			||||||
		solver.print_Usage()
 | 
							solver.printUsage()
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 2. Ensure all digits are numbers
 | 
						// 2. Ensure all digits are numbers
 | 
				
			||||||
	for _, value := range row {
 | 
						for _, value := range row {
 | 
				
			||||||
		found = solver.valid_char(value)
 | 
							found = solver.validChar(value)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !found {
 | 
						if !found {
 | 
				
			||||||
		log.Printf("ERROR: Invalid character of %s (%s), must be 9 numbers\n\n", name, row)
 | 
							log.Printf("ERROR: Invalid character of %s (%s), must be 9 numbers\n\n", name, row)
 | 
				
			||||||
		solver.print_Usage()
 | 
							solver.printUsage()
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -137,14 +137,13 @@ func (solver *Solver) validate_row(name string, row string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if double {
 | 
						if double {
 | 
				
			||||||
		log.Printf("ERROR: Double character of %s (%s), numbers between 1 and 9 may only be entered once\n\n", name, row)
 | 
							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()
 | 
							solver.printUsage()
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) valid_char(char rune) bool {
 | 
					func (solver *Solver) validChar(char rune) (valid bool) {
 | 
				
			||||||
	var valid bool
 | 
					 | 
				
			||||||
	decvals := [10]int{48, 49, 50, 51, 52, 53, 54, 55, 56, 57}
 | 
						decvals := [10]int{48, 49, 50, 51, 52, 53, 54, 55, 56, 57}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, value := range decvals {
 | 
						for _, value := range decvals {
 | 
				
			||||||
@@ -156,7 +155,7 @@ func (solver *Solver) valid_char(char rune) bool {
 | 
				
			|||||||
	return valid
 | 
						return valid
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) print_Usage() {
 | 
					func (solver *Solver) printUsage() {
 | 
				
			||||||
	fmt.Fprintf(flag.CommandLine.Output(), "Usage of %s:\n", os.Args[0])
 | 
						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(), "\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])
 | 
						fmt.Fprintf(flag.CommandLine.Output(), "Example: %s -row1 ... -row2 ... -row3 ... (etc)\n\n", os.Args[0])
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,9 +5,22 @@ import (
 | 
				
			|||||||
	"log"
 | 
						"log"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) print_solutions() {
 | 
					func (solver *Solver) printSolutions() {
 | 
				
			||||||
	for solution_index, solution := range solver.solutions {
 | 
						for solutionIndex, solution := range solver.solutions {
 | 
				
			||||||
		log.Printf("\nSolution #%d:", solution_index+1)
 | 
							log.Printf("\nSolution #%d:", solutionIndex+1)
 | 
				
			||||||
		fmt.Println(solution)
 | 
							//fmt.Println(solution)
 | 
				
			||||||
 | 
							fmt.Println("╔═══════════╗")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[0:3] + "│" + solution[3:6] + "│" + solution[6:9] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[10:13] + "│" + solution[13:16] + "│" + solution[16:19] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[20:23] + "│" + solution[23:26] + "│" + solution[26:29] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("╟───┼───┼───╢")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[30:33] + "│" + solution[33:36] + "│" + solution[36:39] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[40:43] + "│" + solution[43:46] + "│" + solution[46:49] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[50:53] + "│" + solution[53:56] + "│" + solution[56:59] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("╟───┼───┼───╢")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[60:63] + "│" + solution[63:66] + "│" + solution[66:69] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[70:73] + "│" + solution[73:76] + "│" + solution[76:79] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("║" + solution[80:83] + "│" + solution[83:86] + "│" + solution[86:89] + "╢")
 | 
				
			||||||
 | 
							fmt.Println("╚═══════════╝")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,52 +6,52 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) populate_blocks() {
 | 
					func (solver *Solver) populateBlocks() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	defer solver.timeTrack(time.Now(), "Populated blocks")
 | 
						defer solver.timeTrack(time.Now(), "Populated blocks")
 | 
				
			||||||
	log.Println("Populating blocks")
 | 
						log.Println("Populating blocks")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	solver.find_blocks(&solver.row1, &solver.row1s)
 | 
						solver.findBlocks(&solver.row1, &solver.row1s)
 | 
				
			||||||
	solver.find_blocks(&solver.row2, &solver.row2s)
 | 
						solver.findBlocks(&solver.row2, &solver.row2s)
 | 
				
			||||||
	solver.find_blocks(&solver.row3, &solver.row3s)
 | 
						solver.findBlocks(&solver.row3, &solver.row3s)
 | 
				
			||||||
	solver.find_blocks(&solver.row4, &solver.row4s)
 | 
						solver.findBlocks(&solver.row4, &solver.row4s)
 | 
				
			||||||
	solver.find_blocks(&solver.row5, &solver.row5s)
 | 
						solver.findBlocks(&solver.row5, &solver.row5s)
 | 
				
			||||||
	solver.find_blocks(&solver.row6, &solver.row6s)
 | 
						solver.findBlocks(&solver.row6, &solver.row6s)
 | 
				
			||||||
	solver.find_blocks(&solver.row7, &solver.row7s)
 | 
						solver.findBlocks(&solver.row7, &solver.row7s)
 | 
				
			||||||
	solver.find_blocks(&solver.row8, &solver.row8s)
 | 
						solver.findBlocks(&solver.row8, &solver.row8s)
 | 
				
			||||||
	solver.find_blocks(&solver.row9, &solver.row9s)
 | 
						solver.findBlocks(&solver.row9, &solver.row9s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// This calculates and stores the total number of solutions to validate.
 | 
						// This calculates and stores the total number of solutions to validate.
 | 
				
			||||||
	solver.iter = int64(len(solver.row1s)) * int64(len(solver.row2s)) * int64(len(solver.row3s)) * int64(len(solver.row4s)) * int64(len(solver.row5s)) * int64(len(solver.row6s)) * int64(len(solver.row7s)) * int64(len(solver.row8s)) * int64(len(solver.row9s))
 | 
						solver.iter = int64(len(solver.row1s)) * int64(len(solver.row2s)) * int64(len(solver.row3s)) * int64(len(solver.row4s)) * int64(len(solver.row5s)) * int64(len(solver.row6s)) * int64(len(solver.row7s)) * int64(len(solver.row8s)) * int64(len(solver.row9s))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) find_blocks(row *string, rows *[]int) {
 | 
					func (solver *Solver) findBlocks(row *string, rows *[]int) {
 | 
				
			||||||
	// Declare selection
 | 
						// Declare selection
 | 
				
			||||||
	var selection []int
 | 
						var selection []int
 | 
				
			||||||
	var curr_blocks []int
 | 
						var currBlocks []int
 | 
				
			||||||
	func_row := *row
 | 
						funcRow := *row
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for letter := range func_row {
 | 
						for letter := range funcRow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if len(selection) == 0 {
 | 
							if len(selection) == 0 {
 | 
				
			||||||
			curr_blocks = solver.blocks
 | 
								currBlocks = solver.blocks
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			curr_blocks = selection
 | 
								currBlocks = selection
 | 
				
			||||||
			selection = nil
 | 
								selection = nil
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, block := range curr_blocks {
 | 
							for _, block := range currBlocks {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			curr_row := strconv.Itoa(block)
 | 
								currRow := strconv.Itoa(block)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if func_row[letter] == curr_row[letter] {
 | 
								if funcRow[letter] == currRow[letter] {
 | 
				
			||||||
				found_row, _ := strconv.Atoi(curr_row)
 | 
									foundRow, _ := strconv.Atoi(currRow)
 | 
				
			||||||
				selection = append(selection, found_row)
 | 
									selection = append(selection, foundRow)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if func_row[letter] == '0' {
 | 
								if funcRow[letter] == '0' {
 | 
				
			||||||
				found_row, _ := strconv.Atoi(curr_row)
 | 
									foundRow, _ := strconv.Atoi(currRow)
 | 
				
			||||||
				selection = append(selection, found_row)
 | 
									selection = append(selection, foundRow)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} // End for-loop
 | 
							} // End for-loop
 | 
				
			||||||
@@ -61,17 +61,17 @@ func (solver *Solver) find_blocks(row *string, rows *[]int) {
 | 
				
			|||||||
	*rows = selection
 | 
						*rows = selection
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) check_combinations() {
 | 
					func (solver *Solver) checkCombinations() {
 | 
				
			||||||
	for rows1_index := range solver.row1s {
 | 
						for rows1Index := range solver.row1s {
 | 
				
			||||||
		for rows2_index := range solver.row2s {
 | 
							for rows2Index := range solver.row2s {
 | 
				
			||||||
			for rows3_index := range solver.row3s {
 | 
								for rows3Index := range solver.row3s {
 | 
				
			||||||
				for rows4_index := range solver.row4s {
 | 
									for rows4Index := range solver.row4s {
 | 
				
			||||||
					for rows5_index := range solver.row5s {
 | 
										for rows5Index := range solver.row5s {
 | 
				
			||||||
						for rows6_index := range solver.row6s {
 | 
											for rows6Index := range solver.row6s {
 | 
				
			||||||
							for rows7_index := range solver.row7s {
 | 
												for rows7Index := range solver.row7s {
 | 
				
			||||||
								for rows8_index := range solver.row8s {
 | 
													for rows8Index := range solver.row8s {
 | 
				
			||||||
									for rows9_index := range solver.row9s {
 | 
														for rows9Index := 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)
 | 
															go solver.routineValidator(rows1Index, rows2Index, rows3Index, rows4Index, rows5Index, rows6Index, rows7Index, rows8Index, rows9Index)
 | 
				
			||||||
									}
 | 
														}
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
@@ -83,13 +83,13 @@ func (solver *Solver) check_combinations() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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) {
 | 
					func (solver *Solver) routineValidator(rows1Index int, rows2Index int, rows3Index int, rows4Index int, rows5Index int, rows6Index int, rows7Index int, rows8Index int, rows9Index int) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// solver.counter = solver.counter + 1
 | 
						// solver.counter = solver.counter + 1
 | 
				
			||||||
	solver.counter.Add(1)
 | 
						solver.counter.Add(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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]) {
 | 
						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.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.solutions = append(solver.solutions, solver.renderCombination(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]))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -108,13 +108,13 @@ func (solver *Solver) tracker() {
 | 
				
			|||||||
	var track int
 | 
						var track int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Tracking the rate, starting point
 | 
						// Tracking the rate, starting point
 | 
				
			||||||
	var rate_start int64
 | 
						var rateStart int64
 | 
				
			||||||
	// Tracking the rate, difference between previous iterations
 | 
						// Tracking the rate, difference between previous iterations
 | 
				
			||||||
	var rate_diff int64
 | 
						var rateDiff int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Tracking duration
 | 
						// Tracking duration
 | 
				
			||||||
	var timer_start = time.Now()
 | 
						var timerStart = time.Now()
 | 
				
			||||||
	// Prevent division-by-zero error when establishing `rate_diff`
 | 
						// Prevent division-by-zero error when establishing `rateDiff`
 | 
				
			||||||
	time.Sleep(time.Second)
 | 
						time.Sleep(time.Second)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Estimation how long it will take
 | 
						// Estimation how long it will take
 | 
				
			||||||
@@ -127,30 +127,36 @@ func (solver *Solver) tracker() {
 | 
				
			|||||||
		percentage = (float32(solver.counter.Load()) / (float32(solver.iter) / 100))
 | 
							percentage = (float32(solver.counter.Load()) / (float32(solver.iter) / 100))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Reset the loop
 | 
							// Reset the loop
 | 
				
			||||||
		rate_diff = solver.counter.Load() - rate_start
 | 
							rateDiff = solver.counter.Load() - rateStart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if track <= int(percentage) || rate_diff == 0 { // Start if-statement
 | 
							if track <= int(percentage) || rateDiff == 0 { // Start if-statement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Make sure something happened, making rate_start the only reliable variable
 | 
								// Make sure something happened, making rateStart the only reliable variable
 | 
				
			||||||
			if rate_diff == 0 {
 | 
								if rateDiff == 0 {
 | 
				
			||||||
				percentage = 100
 | 
									percentage = 100
 | 
				
			||||||
				solver.counter.Store(solver.iter)
 | 
									solver.counter.Store(solver.iter)
 | 
				
			||||||
				done = true
 | 
									done = true
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			timer_elapsed := time.Since(timer_start)
 | 
								timer_elapsed := time.Since(timerStart)
 | 
				
			||||||
			solver.rates = append(solver.rates, rate_diff)
 | 
								solver.rates = append(solver.rates, rateDiff)
 | 
				
			||||||
			rate_avg := solver.calc_avg()
 | 
								rate_avg := solver.calcAVG()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Estimate when this is finished
 | 
								// Estimate when this is finished
 | 
				
			||||||
			if rate_diff == 0 {
 | 
								if rateDiff == 0 {
 | 
				
			||||||
				est_fin = "N/A"
 | 
									est_fin = "N/A"
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				est_fin = solver.secondsToHuman((solver.iter - solver.counter.Load()) / rate_avg)
 | 
									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"
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									est_fin = est.String()
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Printing the progress
 | 
								// Printing the progress
 | 
				
			||||||
			log.Println("Processing: " + strconv.Itoa(int(percentage)) + "% (" + strconv.FormatInt(solver.counter.Load(), 10) + "/" + strconv.Itoa(int(solver.iter)) + "); Rate: " + strconv.FormatInt(rate_diff, 10) + "/sec for " + timer_elapsed.String() + "; Time left (est.): " + est_fin)
 | 
								log.Println("Processing: " + strconv.Itoa(int(percentage)) + "% (" + strconv.FormatInt(solver.counter.Load(), 10) + "/" + strconv.Itoa(int(solver.iter)) + "); Rate: " + strconv.FormatInt(rateDiff, 10) + "/sec for " + timer_elapsed.String() + "; Time left (est.): " + est_fin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// After we are done printing, exit this for-loop
 | 
								// After we are done printing, exit this for-loop
 | 
				
			||||||
			if percentage == 100 {
 | 
								if percentage == 100 {
 | 
				
			||||||
@@ -164,22 +170,22 @@ func (solver *Solver) tracker() {
 | 
				
			|||||||
				track = track + 1
 | 
									track = track + 1
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			timer_start = time.Now()
 | 
								timerStart = time.Now()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Resert the rate counter
 | 
							// Resert the rate counter
 | 
				
			||||||
		rate_start = solver.counter.Load()
 | 
							rateStart = solver.counter.Load()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Sleep for a second
 | 
							// Sleep for a second
 | 
				
			||||||
 | 
							if solver.iter != solver.counter.Load() {
 | 
				
			||||||
			time.Sleep(1 * time.Second)
 | 
								time.Sleep(1 * time.Second)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	} // End for-loop
 | 
						} // End for-loop
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) validate_combination(row1 int, row2 int, row3 int, row4 int, row5 int, row6 int, row7 int, row8 int, row9 int) bool {
 | 
					func (solver *Solver) validateCombination(row1 int, row2 int, row3 int, row4 int, row5 int, row6 int, row7 int, row8 int, row9 int) (retval bool) {
 | 
				
			||||||
	var retval bool
 | 
					 | 
				
			||||||
	retval = true
 | 
						retval = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	row1s := strconv.Itoa(row1)
 | 
						row1s := strconv.Itoa(row1)
 | 
				
			||||||
@@ -234,14 +240,14 @@ func (solver *Solver) validate_combination(row1 int, row2 int, row3 int, row4 in
 | 
				
			|||||||
	return retval
 | 
						return retval
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) calc_avg() (avg int64) {
 | 
					func (solver *Solver) calcAVG() (avg int64) {
 | 
				
			||||||
	var avg_sum int64
 | 
						var avgSum int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, value := range solver.rates {
 | 
						for _, value := range solver.rates {
 | 
				
			||||||
		avg_sum += value
 | 
							avgSum += value
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	avg = avg_sum / int64(len(solver.rates))
 | 
						avg = avgSum / int64(len(solver.rates))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,38 +6,39 @@ import (
 | 
				
			|||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The main loop that orchastrates all the logic.
 | 
				
			||||||
func Run() {
 | 
					func Run() {
 | 
				
			||||||
	// Instantiate the Solver interface
 | 
						// Instantiate the Solver interface
 | 
				
			||||||
	solver := Solver{}
 | 
						solver := Solver{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Parse and handle flags
 | 
						// Parse and handle flags
 | 
				
			||||||
	solver.parse_flags()
 | 
						solver.parseFlags()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Report number of CPUs being used, if set.
 | 
						// Report number of CPUs being used, if set.
 | 
				
			||||||
	if runtime.NumCPU() != solver.numcpus {
 | 
						if runtime.NumCPU() != solver.numCPUs {
 | 
				
			||||||
		log.Println("Using " + strconv.Itoa(solver.numcpus) + " CPUs, (was " + strconv.Itoa(runtime.NumCPU()) + ")")
 | 
							log.Println("Using " + strconv.Itoa(solver.numCPUs) + " CPUs, (was " + strconv.Itoa(runtime.NumCPU()) + ")")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Load blocks from CSV file
 | 
						// Load blocks from CSV file
 | 
				
			||||||
	solver.load_blocks()
 | 
						solver.loadBlocks()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Find rows that fit with the entered rows
 | 
						// Find rows that fit with the entered rows
 | 
				
			||||||
	solver.populate_blocks()
 | 
						solver.populateBlocks()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If needed, split the workload
 | 
						// If needed, split the workload
 | 
				
			||||||
	// May exit and throw an error if the work load isn't viable
 | 
						// May exit and throw an error if the work load isn't viable
 | 
				
			||||||
	if solver.split != 1 {
 | 
						if solver.split != 1 {
 | 
				
			||||||
		solver.select_workload()
 | 
							solver.selectWorkload()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Print the total number of solutions to validate
 | 
						// Print the total number of solutions to validate
 | 
				
			||||||
	log.Println("Number of (potential) solutions:", solver.iter)
 | 
						log.Println("Number of (potential) solutions:", solver.iter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Check the number of solutions
 | 
						// Check the number of solutions
 | 
				
			||||||
	go solver.check_combinations()
 | 
						go solver.checkCombinations()
 | 
				
			||||||
	solver.tracker()
 | 
						solver.tracker()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Print the valid solutions
 | 
						// Print the valid solutions
 | 
				
			||||||
	solver.print_solutions()
 | 
						solver.printSolutions()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,7 @@ import (
 | 
				
			|||||||
// Perform some checks
 | 
					// Perform some checks
 | 
				
			||||||
// and
 | 
					// and
 | 
				
			||||||
// Modify solver.row1s so it limits the workload to what is only desired.
 | 
					// Modify solver.row1s so it limits the workload to what is only desired.
 | 
				
			||||||
func (solver *Solver) select_workload() {
 | 
					func (solver *Solver) selectWorkload() {
 | 
				
			||||||
	if solver.split > len(solver.row1s) {
 | 
						if solver.split > len(solver.row1s) {
 | 
				
			||||||
		log.Println("ERROR: Unable to divide the workload in " + strconv.Itoa(solver.split) + " parts, when only " + strconv.Itoa(len(solver.row1s)) + " are available.\n\n")
 | 
							log.Println("ERROR: Unable to divide the workload in " + strconv.Itoa(solver.split) + " parts, when only " + strconv.Itoa(len(solver.row1s)) + " are available.\n\n")
 | 
				
			||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
@@ -18,12 +18,12 @@ func (solver *Solver) select_workload() {
 | 
				
			|||||||
	defer solver.timeTrack(time.Now(), "Workload set")
 | 
						defer solver.timeTrack(time.Now(), "Workload set")
 | 
				
			||||||
	log.Println("Setting workload")
 | 
						log.Println("Setting workload")
 | 
				
			||||||
	log.Println("We are agent " + strconv.Itoa(solver.part) + " of " + strconv.Itoa(solver.split))
 | 
						log.Println("We are agent " + strconv.Itoa(solver.part) + " of " + strconv.Itoa(solver.split))
 | 
				
			||||||
	workloads := solver.split_workload()
 | 
						workloads := solver.splitWorkload()
 | 
				
			||||||
	solver.set_workload(workloads)
 | 
						solver.setWorkload(workloads)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Determine how workload should be split among the agents
 | 
					// Determine how workload should be split among the agents
 | 
				
			||||||
func (solver *Solver) split_workload() []int {
 | 
					func (solver *Solver) splitWorkload() []int {
 | 
				
			||||||
	agents := make([]int, solver.split)
 | 
						agents := make([]int, solver.split)
 | 
				
			||||||
	var tracker int
 | 
						var tracker int
 | 
				
			||||||
	var tasks int = len(solver.row1s)
 | 
						var tasks int = len(solver.row1s)
 | 
				
			||||||
@@ -41,7 +41,7 @@ func (solver *Solver) split_workload() []int {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Set the workload by setting solver.row1s
 | 
					// Set the workload by setting solver.row1s
 | 
				
			||||||
func (solver *Solver) set_workload(agents []int) {
 | 
					func (solver *Solver) setWorkload(agents []int) {
 | 
				
			||||||
	var start int = 0
 | 
						var start int = 0
 | 
				
			||||||
	var finish int = 0
 | 
						var finish int = 0
 | 
				
			||||||
	for key, value := range agents {
 | 
						for key, value := range agents {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import (
 | 
				
			|||||||
	"strconv"
 | 
						"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 {
 | 
					func (solver *Solver) renderCombination(row1 int, row2 int, row3 int, row4 int, row5 int, row6 int, row7 int, row8 int, row9 int) string {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	row1s := strconv.Itoa(row1)
 | 
						row1s := strconv.Itoa(row1)
 | 
				
			||||||
	row2s := strconv.Itoa(row2)
 | 
						row2s := strconv.Itoa(row2)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,8 +2,6 @@ package solver
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"log"
 | 
						"log"
 | 
				
			||||||
	"math"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -11,46 +9,3 @@ func (solver *Solver) timeTrack(start time.Time, msg string) {
 | 
				
			|||||||
	elapsed := time.Since(start)
 | 
						elapsed := time.Since(start)
 | 
				
			||||||
	log.Printf("%s (%s)", msg, elapsed)
 | 
						log.Printf("%s (%s)", msg, elapsed)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
// Stolen from https://socketloop.com/tutorials/golang-convert-seconds-to-human-readable-time-format-example
 | 
					 | 
				
			||||||
func (solver *Solver) plural(count int, singular string) (result string) {
 | 
					 | 
				
			||||||
	if (count == 1) || (count == 0) {
 | 
					 | 
				
			||||||
		result = strconv.Itoa(count) + " " + singular + " "
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		result = strconv.Itoa(count) + " " + singular + "s "
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (solver *Solver) secondsToHuman(input int64) (result string) {
 | 
					 | 
				
			||||||
	years := math.Floor(float64(input) / 60 / 60 / 24 / 7 / 30 / 12)
 | 
					 | 
				
			||||||
	seconds := input % (60 * 60 * 24 * 7 * 30 * 12)
 | 
					 | 
				
			||||||
	months := math.Floor(float64(seconds) / 60 / 60 / 24 / 7 / 30)
 | 
					 | 
				
			||||||
	seconds = input % (60 * 60 * 24 * 7 * 30)
 | 
					 | 
				
			||||||
	weeks := math.Floor(float64(seconds) / 60 / 60 / 24 / 7)
 | 
					 | 
				
			||||||
	seconds = input % (60 * 60 * 24 * 7)
 | 
					 | 
				
			||||||
	days := math.Floor(float64(seconds) / 60 / 60 / 24)
 | 
					 | 
				
			||||||
	seconds = input % (60 * 60 * 24)
 | 
					 | 
				
			||||||
	hours := math.Floor(float64(seconds) / 60 / 60)
 | 
					 | 
				
			||||||
	seconds = input % (60 * 60)
 | 
					 | 
				
			||||||
	minutes := math.Floor(float64(seconds) / 60)
 | 
					 | 
				
			||||||
	seconds = input % 60
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if years > 0 {
 | 
					 | 
				
			||||||
		result = solver.plural(int(years), "year") + solver.plural(int(months), "month") + solver.plural(int(weeks), "week") + solver.plural(int(days), "day") + solver.plural(int(hours), "hour") + solver.plural(int(minutes), "minute") + solver.plural(int(seconds), "second")
 | 
					 | 
				
			||||||
	} else if months > 0 {
 | 
					 | 
				
			||||||
		result = solver.plural(int(months), "month") + solver.plural(int(weeks), "week") + solver.plural(int(days), "day") + solver.plural(int(hours), "hour") + solver.plural(int(minutes), "minute") + solver.plural(int(seconds), "second")
 | 
					 | 
				
			||||||
	} else if weeks > 0 {
 | 
					 | 
				
			||||||
		result = solver.plural(int(weeks), "week") + solver.plural(int(days), "day") + solver.plural(int(hours), "hour") + solver.plural(int(minutes), "minute") + solver.plural(int(seconds), "second")
 | 
					 | 
				
			||||||
	} else if days > 0 {
 | 
					 | 
				
			||||||
		result = solver.plural(int(days), "day") + solver.plural(int(hours), "hour") + solver.plural(int(minutes), "minute") + solver.plural(int(seconds), "second")
 | 
					 | 
				
			||||||
	} else if hours > 0 {
 | 
					 | 
				
			||||||
		result = solver.plural(int(hours), "hour") + solver.plural(int(minutes), "minute") + solver.plural(int(seconds), "second")
 | 
					 | 
				
			||||||
	} else if minutes > 0 {
 | 
					 | 
				
			||||||
		result = solver.plural(int(minutes), "minute") + solver.plural(int(seconds), "second")
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		result = solver.plural(int(seconds), "second")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import (
 | 
				
			|||||||
	"sync/atomic"
 | 
						"sync/atomic"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Struct/Interface containing all the important variabes it functions need access to.
 | 
				
			||||||
type Solver struct {
 | 
					type Solver struct {
 | 
				
			||||||
	blocks    []int
 | 
						blocks    []int
 | 
				
			||||||
	row1      string
 | 
						row1      string
 | 
				
			||||||
@@ -28,7 +29,7 @@ type Solver struct {
 | 
				
			|||||||
	counter   atomic.Int64
 | 
						counter   atomic.Int64
 | 
				
			||||||
	solutions []string
 | 
						solutions []string
 | 
				
			||||||
	rates     []int64
 | 
						rates     []int64
 | 
				
			||||||
	numcpus   int
 | 
						numCPUs   int
 | 
				
			||||||
	split     int
 | 
						split     int
 | 
				
			||||||
	part      int
 | 
						part      int
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ func (solver *Solver) routine_row8(index1 int, index2 int, index3 int, index4 in
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (solver *Solver) routine_row9(index1 int, index2 int, index3 int, index4 int, index5 int, index6 int, index7 int, index8 int, index9 int) {
 | 
					func (solver *Solver) routine_row9(index1 int, index2 int, index3 int, index4 int, index5 int, index6 int, index7 int, index8 int, index9 int) {
 | 
				
			||||||
	go solver.routine_validator(index1, index2, index3, index4, index5, index6, index7, index8, index9)
 | 
						go solver.routineValidator(index1, index2, index3, index4, index5, index6, index7, index8, index9)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// blocks.go
 | 
					// blocks.go
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user