summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Kobert <dennis@kobert.dev>2019-12-22 13:42:31 +0100
committerDennis Kobert <dennis@kobert.dev>2019-12-22 13:42:31 +0100
commit1c46971754b4e4247b3f284466779a628f0201c2 (patch)
tree83ca835bf36a9cade34ec464982b44df309bc7b8
parenta8e1517fd1ad2fa30b9fc68d3e7b58cf9b680e1f (diff)
parentdb532edb6b63912f6cce0c5b6445b37686473069 (diff)
Merge branch 'master' of kobert:/var/repos/babel
-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.rs132
5 files changed, 154 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 e8cefb3..16baa03 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,
@@ -117,7 +63,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);
@@ -180,15 +126,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..fdc20f4
--- /dev/null
+++ b/src/structs.rs
@@ -0,0 +1,132 @@
+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 fn set_stone(&mut self, row: u32, pos: u32, stone: u32) -> Option<()> {
+ self.rows.get_mut(row as usize).and_then(|v| v.get_mut(pos as usize))
+ .map(|v| *v = stone)
+ }
+
+ pub fn output(&self) {
+ let colors = [
+ [31, 32],
+ [33, 35],
+ ];
+ for (i, row) in self.rows.iter().enumerate() {
+ for (j, &stone) in row.iter().enumerate() {
+ print!("{}", colors[i & 1][j & 1]);
+ print!("\x1b[{}m{}",
+ colors[i & 1][j & 1],
+ "◙".repeat(stone as usize));
+ }
+ println!("\x1b[m");
+ }
+ }
+}
+
+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 fn as_stone_wall(&self, n: u32) -> StoneWall {
+ let h = n/2 + 1;
+ let mut rows = Vec::with_capacity(h as usize);
+ for i in 0..h {
+ let mut row = vec![0; n as usize];
+ self.calculate_row(i, &mut row);
+ rows.push(row);
+ }
+ StoneWall {
+ rows
+ }
+ }
+}
+
+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)
+ }
+}