summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs4
-rw-r--r--src/solver.rs9
-rw-r--r--src/solvers/intuitive.rs (renamed from src/solvers.rs)72
-rw-r--r--src/solvers/mod.rs1
-rw-r--r--src/structs.rs98
5 files changed, 120 insertions, 64 deletions
diff --git a/src/main.rs b/src/main.rs
index bb8b978..a1cdd3b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,9 @@
+mod structs;
+mod solver;
mod solvers;
fn main() {
- let mut solver = solvers::Solver::<u32>::new(8);
+ let mut solver = solvers::intuitive::NormalSolver::<u32>::new(6);
solver.solve();
//wall.output(solver.n, solver.h);
diff --git a/src/solver.rs b/src/solver.rs
new file mode 100644
index 0000000..c289cd6
--- /dev/null
+++ b/src/solver.rs
@@ -0,0 +1,9 @@
+use crate::structs::StoneWall;
+
+pub trait Solver {
+ fn new(n: u32) -> Self;
+ fn solve(&mut self) -> StoneWall;
+ fn n(&self) -> u32;
+ fn h(&self) -> u32;
+ fn w(&self) -> u32;
+}
diff --git a/src/solvers.rs b/src/solvers/intuitive.rs
index a0845a1..61ecbdf 100644
--- a/src/solvers.rs
+++ b/src/solvers/intuitive.rs
@@ -1,62 +1,8 @@
-pub struct Wall {
- heights: Vec<u32>,
-}
-
-impl Wall {
- pub fn from_heights(heights: Vec<u32>) -> Self {
- Self { heights }
- }
-
- #[allow(dead_code)]
- fn create_empty(w: u32) -> Self {
- let heights = if w == 0 {
- vec![]
- } else if w == 1 {
- vec![0]
- } else {
- let mut v = Vec::with_capacity(w as usize);
- v.push(0);
- v.push(1);
- v
- };
- Self { heights }
- }
-
- pub fn calculate_row(&self, r: u32, stones: &mut [u32]) {
- let mut len = 1;
- let mut i = 0;
- for &height in self.heights.iter().chain([r].iter()) {
- if height == r {
- stones[i] = len;
- i += 1;
- len = 0;
- }
- len += 1;
- }
- }
-
- pub fn output(&self, n: u32, h: u32) {
- let mut stones = vec![0; n as usize];
- let mut toggle = 0;
- let colors = [
- "\x1b[31m", "\x1b[32m", "\x1b[33m", "\x1b[34m", "\x1b[35m", "\x1b[36m",
- ];
- for row in 0..h {
- self.calculate_row(row, &mut stones);
- for &len in stones.iter() {
- print!("{}", colors[toggle]);
- toggle = (toggle + 1) % colors.len();
- for _ in 0..len {
- print!("◙");
- }
- }
- println!("\x1b[m");
- }
- }
-}
+use crate::solver::Solver;
+use crate::structs::GapHeights;
/// Solve for a given N and return the resulting wall
-pub struct Solver<T: num::PrimInt> {
+pub struct NormalSolver<T: num::PrimInt> {
pub n: u32,
/// calculated height [might not be correct!]
pub h: u32,
@@ -133,7 +79,7 @@ impl<T: num::PrimInt> SaveState<T> {
}
}
-impl<T: num::PrimInt> Solver<T> {
+impl<T: num::PrimInt> NormalSolver<T> {
pub fn new(n: u32) -> Self {
let h = n / 2 + 1;
let w = h * (n - 1);
@@ -195,15 +141,15 @@ impl<T: num::PrimInt> Solver<T> {
sums[sum - 1] = i as u32;
}
}
- Wall::from_heights(sums.iter().map(|x| *x as u32).collect()).output(self.w, self.h);
+ GapHeights::from_heights(sums.iter().map(|x| *x as u32).collect()).output(self.w, self.h);
true
}
#[allow(dead_code)]
- fn check_gaps(&mut self, wall: &Wall) -> bool {
- for (r, i) in wall.heights.iter().zip(1..self.w) {
- let stone = i - self.solve_stack[*r as usize].sum;
- self.solve_stack[*r as usize].set_bit(stone);
+ fn check_gaps(&mut self, wall: &GapHeights) -> bool {
+ for (i, r) in wall.iter().enumerate() {
+ let stone = (i + 1) as u32 - self.solve_stack[r as usize].sum;
+ self.solve_stack[r as usize].set_bit(stone);
}
for state in self.solve_stack.as_ref() as &[SaveState<T>] {
if state.bitmask != T::from(1 << self.n).unwrap() {
diff --git a/src/solvers/mod.rs b/src/solvers/mod.rs
new file mode 100644
index 0000000..0b1d716
--- /dev/null
+++ b/src/solvers/mod.rs
@@ -0,0 +1 @@
+pub mod intuitive;
diff --git a/src/structs.rs b/src/structs.rs
new file mode 100644
index 0000000..571c79d
--- /dev/null
+++ b/src/structs.rs
@@ -0,0 +1,98 @@
+pub struct StoneWall {
+ rows: Vec<Vec<u32>>,
+}
+
+impl StoneWall {
+ pub fn create_empty(n: u32) -> Self {
+ let n = n as usize;
+ let h = n / 2 + 1;
+ let mut rows = vec![vec![0; n]; h];
+ rows.get_mut(0).map(|r| r[0] = 1);
+ rows.get_mut(1).map(|r| r[1] = 2);
+ Self {
+ rows,
+ }
+ }
+}
+
+pub struct GapHeights {
+ heights: Vec<u32>,
+}
+
+impl GapHeights {
+ pub fn from_heights(heights: Vec<u32>) -> Self {
+ Self { heights }
+ }
+
+ #[allow(dead_code)]
+ fn create_empty(w: u32) -> Self {
+ let heights = if w == 0 {
+ vec![]
+ } else if w == 1 {
+ vec![0]
+ } else {
+ let mut v = Vec::with_capacity(w as usize);
+ v.push(0);
+ v.push(1);
+ v
+ };
+ Self { heights }
+ }
+
+ pub fn add_gap(&mut self, height: u32) {
+ self.add_gap(height)
+ }
+
+ pub fn calculate_row(&self, r: u32, stones: &mut [u32]) {
+ let mut len = 1;
+ let mut i = 0;
+ for &height in self.heights.iter().chain([r].iter()) {
+ if height == r {
+ stones[i] = len;
+ i += 1;
+ len = 0;
+ }
+ len += 1;
+ }
+ }
+
+ pub fn output(&self, n: u32, h: u32) {
+ let mut stones = vec![0; n as usize];
+ let mut toggle = 0;
+ let colors = [
+ "\x1b[31m", "\x1b[32m", "\x1b[33m", "\x1b[34m", "\x1b[35m", "\x1b[36m",
+ ];
+ for row in 0..h {
+ self.calculate_row(row, &mut stones);
+ for &len in stones.iter() {
+ print!("{}", colors[toggle]);
+ toggle = (toggle + 1) % colors.len();
+ for _ in 0..len {
+ print!("◙");
+ }
+ }
+ println!("\x1b[m");
+ }
+ }
+
+ pub fn iter<'a>(&'a self) -> GapIter<'a> {
+ GapIter {
+ gap_heights: self,
+ i: 0,
+ }
+ }
+}
+
+pub struct GapIter<'a> {
+ gap_heights: &'a GapHeights,
+ i: usize,
+}
+
+impl<'a> Iterator for GapIter<'a> {
+ type Item = u32;
+ fn next(&mut self) -> Option<Self::Item> {
+ let i = self.i;
+ self.i += 1;
+ self.gap_heights.heights.get(i).map(|&x| x)
+ }
+}