shark/fish/src/eval.rs

227 lines
5.1 KiB
Rust

use mino::matrix::{COLUMNS, EMPTY_ROW, FULL_ROW};
use mino::Mat;
mod downstacking;
pub use downstacking::mystery_mdse;
pub fn evaluate(mat: &Mat, pcnt: usize) -> i32 {
// TODO: public interface for weights etc.
struct Weights {
height: i32,
i_deps: i32,
mdse: i32,
pcnt: i32,
}
const W: Weights = Weights {
height: 5,
i_deps: 10,
mdse: 10,
pcnt: 10,
};
let mut rating = 0;
rating += max_height(mat) * W.height;
rating += i_deps(mat) * W.i_deps;
rating += mystery_mdse(mat) * W.mdse;
rating += (pcnt as i32) * W.pcnt;
rating
}
pub fn max_height(matrix: &Mat) -> i32 {
matrix.rows() as i32
}
pub fn i_deps(matrix: &Mat) -> i32 {
let mut depth = [0u8; COLUMNS as usize];
let mut count = 0;
for y in 0..matrix.rows() {
// 012345689xxxx
// ↑
// _______xxx___
let mut mask = 0b111 << (COLUMNS - 2);
// _______x.x___
let mut test = 0b101 << (COLUMNS - 2);
for x in (0..COLUMNS).rev() {
if matrix.test_row(y, mask, test) {
depth[x as usize] += 1;
depth[x as usize] %= 4;
if depth[x as usize] == 3 {
count += 1;
}
} else {
depth[x as usize] = 0;
}
mask >>= 1;
test >>= 1;
}
}
count
}
pub fn row_trans(matrix: &Mat) -> i32 {
let mut prev_row = FULL_ROW;
let mut count = 0;
for &curr_row in &matrix[..] {
count += (curr_row ^ prev_row).count_ones();
prev_row = curr_row;
}
count += (prev_row ^ EMPTY_ROW).count_ones();
count as i32
}
#[cfg(test)]
mod test {
use super::*;
use mino::mat;
#[test]
fn test_i_deps() {
assert_eq!(i_deps(Mat::EMPTY), 0);
assert_eq!(
i_deps(mat! {
"xxxxx...xx";
"xxxxx..xxx";
"xxxxx.xx.x";
"xxxxx.xxxx";
}),
0
);
assert_eq!(
i_deps(mat! {
"xxx.....xx";
"xxxx..xxxx";
"xxxxx.xxxx";
"x.xxx.xxxx";
}),
0
);
assert_eq!(
i_deps(mat! {
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
}),
1
);
assert_eq!(
i_deps(mat! {
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
}),
1
);
assert_eq!(
i_deps(mat! {
"xxxxxxxx.x";
"xxxxxxxx.x";
"xxxxxxxx.x";
"xxxxxxxx.x";
"x.xxxxxxxx";
"x.xxxxxxxx";
"x.xxxxxxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
}),
3,
);
assert_eq!(
i_deps(mat! {
// 6 rows
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
}),
1
);
assert_eq!(
i_deps(mat! {
// 7 rows
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
}),
2
);
assert_eq!(
i_deps(mat! {
"x.x......x";
"x.xxx.xxxx";
"x.xxx.xxxx";
"x.xxx.xxxx";
}),
2
);
}
#[test]
fn test_row_trans() {
assert_eq!(row_trans(Mat::EMPTY), 10);
assert_eq!(
row_trans(mat! {
"x.........";
"xx........";
"xxx.......";
"xxxx......";
"xxxxx.....";
"xxxxxx....";
"xxxxxxx...";
"xxxxxxxx..";
"xxxxxxxxx.";
"xxxxxxxxxx";
}),
10,
);
assert_eq!(
row_trans(mat! {
"xxxxx.xxxx";
}),
9 + 1,
);
assert_eq!(
row_trans(mat! {
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
"xxxxx.xxxx";
}),
9 + 1,
);
assert_eq!(
row_trans(mat! {
"xxxxx.xxxx";
"xxxx.Xxxxx";
}),
9 + 2 + 1
);
assert_eq!(
row_trans(mat! {
"xxxxx.xxx.";
"xx....xxxx";
}),
8 + 4 + 4
);
assert_eq!(
row_trans(mat! {
"xxxx..xxxx";
"xxxx...xxx";
"xxxxx.xxxx";
}),
8 + 1 + 2 + 1,
);
}
}