···11+# This file is automatically @generated by Cargo.
22+# It is not intended for manual editing.
33+version = 4
44+55+[[package]]
66+name = "day7"
77+version = "0.1.0"
···11+use std::fmt::Debug;
22+use std::fs;
33+44+struct TachyonManifold {
55+ data: Vec<Vec<char>>,
66+ height: usize,
77+ width: usize,
88+}
99+1010+struct TachyonBeam {
1111+ start_row: usize,
1212+ start_col: usize,
1313+ end_row: usize,
1414+}
1515+1616+impl TachyonManifold {
1717+ fn new(input: String) -> Self {
1818+ let data: Vec<Vec<char>> = input.lines().map(|line| line.chars().collect()).collect();
1919+ let height = data.len();
2020+ let width = data[0].len();
2121+ Self {
2222+ data,
2323+ height,
2424+ width,
2525+ }
2626+ }
2727+2828+ fn propagate_beam(&mut self, row: usize) -> u32 {
2929+ let mut split_count = 0u32;
3030+ let row_data = self.data[row].clone();
3131+3232+ // THIS ANNOYINGLY CONTAINS AN IMMUTABLE BORROW for self.data[row]
3333+ // SO IT BREAKS ALL MY MUTABLE REFERENCES.
3434+ // THIS IS WHY THERE IS ALL THE CLONE()ING
3535+ for (index, c) in row_data.iter().enumerate() {
3636+ match c {
3737+ 'S' | '|' => {
3838+ if self.data[row + 1][index] == '.' {
3939+ self.data[row + 1][index] = '|'
4040+ }
4141+ }
4242+ '^' => {
4343+ if self.data[row.saturating_sub(1)][index] == '|' {
4444+ self.data[row][index + 1] = '|';
4545+ self.data[row][index.saturating_sub(1)] = '|';
4646+ split_count += 1;
4747+ }
4848+ }
4949+ _ => continue,
5050+ }
5151+ }
5252+5353+ // ANNOYINGLY HAVE TO RE-CLONE DATA BC CANT FIGURE OUT HOW TO EDIT IN PLACE
5454+ let row_data = self.data[row].clone();
5555+5656+ for (index, c) in row_data.iter().enumerate() {
5757+ match c {
5858+ '|' => {
5959+ if self.data[row + 1][index] == '.' {
6060+ self.data[row + 1][index] = '|'
6161+ }
6262+ }
6363+ _ => continue,
6464+ }
6565+ }
6666+ split_count
6767+ }
6868+6969+ fn quantum_propagate(&mut self, row: usize) -> u32 {
7070+ let mut split_count = 0u32;
7171+ let row_data = self.data[row].clone();
7272+7373+ for (index, c) in row_data.iter().enumerate() {
7474+ match c {
7575+ '|' => {
7676+ if self.data[row + 1][index] == '.' {
7777+ self.data[row + 1][index] = '|'
7878+ }
7979+ }
8080+ _ => continue,
8181+ }
8282+ }
8383+ split_count
8484+ }
8585+}
8686+8787+// Quantum propagation thoughts
8888+// looks like a tree structure
8989+// every time we find a split, could push a new Tachyon Manifold onto the stack
9090+// --- Wait okay its one beam
9191+// so really we just need to store a stack of L/R decisions that represent
9292+// a map of outcomes
9393+// problem is... how do we distinguish whether tachyons path was unique?
9494+// save every path taken as a a string & convert to a set?
9595+// or are they just guaranteed unique structurally
9696+9797+impl Debug for TachyonManifold {
9898+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9999+ writeln!(
100100+ f,
101101+ "TachyonManifold of size {}, {} {{",
102102+ self.width, self.height
103103+ )?;
104104+ for row in &self.data {
105105+ for &cell in row {
106106+ write!(f, "{}", cell)?;
107107+ }
108108+ writeln!(f)?;
109109+ }
110110+ writeln!(f, "}}")?;
111111+ Ok(())
112112+ }
113113+}
114114+115115+fn main() {
116116+ let mut manifold = TachyonManifold::new(fs::read_to_string("input.txt").unwrap());
117117+118118+ let mut splits = 0u32;
119119+ for row in 0..manifold.height - 1 {
120120+ splits += manifold.propagate_beam(row);
121121+ println!("{:?}", manifold);
122122+ }
123123+124124+ // Weird observation: for the small example provided
125125+ // answer for total number of paths == the number of beams
126126+ let beam_count = manifold.data[2..]
127127+ .iter()
128128+ .map(|row| row.iter().filter(|&cell| *cell == '|').count())
129129+ .sum::<usize>();
130130+131131+ println!("Beam split {} times.", splits);
132132+ println!("Total possible paths: {}", beam_count / 2);
133133+}