diff --git a/controller/types.go b/controller/types.go index 340c32c..bca66c2 100644 --- a/controller/types.go +++ b/controller/types.go @@ -1,9 +1,5 @@ package controller -import ( - "sync/atomic" -) - type Controller struct { Blocks []int Row1 string @@ -15,19 +11,7 @@ type Controller struct { 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 int64 - Counter atomic.Int64 Solutions []string - Rates []int64 NumCPUs int Split int Part int diff --git a/main.go b/main.go index 8c11848..3702a4a 100644 --- a/main.go +++ b/main.go @@ -37,7 +37,7 @@ func main() { } // Print the total number of solutions to validate - log.Println("Number of (potential) solutions:", controller.Iter) + log.Println("Number of (potential) solutions:", solver.Iter) // Check the number of solutions go solver.CheckCombinations() diff --git a/solver/processing.go b/solver/processing.go index b55094e..9f1b0b5 100644 --- a/solver/processing.go +++ b/solver/processing.go @@ -11,18 +11,18 @@ func (solver *Solver) PopulateBlocks() { defer solver.timeTrack(time.Now(), "Populated blocks") log.Println("Populating blocks") - solver.findBlocks(&solver.Controller.Row1, &solver.Controller.Row1s) - solver.findBlocks(&solver.Controller.Row2, &solver.Controller.Row2s) - solver.findBlocks(&solver.Controller.Row3, &solver.Controller.Row3s) - solver.findBlocks(&solver.Controller.Row4, &solver.Controller.Row4s) - solver.findBlocks(&solver.Controller.Row5, &solver.Controller.Row5s) - solver.findBlocks(&solver.Controller.Row6, &solver.Controller.Row6s) - solver.findBlocks(&solver.Controller.Row7, &solver.Controller.Row7s) - solver.findBlocks(&solver.Controller.Row8, &solver.Controller.Row8s) - solver.findBlocks(&solver.Controller.Row9, &solver.Controller.Row9s) + 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.Controller.Iter = int64(len(solver.Controller.Row1s)) * int64(len(solver.Controller.Row2s)) * int64(len(solver.Controller.Row3s)) * int64(len(solver.Controller.Row4s)) * int64(len(solver.Controller.Row5s)) * int64(len(solver.Controller.Row6s)) * int64(len(solver.Controller.Row7s)) * int64(len(solver.Controller.Row8s)) * int64(len(solver.Controller.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)) } @@ -62,15 +62,15 @@ func (solver *Solver) findBlocks(row *string, rows *[]int) { } func (solver *Solver) CheckCombinations() { - for rows1Index := range solver.Controller.Row1s { - for rows2Index := range solver.Controller.Row2s { - for rows3Index := range solver.Controller.Row3s { - for rows4Index := range solver.Controller.Row4s { - for rows5Index := range solver.Controller.Row5s { - for rows6Index := range solver.Controller.Row6s { - for rows7Index := range solver.Controller.Row7s { - for rows8Index := range solver.Controller.Row8s { - for rows9Index := range solver.Controller.Row9s { + 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) } } @@ -85,10 +85,10 @@ func (solver *Solver) CheckCombinations() { func (solver *Solver) validator(rows1Index int, rows2Index int, rows3Index int, rows4Index int, rows5Index int, rows6Index int, rows7Index int, rows8Index int, rows9Index int) { - solver.Controller.Counter.Add(1) + solver.counter.Add(1) - if solver.validateCombination(solver.Controller.Row1s[rows1Index], solver.Controller.Row2s[rows2Index], solver.Controller.Row3s[rows3Index], solver.Controller.Row4s[rows4Index], solver.Controller.Row5s[rows5Index], solver.Controller.Row6s[rows6Index], solver.Controller.Row7s[rows7Index], solver.Controller.Row8s[rows8Index], solver.Controller.Row9s[rows9Index]) { - solver.Controller.Solutions = append(solver.Controller.Solutions, solver.renderCombination(solver.Controller.Row1s[rows1Index], solver.Controller.Row2s[rows2Index], solver.Controller.Row3s[rows3Index], solver.Controller.Row4s[rows4Index], solver.Controller.Row5s[rows5Index], solver.Controller.Row6s[rows6Index], solver.Controller.Row7s[rows7Index], solver.Controller.Row8s[rows8Index], solver.Controller.Row9s[rows9Index])) + 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, 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])) } } @@ -121,33 +121,33 @@ func (solver *Solver) Tracker() { // While not needed for rateDiff anymore, it makes estimation calculations more accurate. ☹️ time.Sleep(time.Second) - // for solver.Controller.Iter != solver.Controller.Counter { // Start for-loop + // for solver.Iter != solver.counter { // Start for-loop for !done { // Determine how far we are. - percentage = (float32(solver.Controller.Counter.Load()) / (float32(solver.Controller.Iter) / 100)) + percentage = (float32(solver.counter.Load()) / (float32(solver.Iter) / 100)) // Reset the loop - rateDiff = solver.Controller.Counter.Load() - rateStart + 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.Controller.Iter == solver.Controller.Counter.Load() { + if solver.Iter == solver.counter.Load() { percentage = 100 - solver.Controller.Counter.Store(solver.Controller.Iter) + solver.counter.Store(solver.Iter) done = true } timer_elapsed := time.Since(timerStart) - solver.Controller.Rates = append(solver.Controller.Rates, rateDiff) + 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.Controller.Iter - solver.Controller.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 { @@ -158,7 +158,7 @@ func (solver *Solver) Tracker() { } // Printing the progress - log.Println("Processing: " + strconv.Itoa(int(percentage)) + "% (" + strconv.FormatInt(solver.Controller.Counter.Load(), 10) + "/" + strconv.Itoa(int(solver.Controller.Iter)) + "); Rate: " + strconv.FormatInt(rateDiff, 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 if percentage == 100 { @@ -177,10 +177,10 @@ func (solver *Solver) Tracker() { } // Resert the rate counter - rateStart = solver.Controller.Counter.Load() + rateStart = solver.counter.Load() // Sleep for a second - if solver.Controller.Iter != solver.Controller.Counter.Load() { + if solver.Iter != solver.counter.Load() { time.Sleep(1 * time.Second) } } // End for-loop @@ -245,11 +245,11 @@ func (solver *Solver) validateCombination(row1 int, row2 int, row3 int, row4 int func (solver *Solver) calcAVG() (avg int64) { var avgSum int64 - for _, value := range solver.Controller.Rates { + for _, value := range solver.rates { avgSum += value } - avg = avgSum / int64(len(solver.Controller.Rates)) + avg = avgSum / int64(len(solver.rates)) return } diff --git a/solver/split.go b/solver/split.go index 373f0ac..0f59bbb 100644 --- a/solver/split.go +++ b/solver/split.go @@ -11,8 +11,8 @@ import ( // and // Modify solver.row1s so it limits the workload to what is only desired. func (solver *Solver) SelectWorkload() { - if solver.Controller.Split > len(solver.Controller.Row1s) { - log.Println("ERROR: Unable to divide the workload in " + strconv.Itoa(solver.Controller.Split) + " parts, when only " + strconv.Itoa(len(solver.Controller.Row1s)) + " are available.\n\n") + 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") @@ -26,7 +26,7 @@ func (solver *Solver) SelectWorkload() { func (solver *Solver) splitWorkload() []int { agents := make([]int, solver.Controller.Split) var tracker int - var tasks int = len(solver.Controller.Row1s) + var tasks int = len(solver.row1s) for tasks != 0 { agents[tracker] += 1 @@ -54,8 +54,8 @@ func (solver *Solver) setWorkload(agents []int) { } // Set the shortened set of instructions - solver.Controller.Row1s = solver.Controller.Row1s[start:finish] + solver.row1s = solver.row1s[start:finish] // Recalculate how much we need to grind through - solver.Controller.Iter = int64(len(solver.Controller.Row1s)) * int64(len(solver.Controller.Row2s)) * int64(len(solver.Controller.Row3s)) * int64(len(solver.Controller.Row4s)) * int64(len(solver.Controller.Row5s)) * int64(len(solver.Controller.Row6s)) * int64(len(solver.Controller.Row7s)) * int64(len(solver.Controller.Row8s)) * int64(len(solver.Controller.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)) } diff --git a/solver/types.go b/solver/types.go index a793d36..46dacfa 100644 --- a/solver/types.go +++ b/solver/types.go @@ -1,39 +1,24 @@ package solver import ( + "sync/atomic" + "gitea.ligthert.net/golang/sudoku-funpark/controller" ) // Struct/Interface containing all the important variabes it functions need access to. type Solver struct { Controller *controller.Controller + row1s []int + row2s []int + row3s []int + row4s []int + row5s []int + row6s []int + row7s []int + row8s []int + row9s []int + Iter int64 + counter atomic.Int64 + rates []int64 } - -// 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 int64 -// counter atomic.Int64 -// solutions []string -// rates []int64 -// NumCPUs int -// Split int -// Part int -// }