Implement quicksort on chess board.
Note that it might be easier / cheaper to serialize and compare bytes?
This commit is contained in:
parent
f2ff9a2ee3
commit
65afb11546
|
@ -59,7 +59,11 @@ pub fn descendants(board: ChessSet) -> List<ChessSet> {
|
||||||
let singles = single_descend(board)
|
let singles = single_descend(board)
|
||||||
|
|
||||||
when singles is {
|
when singles is {
|
||||||
[] -> board |> desc_and_no |> quick_sort |> list.map(builtin.snd_pair)
|
[] ->
|
||||||
|
board
|
||||||
|
|> desc_and_no
|
||||||
|
|> quicksort(compare_chess_set)
|
||||||
|
|> list.map(fn(t) { t.2nd })
|
||||||
[_] -> singles
|
[_] -> singles
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
[]
|
||||||
|
@ -126,5 +130,70 @@ fn move_knight(board: ChessSet, direction: Direction) -> ChessSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn possible_moves(board: ChessSet) -> List<Direction> {
|
fn possible_moves(board: ChessSet) -> List<Direction> {
|
||||||
direction_list() |> list.filter(fn(direction) { can_move(board, direction) })
|
direction_list() |> list.filter(can_move(board, _))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compare_tile(a: Tile, b: Tile) -> Ordering {
|
||||||
|
if a.1st == b.1st {
|
||||||
|
int.compare(a.2nd, b.2nd)
|
||||||
|
} else {
|
||||||
|
int.compare(a.1st, b.1st)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compare_list(xs: List<Tile>, ys: List<Tile>) -> Ordering {
|
||||||
|
when xs is {
|
||||||
|
[] ->
|
||||||
|
when ys is {
|
||||||
|
[] -> Equal
|
||||||
|
_ -> Less
|
||||||
|
}
|
||||||
|
[x, ..xs] ->
|
||||||
|
when ys is {
|
||||||
|
[] -> Greater
|
||||||
|
[y, ..ys] -> {
|
||||||
|
let ord = compare_tile(x, y)
|
||||||
|
if ord == Equal {
|
||||||
|
compare_list(xs, ys)
|
||||||
|
} else {
|
||||||
|
ord
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compare_chess_set(a: (Int, ChessSet), b: (Int, ChessSet)) -> Ordering {
|
||||||
|
if a.1st != b.1st {
|
||||||
|
int.compare(a.1st, b.1st)
|
||||||
|
} else {
|
||||||
|
let ChessSet {
|
||||||
|
size: size_a,
|
||||||
|
move_number: move_a,
|
||||||
|
start: start_a,
|
||||||
|
visited: visited_a,
|
||||||
|
} = a.2nd
|
||||||
|
let ChessSet {
|
||||||
|
size: size_b,
|
||||||
|
move_number: move_b,
|
||||||
|
start: start_b,
|
||||||
|
visited: visited_b,
|
||||||
|
} = b.2nd
|
||||||
|
if size_a != size_b {
|
||||||
|
int.compare(size_a, size_b)
|
||||||
|
} else if move_a != move_b {
|
||||||
|
int.compare(move_a, move_b)
|
||||||
|
} else if start_a != start_b {
|
||||||
|
when start_a is {
|
||||||
|
Some(a) ->
|
||||||
|
when start_b is {
|
||||||
|
Some(b) -> compare_tile(a, b)
|
||||||
|
None -> Greater
|
||||||
|
}
|
||||||
|
None -> Less
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
compare_list(visited_a, visited_b)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
pub fn quick_sort(l: List<a>) -> List<a> {
|
use aiken/list
|
||||||
todo
|
|
||||||
|
pub fn quicksort(xs: List<a>, compare: fn(a, a) -> Ordering) -> List<a> {
|
||||||
|
when xs is {
|
||||||
|
[] ->
|
||||||
|
[]
|
||||||
|
[head, ..tail] -> {
|
||||||
|
let before =
|
||||||
|
tail
|
||||||
|
|> list.filter(fn(x) { compare(x, head) == Less })
|
||||||
|
|> quicksort(compare)
|
||||||
|
let after =
|
||||||
|
tail
|
||||||
|
|> list.filter(fn(x) { compare(x, head) != Less })
|
||||||
|
|> quicksort(compare)
|
||||||
|
list.concat(before, [head, ..after])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue