2024-12-07 19:23:45 +01:00
package solver
import (
2025-01-21 21:43:27 +01:00
"log"
2024-12-07 19:23:45 +01:00
"strconv"
2025-01-23 20:26:43 +01:00
"time"
2024-12-07 19:23:45 +01:00
)
2025-01-21 21:32:50 +01:00
func ( solver * Solver ) populate_blocks ( ) {
2025-01-23 20:26:43 +01:00
defer solver . timeTrack ( time . Now ( ) , "Populated blocks" )
log . Println ( "Populating blocks" )
2025-01-21 21:32:50 +01:00
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 )
2025-01-21 21:37:07 +01:00
// 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 ) )
2025-01-23 20:26:43 +01:00
2025-01-21 21:32:50 +01:00
}
2024-12-07 19:23:45 +01:00
func ( solver * Solver ) find_blocks ( row * string , rows * [ ] int ) {
// Declare selection
var selection [ ] int
var curr_blocks [ ] int
func_row := * row
for letter := range func_row {
if len ( selection ) == 0 {
curr_blocks = solver . blocks
} else {
curr_blocks = selection
selection = nil
}
2025-01-23 23:11:30 +01:00
for _ , block := range curr_blocks {
2024-12-07 19:23:45 +01:00
2025-01-23 23:11:30 +01:00
curr_row := strconv . Itoa ( block )
2024-12-07 19:23:45 +01:00
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 {
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 {
2024-12-08 01:28:32 +01:00
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 )
}
2024-12-07 19:23:45 +01:00
}
}
}
}
}
}
}
}
}
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 ) {
2025-01-23 20:26:43 +01:00
solver . counter = solver . counter + 1
2024-12-07 19:23:45 +01:00
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 ] ) )
}
2025-01-23 20:26:43 +01:00
}
func ( solver * Solver ) tracker ( ) {
defer solver . timeTrack ( time . Now ( ) , "Validated solutions" )
log . Println ( "Validating solutions" )
2025-01-25 17:32:11 +01:00
// Determine if the main-loop is done
var done bool
// Tracking progress in percentages
2025-01-23 20:26:43 +01:00
var percentage float32
2025-01-25 17:32:11 +01:00
// Tracking progress in validated solutions
2025-01-23 20:26:43 +01:00
var track int
2025-01-25 17:32:11 +01:00
// Tracking the rate, starting point
var rate_start int64
// Tracking the rate, difference between previous iterations
var rate_diff int64
2025-01-23 20:26:43 +01:00
// Tracking duration
var timer_start = time . Now ( )
2025-01-25 17:32:11 +01:00
// Prevent division-by-zero error when establishing `rate_diff`
2025-01-23 20:26:43 +01:00
time . Sleep ( time . Second )
2024-12-07 19:23:45 +01:00
2025-01-23 20:26:43 +01:00
// Estimation how long it will take
var est_fin string
2025-01-25 17:32:11 +01:00
// for solver.iter != solver.counter { // Start for-loop
for ! done {
2025-01-23 20:26:43 +01:00
// Determine how far we are.
2024-12-07 19:23:45 +01:00
percentage = ( float32 ( solver . counter ) / ( float32 ( solver . iter ) / 100 ) )
2025-01-25 17:32:11 +01:00
// Reset the loop
rate_diff = solver . counter - rate_start
if track <= int ( percentage ) || rate_diff == 0 { // Start if-statement
2025-01-23 20:26:43 +01:00
// Make sure something happened, making rate_start the only reliable variable
2025-01-25 17:32:11 +01:00
if rate_diff == 0 {
2025-01-23 20:26:43 +01:00
percentage = 100
solver . counter = solver . iter
2025-01-25 17:32:11 +01:00
done = true
2025-01-23 20:26:43 +01:00
}
timer_elapsed := time . Since ( timer_start )
2025-01-25 17:54:18 +01:00
solver . rates = append ( solver . rates , rate_diff )
2025-01-25 14:34:51 +01:00
rate_avg := solver . calc_avg ( )
2025-01-23 20:26:43 +01:00
2025-01-25 14:34:51 +01:00
// Estimate when this is finished
2025-01-23 20:26:43 +01:00
if rate_diff == 0 {
est_fin = "N/A"
} else {
2025-01-25 17:54:18 +01:00
est_fin = solver . secondsToHuman ( ( solver . iter - solver . counter ) / rate_avg )
2025-01-23 20:26:43 +01:00
}
2025-01-25 17:32:11 +01:00
// Printing the progress
2025-01-25 17:54:18 +01:00
log . Println ( "Processing: " + strconv . Itoa ( int ( percentage ) ) + "% (" + strconv . Itoa ( int ( solver . counter ) ) + "/" + strconv . Itoa ( int ( solver . iter ) ) + "); Rate: " + strconv . FormatInt ( rate_diff , 10 ) + "/sec for " + timer_elapsed . String ( ) + "; Time left (est.): " + est_fin )
2025-01-23 20:26:43 +01:00
2025-01-25 17:32:11 +01:00
// After we are done printing, exit this for-loop
if percentage == 100 {
break
}
2025-01-23 20:26:43 +01:00
// Wrap up the loop or break
if int ( percentage ) > track {
track = int ( percentage )
} else {
track = track + 1
}
2025-01-25 17:32:11 +01:00
timer_start = time . Now ( )
2025-01-23 20:26:43 +01:00
}
2025-01-25 17:32:11 +01:00
// Resert the rate counter
rate_start = solver . counter
2025-01-25 17:54:18 +01:00
2025-01-25 17:32:11 +01:00
// Sleep for a second
2025-01-23 20:26:43 +01:00
time . Sleep ( 1 * time . Second )
2025-01-25 17:32:11 +01:00
} // End for-loop
2024-12-07 19:23:45 +01:00
}
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
}
2025-01-25 14:34:51 +01:00
2025-01-25 17:54:18 +01:00
func ( solver * Solver ) calc_avg ( ) ( avg int64 ) {
2025-01-25 14:34:51 +01:00
var avg_sum int64
for _ , value := range solver . rates {
avg_sum += value
}
2025-01-25 17:54:18 +01:00
avg = avg_sum / int64 ( len ( solver . rates ) )
2025-01-25 14:34:51 +01:00
2025-01-25 17:54:18 +01:00
return
2025-01-25 14:34:51 +01:00
}