summary refs log tree commit diff
path: root/24/src/main.rs
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@gmail.com>2020-12-23 22:02:37 -0800
committerIrene Knapp <ireneista@gmail.com>2020-12-23 22:02:37 -0800
commitbc3acb749d563a5d5db1551b40b433a900d4c154 (patch)
tree0aca888050be707a3dd690d799c5e64c3052c7bc /24/src/main.rs
parentbf4ada00a845e08e552f0521d245c23f04c47b1f (diff)
24! yay :)
Diffstat (limited to '24/src/main.rs')
-rw-r--r--24/src/main.rs214
1 files changed, 214 insertions, 0 deletions
diff --git a/24/src/main.rs b/24/src/main.rs
new file mode 100644
index 0000000..21b3568
--- /dev/null
+++ b/24/src/main.rs
@@ -0,0 +1,214 @@
+use advent_lib::prelude::*;
+
+use std::collections::BTreeSet;
+//use std::convert::TryFrom;
+
+#[derive(Clone,Copy)]
+enum Dir {
+  East,
+  West,
+  Northeast,
+  Northwest,
+  Southeast,
+  Southwest,
+}
+
+
+fn main() -> Result<()> {
+  let mut args = std::env::args();
+  if args.len() != 2 {
+    eprintln!("Usage: advent input");
+  }
+  let _ = args.next();
+  let filename = args.next().unwrap();
+
+  let input = advent_lib::read_lines_file(&filename)?;
+
+  let mut tile_flips: BTreeSet<(isize,isize)> = BTreeSet::new();
+  for line in &input {
+    let mut x: isize = 0;
+    let mut y: isize = 0;
+    let mut c_iter = line.chars();
+    loop {
+      match c_iter.next() {
+        Some('e') => {
+          let (new_x, new_y) = adjacent_cell(x, y, Dir::East);
+          x = new_x;
+          y = new_y
+          //x += 2;
+        },
+        Some('w') => {
+          let (new_x, new_y) = adjacent_cell(x, y, Dir::West);
+          x = new_x;
+          y = new_y
+          //x -= 2;
+        },
+        Some('n') => {
+          match c_iter.next() {
+            Some('e') => {
+              let (new_x, new_y) = adjacent_cell(x, y, Dir::Northeast);
+              x = new_x;
+              y = new_y
+              /*
+              if x % 2 != 0 {
+                y += 1;
+              }
+              x += 1;
+              */
+            },
+            Some('w') => {
+              let (new_x, new_y) = adjacent_cell(x, y, Dir::Northwest);
+              x = new_x;
+              y = new_y
+              /*
+              if x % 2 != 0 {
+                y += 1;
+              }
+              x -= 1;
+              */
+            },
+            _ => { },
+          }
+        },
+        Some('s') => {
+          match c_iter.next() {
+            Some('e') => {
+              let (new_x, new_y) = adjacent_cell(x, y, Dir::Southeast);
+              x = new_x;
+              y = new_y
+              /*
+              if x % 2 == 0 {
+                y -= 1;
+              }
+              x += 1;
+              */
+            },
+            Some('w') => {
+              let (new_x, new_y) = adjacent_cell(x, y, Dir::Southwest);
+              x = new_x;
+              y = new_y
+              /*
+              if x % 2 == 0 {
+                y -= 1;
+              }
+              x -= 1;
+              */
+            },
+            _ => { },
+          }
+        },
+        None => break,
+        _ => { },
+      }
+    }
+
+    if !tile_flips.contains(&(x, y)) {
+      tile_flips.insert((x, y));
+    } else {
+      tile_flips.remove(&(x, y));
+    }
+  }
+
+  println!("{}", tile_flips.len());
+
+  let mut state = tile_flips.clone();
+  for _ in 0 .. 100 {
+    state = iterate(state);
+  }
+
+  println!("{}", state.len());
+
+  Ok(())
+}
+
+
+fn iterate(input_state: BTreeSet<(isize, isize)>) -> BTreeSet<(isize, isize)> {
+  let mut min_x = 0;
+  let mut min_y = 0;
+  let mut max_x = 0;
+  let mut max_y = 0;
+
+  for (x, y) in &input_state {
+    if *x > max_x {
+      max_x = *x;
+    }
+    if *x < min_x {
+      min_x = *x;
+    }
+    if *y > max_y {
+      max_y = *y;
+    }
+    if *y < min_y {
+      min_y = *y;
+    }
+  }
+
+  max_x += 2;
+  min_x -= 2;
+  max_y += 1;
+  min_y -= 1;
+
+  let mut output_state: BTreeSet<(isize,isize)> = BTreeSet::new();
+
+  for y in min_y .. max_y + 1 {
+    for x in min_x .. max_x + 1 {
+      let mut adjacent_count = 0;
+      for direction in &[Dir::East, Dir::West, Dir::Northeast, Dir::Northwest,
+                         Dir::Southeast, Dir::Southwest]
+      {
+        let adjacent_coordinates = adjacent_cell(x, y, *direction);
+        if input_state.contains(&adjacent_coordinates) {
+          adjacent_count += 1;
+        }
+      }
+
+      if input_state.contains(&(x, y)) {
+        if adjacent_count >= 1 && adjacent_count <= 2 {
+          output_state.insert((x, y));
+        }
+      } else {
+        if adjacent_count == 2 {
+          output_state.insert((x, y));
+        }
+      }
+    }
+  }
+
+  output_state
+}
+
+
+fn adjacent_cell(x: isize, y: isize, direction: Dir) -> (isize, isize) {
+  match direction {
+    Dir::East => (x + 2, y),
+    Dir::West => (x - 2, y),
+    Dir::Northeast => {
+      if x % 2 != 0 {
+        (x + 1, y + 1)
+      } else {
+        (x + 1, y)
+      }
+    },
+    Dir::Northwest => {
+      if x % 2 != 0 {
+        (x - 1, y + 1)
+      } else {
+        (x - 1, y)
+      }
+    },
+    Dir::Southeast => {
+      if x % 2 == 0 {
+        (x + 1, y - 1)
+      } else {
+        (x + 1, y)
+      }
+    },
+    Dir::Southwest => {
+      if x % 2 == 0 {
+        (x - 1, y - 1)
+      } else {
+        (x - 1, y)
+      }
+    },
+  }
+}