aiken/examples/benchmarks/lib/benchmarks/knights/benchmark.ak

497 lines
8.9 KiB
Plaintext

use aiken/list
use benchmarks/knights/heuristic.{descendants, start_tour, tour_finished}
use benchmarks/knights/queue.{Queue}
use benchmarks/knights/types.{ChessSet, Solution}
// ------------------------------------------------------------------ Benchmarks
test bench_knights_100_4x4() {
run_knights(100, 4) == []
}
test bench_knights_100_6x6() {
run_knights(100, 6) == solution_100_6x6()
}
test bench_knights_100_8x8() {
run_knights(100, 8) == solution_100_8x8()
}
// ----------------------------------------------------------------------- Setup
fn run_knights(depth: Int, board_size: Int) -> Solution {
depth_search(depth, root(board_size), grow, done) |> queue.to_list
}
fn depth_search(
depth: Int,
xs: Queue<a>,
grow: fn(a) -> List<a>,
done: fn(a) -> Bool,
) -> Queue<a> {
if depth == 0 || queue.is_empty(xs) {
queue.new()
} else if done(queue.head(xs)) {
depth_search(depth - 1, queue.remove_front(xs), grow, done)
|> queue.append_front(queue.head(xs))
} else {
queue.append_all_front(queue.remove_front(xs), grow(queue.head(xs)))
|> depth_search(depth - 1, _, grow, done)
}
}
fn root(size: Int) -> Queue<(Int, ChessSet)> {
queue.append_all_front(queue.new(), mk_starts(size))
}
fn mk_starts(size: Int) -> List<(Int, ChessSet)> {
let it = interval(1, size)
let l =
list.flat_map(
it,
fn(x) { list.map(it, fn(y) { start_tour((x, y), size) }) },
)
let length = list.length(l)
expect length == size * size
list.zip(list.repeat(1 - length, length), l)
}
fn interval(a: Int, b: Int) -> List<Int> {
if a > b {
[]
} else {
[a, ..interval(a + 1, b)]
}
}
fn grow(item: (Int, ChessSet)) -> List<(Int, ChessSet)> {
let (x, y) = item
descendants(y) |> list.map(fn(list_item) { (x + 1, list_item) })
}
fn done(item: (Int, ChessSet)) -> Bool {
tour_finished(item.2nd)
}
// ------------------------------------------------------------------ Fixtures
fn solution_100_6x6() -> Solution {
[
(
0,
ChessSet {
size: 6,
move_number: 36,
start: Some((1, 1)),
visited: [
(3, 2),
(5, 3),
(6, 1),
(4, 2),
(3, 4),
(2, 6),
(4, 5),
(6, 6),
(5, 4),
(6, 2),
(4, 1),
(2, 2),
(1, 4),
(3, 3),
(2, 1),
(1, 3),
(2, 5),
(4, 6),
(6, 5),
(4, 4),
(5, 2),
(6, 4),
(5, 6),
(3, 5),
(1, 6),
(2, 4),
(1, 2),
(3, 1),
(4, 3),
(5, 1),
(6, 3),
(5, 5),
(3, 6),
(1, 5),
(2, 3),
(1, 1),
],
},
),
(
0,
ChessSet {
size: 6,
move_number: 36,
start: Some((1, 1)),
visited: [
(3, 2),
(5, 3),
(6, 1),
(4, 2),
(3, 4),
(2, 2),
(4, 1),
(6, 2),
(5, 4),
(6, 6),
(4, 5),
(2, 6),
(1, 4),
(3, 3),
(2, 1),
(1, 3),
(2, 5),
(4, 6),
(6, 5),
(4, 4),
(5, 2),
(6, 4),
(5, 6),
(3, 5),
(1, 6),
(2, 4),
(1, 2),
(3, 1),
(4, 3),
(5, 1),
(6, 3),
(5, 5),
(3, 6),
(1, 5),
(2, 3),
(1, 1),
],
},
),
(
0,
ChessSet {
size: 6,
move_number: 36,
start: Some((1, 1)),
visited: [
(3, 2),
(5, 3),
(6, 1),
(4, 2),
(3, 4),
(2, 2),
(1, 4),
(2, 6),
(4, 5),
(6, 6),
(5, 4),
(6, 2),
(4, 1),
(3, 3),
(2, 1),
(1, 3),
(2, 5),
(4, 6),
(6, 5),
(4, 4),
(5, 2),
(6, 4),
(5, 6),
(3, 5),
(1, 6),
(2, 4),
(1, 2),
(3, 1),
(4, 3),
(5, 1),
(6, 3),
(5, 5),
(3, 6),
(1, 5),
(2, 3),
(1, 1),
],
},
),
(
0,
ChessSet {
size: 6,
move_number: 36,
start: Some((1, 1)),
visited: [
(3, 2),
(5, 3),
(6, 1),
(4, 2),
(3, 4),
(2, 6),
(1, 4),
(2, 2),
(4, 1),
(6, 2),
(5, 4),
(6, 6),
(4, 5),
(3, 3),
(2, 1),
(1, 3),
(2, 5),
(4, 6),
(6, 5),
(4, 4),
(5, 2),
(6, 4),
(5, 6),
(3, 5),
(1, 6),
(2, 4),
(1, 2),
(3, 1),
(4, 3),
(5, 1),
(6, 3),
(5, 5),
(3, 6),
(1, 5),
(2, 3),
(1, 1),
],
},
),
]
}
fn solution_100_8x8() -> Solution {
[
(
0,
ChessSet {
size: 8,
move_number: 64,
start: Some((1, 1)),
visited: [
(3, 2),
(4, 4),
(5, 6),
(6, 4),
(8, 5),
(7, 7),
(6, 5),
(8, 4),
(7, 2),
(5, 3),
(3, 4),
(4, 6),
(5, 8),
(6, 6),
(4, 5),
(3, 7),
(1, 8),
(2, 6),
(4, 7),
(5, 5),
(6, 3),
(5, 1),
(4, 3),
(3, 5),
(5, 4),
(7, 3),
(8, 1),
(6, 2),
(4, 1),
(2, 2),
(1, 4),
(3, 3),
(2, 5),
(1, 3),
(2, 1),
(4, 2),
(6, 1),
(8, 2),
(7, 4),
(8, 6),
(7, 8),
(5, 7),
(3, 8),
(1, 7),
(3, 6),
(2, 8),
(1, 6),
(2, 4),
(1, 2),
(3, 1),
(5, 2),
(7, 1),
(8, 3),
(7, 5),
(8, 7),
(6, 8),
(7, 6),
(8, 8),
(6, 7),
(4, 8),
(2, 7),
(1, 5),
(2, 3),
(1, 1),
],
},
),
(
0,
ChessSet {
size: 8,
move_number: 64,
start: Some((1, 1)),
visited: [
(3, 2),
(4, 4),
(5, 6),
(7, 7),
(8, 5),
(6, 4),
(7, 2),
(8, 4),
(6, 5),
(5, 3),
(3, 4),
(4, 6),
(5, 8),
(6, 6),
(4, 5),
(3, 7),
(1, 8),
(2, 6),
(4, 7),
(5, 5),
(6, 3),
(5, 1),
(4, 3),
(3, 5),
(5, 4),
(7, 3),
(8, 1),
(6, 2),
(4, 1),
(2, 2),
(1, 4),
(3, 3),
(2, 5),
(1, 3),
(2, 1),
(4, 2),
(6, 1),
(8, 2),
(7, 4),
(8, 6),
(7, 8),
(5, 7),
(3, 8),
(1, 7),
(3, 6),
(2, 8),
(1, 6),
(2, 4),
(1, 2),
(3, 1),
(5, 2),
(7, 1),
(8, 3),
(7, 5),
(8, 7),
(6, 8),
(7, 6),
(8, 8),
(6, 7),
(4, 8),
(2, 7),
(1, 5),
(2, 3),
(1, 1),
],
},
),
(
0,
ChessSet {
size: 8,
move_number: 64,
start: Some((1, 1)),
visited: [
(3, 2),
(4, 4),
(6, 5),
(8, 4),
(7, 2),
(5, 3),
(3, 4),
(4, 6),
(5, 8),
(7, 7),
(5, 6),
(6, 4),
(8, 5),
(6, 6),
(4, 5),
(3, 7),
(1, 8),
(2, 6),
(4, 7),
(5, 5),
(6, 3),
(5, 1),
(4, 3),
(3, 5),
(5, 4),
(7, 3),
(8, 1),
(6, 2),
(4, 1),
(2, 2),
(1, 4),
(3, 3),
(2, 5),
(1, 3),
(2, 1),
(4, 2),
(6, 1),
(8, 2),
(7, 4),
(8, 6),
(7, 8),
(5, 7),
(3, 8),
(1, 7),
(3, 6),
(2, 8),
(1, 6),
(2, 4),
(1, 2),
(3, 1),
(5, 2),
(7, 1),
(8, 3),
(7, 5),
(8, 7),
(6, 8),
(7, 6),
(8, 8),
(6, 7),
(4, 8),
(2, 7),
(1, 5),
(2, 3),
(1, 1),
],
},
),
]
}