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)
|
||||
|
||||
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
|
||||
_ ->
|
||||
[]
|
||||
|
@ -126,5 +130,70 @@ fn move_knight(board: ChessSet, direction: Direction) -> ChessSet {
|
|||
}
|
||||
|
||||
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> {
|
||||
todo
|
||||
use aiken/list
|
||||
|
||||
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