Powered by AppSignal & Oban Pro

Sudoku (benchmarks)

livebooks/sudoku_benchmarks.livemd

Sudoku (benchmarks)

Mix.install([
  {:fixpoint, path: Path.join(System.get_env("HOME"), "projects/cpsolver")}
])

Logger.configure(level: :notice)

Section

IEx.Helpers.c(Path.join([System.get_env("HOME"), 
  "projects", "cpsolver",
  "scripts/sudoku_benchmark.exs"]))
require Logger
alias CPSolver.Examples.Sudoku
alias CPSolver.Constraint.AllDifferent.{DC, BC, FWC, DC.Fast}

puzzle_file = 
  
#"data/sudoku/clue17"
#"data/sudoku/top95"
"data/sudoku/hardest"
#"data/sudoku/puzzles5_forum_hardest_1905_11+"
#"data/sudoku/quasi_uniform_834"
num_instances = 100_000
num_threads = 8
alldiff_impl = Fast

{elapsed_times, success_count, failure_count, incorrect_count} =
  SudokuBenchmark.run(
    Path.join([System.get_env("HOME"), 
  "projects", "cpsolver",
    puzzle_file]), num_instances, num_threads, 30_000, alldiff_impl)
  |> Enum.with_index()
  |> Enum.reduce({[], 0, 0, 0}, fn {s, problem_num}, {elapsed_acc, succ_acc, fail_acc, wrong_acc} ->
    elapsed_acc = [s.statistics.elapsed_time | elapsed_acc]
    s.solutions
    |> List.first()
    |> then(fn sol ->
      if sol do
        if Sudoku.check_solution(sol) do
          #Logger.notice("OK") 
          {elapsed_acc, succ_acc + 1, fail_acc, wrong_acc}
        else
          Logger.error("Wrong solution for #{problem_num} ! #{sol}")
           {elapsed_acc, succ_acc, fail_acc, wrong_acc + 1}
        end 
      else
        Logger.error("No solution for #{problem_num}")
        {elapsed_acc, succ_acc, fail_acc + 1, wrong_acc}
      end
    end)
  end)
  #|> Enum.sort()
res = %{elapsed: elapsed_times, success: success_count, no_solution: failure_count, incorrect: incorrect_count} 

res = Map.merge(res, 
%{
  source: puzzle_file,
  shortest: Enum.min(res.elapsed), 
  longest: Enum.max(res.elapsed), 
  average: Enum.sum(res.elapsed) / length(res.elapsed), 
  total: Enum.sum(res.elapsed),
  elapsed: Enum.sort(res.elapsed)
})