github.com/thomasjungblut/go-dancing-links@v0.0.0-20210606150257-22b8f71a45a8/benchmark/benchmark_sudoku_euler96_test.go (about)

     1  package benchmark
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/stretchr/testify/assert"
     6  	"github.com/thomasjungblut/go-dancing-links/sudoku"
     7  	"io/ioutil"
     8  	"os"
     9  	"strings"
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  func BenchmarkSolvingLongestTakingEulerPuzzle(t *testing.B) {
    16  	eulerBoards, err := readAllEulerBoards()
    17  	assert.Nil(t, err)
    18  
    19  	// only run the one board that takes so long
    20  	theBoard := eulerBoards[46]
    21  	for i := 0; i < t.N; i++ {
    22  		start := time.Now()
    23  		board, err := theBoard.FindSingleSolution()
    24  		assert.Nil(t, err)
    25  		elapsed := time.Since(start)
    26  		fmt.Println(fmt.Sprintf("solving the board took %s", elapsed))
    27  		assert.Nil(t, board.VerifyCorrectness())
    28  		_ = board.Print(os.Stdout)
    29  	}
    30  }
    31  
    32  func BenchmarkSolvingAllEulerPuzzlesHappyPath(t *testing.B) {
    33  	eulerBoards, err := readAllEulerBoards()
    34  	assert.Nil(t, err)
    35  
    36  	wg := sync.WaitGroup{}
    37  	wg.Add(len(eulerBoards))
    38  
    39  	for i := range eulerBoards {
    40  		go func(i int, boardI sudoku.SudokuBoardI) {
    41  			defer wg.Done()
    42  			start := time.Now()
    43  			boardResult, err := boardI.FindSingleSolution()
    44  			elapsed := time.Since(start)
    45  			assert.Nil(t, err)
    46  			fmt.Println(fmt.Sprintf("solving board %d took %s", i, elapsed))
    47  			assert.Nil(t, boardResult.VerifyCorrectness())
    48  		}(i, eulerBoards[i])
    49  	}
    50  
    51  	wg.Wait()
    52  }
    53  
    54  func readAllEulerBoards() ([]sudoku.SudokuBoardI, error) {
    55  	txt, err := ioutil.ReadFile("p096_sudoku.txt")
    56  	if err != nil {
    57  		return nil, err
    58  	}
    59  
    60  	var boards []sudoku.SudokuBoardI
    61  	// bit of a hacky parser, but does the job pretty well
    62  	for _, grid := range strings.Split(string(txt), "Grid") {
    63  		if len(grid) == 0 {
    64  			continue
    65  		}
    66  		board := sudoku.NewSudokuBoard(9)
    67  		err = board.ReadEulerTextFormat(grid)
    68  		if err != nil {
    69  			return nil, err
    70  		}
    71  		boards = append(boards, board)
    72  	}
    73  
    74  	return boards, nil
    75  }