clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

bug/architecture-test-trim-path
puzzletea / games / sudoku / benchmark_test.go
benchmark_test.go 3.8K
1package sudoku23import (4 "fmt"5 "math/rand/v2"6 "testing"7)89func skipBenchmarkInShortMode(b *testing.B) {10 b.Helper()11 if testing.Short() {12 b.Skip("skipping benchmark in short mode")13 }14}1516func benchmarkSudokuModes() []SudokuMode {17 return []SudokuMode{18 NewMode("Beginner", "benchmark", 45),19 NewMode("Easy", "benchmark", 38),20 NewMode("Medium", "benchmark", 32),21 NewMode("Hard", "benchmark", 27),22 NewMode("Expert", "benchmark", 22),23 NewMode("Diabolical", "benchmark", 17),24 }25}2627func BenchmarkGenerateProvidedCellsByMode(b *testing.B) {28 skipBenchmarkInShortMode(b)2930 for modeIndex, mode := range benchmarkSudokuModes() {31 b.Run(mode.Title(), func(b *testing.B) {32 b.ReportAllocs()33 for i := 0; i < b.N; i++ {34 rng := rand.New(rand.NewPCG(uint64(i+1), uint64(modeIndex+10_000)))35 cells := GenerateProvidedCellsSeeded(mode, rng)36 if len(cells) < mode.ProvidedCount {37 b.Fatalf("provided count %d below target %d", len(cells), mode.ProvidedCount)38 }39 }40 })41 }42}4344func BenchmarkCountSolutionsByDifficulty(b *testing.B) {45 skipBenchmarkInShortMode(b)4647 for modeIndex, mode := range benchmarkSudokuModes() {48 b.Run(mode.Title(), func(b *testing.B) {49 rng := rand.New(rand.NewPCG(uint64(modeIndex+1), uint64(modeIndex+2)))50 cells := GenerateProvidedCellsSeeded(mode, rng)51 source := newGrid(cells)52 if got := countSolutions(&source, 2); got != 1 {53 b.Fatalf("expected unique seed puzzle for %s, got %d", mode.Title(), got)54 }5556 b.ReportAllocs()57 b.ResetTimer()5859 for i := 0; i < b.N; i++ {60 g := source61 if got := countSolutions(&g, 2); got != 1 {62 b.Fatalf("countSolutions(%s) = %d, want 1", mode.Title(), got)63 }64 }65 })66 }67}6869func BenchmarkGenerateProvidedCellsSeededStable(b *testing.B) {70 skipBenchmarkInShortMode(b)7172 mode := NewMode("Hard", "benchmark", 27)73 b.ReportAllocs()74 i := 075 for b.Loop() {76 rng := rand.New(rand.NewPCG(uint64(i+1), uint64(i+100)))77 cells := GenerateProvidedCellsSeeded(mode, rng)78 if len(cells) < mode.ProvidedCount {79 b.Fatalf("generated %d clues, want >= %d", len(cells), mode.ProvidedCount)80 }81 i++82 }83}8485func BenchmarkCountSolutionsFixedPuzzle(b *testing.B) {86 skipBenchmarkInShortMode(b)8788 mode := NewMode("Expert", "benchmark", 22)89 cells := GenerateProvidedCellsSeeded(mode, rand.New(rand.NewPCG(42, 84)))90 source := newGrid(cells)91 if got := countSolutions(&source, 2); got != 1 {92 b.Fatalf("seed puzzle not unique: %d", got)93 }9495 b.ReportAllocs()96 b.ResetTimer()97 i := 098 for b.Loop() {99 g := source100 count := countSolutions(&g, 2)101 if count != 1 {102 b.Fatalf("iteration %d: countSolutions=%d, want 1", i, count)103 }104 i++105 }106}107108func BenchmarkIsValidAllCells(b *testing.B) {109 skipBenchmarkInShortMode(b)110111 mode := NewMode("Medium", "benchmark", 32)112 cells := GenerateProvidedCellsSeeded(mode, rand.New(rand.NewPCG(7, 11)))113 g := newGrid(cells)114115 b.ReportAllocs()116 b.ResetTimer()117 for b.Loop() {118 for y := range gridSize {119 for x := range gridSize {120 val := g[y][x].v121 if val == 0 {122 val = ((x + y) % gridSize) + 1123 }124 if !isValid(&g, val, x, y) && g[y][x].v == val {125 b.Fatalf("unexpected invalid self-check at (%d,%d)", x, y)126 }127 }128 }129 }130}131132func BenchmarkCountSolutionsModesSummary(b *testing.B) {133 skipBenchmarkInShortMode(b)134135 modes := benchmarkSudokuModes()136 b.ReportAllocs()137 i := 0138 for b.Loop() {139 mode := modes[i%len(modes)]140 rng := rand.New(rand.NewPCG(uint64(i+1), uint64(i+2)))141 cells := GenerateProvidedCellsSeeded(mode, rng)142 g := newGrid(cells)143 if got := countSolutions(&g, 2); got != 1 {144 b.Fatalf("mode %s uniqueness check failed: %d", mode.Title(), got)145 }146 i++147 }148}149150func ExampleBenchmarkGenerateProvidedCellsByMode() {151 fmt.Println("run with: go test ./sudoku -run '^$' -bench BenchmarkGenerateProvidedCellsByMode -benchmem")152 // Output: run with: go test ./sudoku -run '^$' -bench BenchmarkGenerateProvidedCellsByMode -benchmem153}