adventofcode

git clone https://git.ce9e.org/adventofcode.git

commit
cd8a82ea8ff2eb25f47f5a5a33584ba6595a579b
parent
18f5919f86025a58624a35f4bd5e7a8729e5b317
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-12-14 09:33
refactor

Diffstat

M 2023/14/solution.rs 111 ++++++++++++++++++-------------------------------------------

1 files changed, 33 insertions, 78 deletions


diff --git a/2023/14/solution.rs b/2023/14/solution.rs

@@ -1,6 +1,7 @@
    1     1 #[path = "../lib.rs"]
    2     2 mod lib;
    3     3 
   -1     4 #[derive(Clone)]
    4     5 enum Cell {
    5     6     Square,
    6     7     Round,
@@ -22,69 +23,23 @@ fn parse_input() -> Vec<Vec<Cell>> {
   22    23         .collect();
   23    24 }
   24    25 
   25    -1 fn tilt_north(rows: &mut Vec<Vec<Cell>>) {
   26    -1     for x in 0..rows[0].len() {
   -1    26 fn tilt<F: Fn(usize, usize) -> (usize, usize)>(
   -1    27     rows: &mut Vec<Vec<Cell>>,
   -1    28     width: usize,
   -1    29     height: usize,
   -1    30     coords: F,
   -1    31 ) {
   -1    32     for a in 0..width {
   27    33         let mut next = 0;
   28    -1         for y in 0..rows.len() {
   -1    34         for b in 0..height {
   -1    35             let (x, y) = coords(a, b);
   29    36             match rows[y][x] {
   30    37                 Cell::Empty => {}
   31    -1                 Cell::Square => next = y + 1,
   -1    38                 Cell::Square => next = b + 1,
   32    39                 Cell::Round => {
   33    40                     rows[y][x] = Cell::Empty;
   34    -1                     rows[next][x] = Cell::Round;
   35    -1                     next += 1;
   36    -1                 }
   37    -1             }
   38    -1         }
   39    -1     }
   40    -1 }
   41    -1 
   42    -1 fn tilt_south(rows: &mut Vec<Vec<Cell>>) {
   43    -1     let last = rows.len() - 1;
   44    -1     for x in 0..rows[0].len() {
   45    -1         let mut next = 0;
   46    -1         for y in 0..rows.len() {
   47    -1             match rows[last - y][x] {
   48    -1                 Cell::Empty => {}
   49    -1                 Cell::Square => next = y + 1,
   50    -1                 Cell::Round => {
   51    -1                     rows[last - y][x] = Cell::Empty;
   52    -1                     rows[last - next][x] = Cell::Round;
   53    -1                     next += 1;
   54    -1                 }
   55    -1             }
   56    -1         }
   57    -1     }
   58    -1 }
   59    -1 
   60    -1 fn tilt_west(rows: &mut Vec<Vec<Cell>>) {
   61    -1     for y in 0..rows.len() {
   62    -1         let mut next = 0;
   63    -1         for x in 0..rows[0].len() {
   64    -1             match rows[y][x] {
   65    -1                 Cell::Empty => {}
   66    -1                 Cell::Square => next = x + 1,
   67    -1                 Cell::Round => {
   68    -1                     rows[y][x] = Cell::Empty;
   69    -1                     rows[y][next] = Cell::Round;
   70    -1                     next += 1;
   71    -1                 }
   72    -1             }
   73    -1         }
   74    -1     }
   75    -1 }
   76    -1 
   77    -1 fn tilt_east(rows: &mut Vec<Vec<Cell>>) {
   78    -1     let last = rows[0].len() - 1;
   79    -1     for y in 0..rows.len() {
   80    -1         let mut next = 0;
   81    -1         for x in 0..rows[0].len() {
   82    -1             match rows[y][last - x] {
   83    -1                 Cell::Empty => {}
   84    -1                 Cell::Square => next = x + 1,
   85    -1                 Cell::Round => {
   86    -1                     rows[y][last - x] = Cell::Empty;
   87    -1                     rows[y][last - next] = Cell::Round;
   -1    41                     let (nx, ny) = coords(a, next);
   -1    42                     rows[ny][nx] = Cell::Round;
   88    43                     next += 1;
   89    44                 }
   90    45             }
@@ -93,10 +48,12 @@ fn tilt_east(rows: &mut Vec<Vec<Cell>>) {
   93    48 }
   94    49 
   95    50 fn cycle(rows: &mut Vec<Vec<Cell>>) {
   96    -1     tilt_north(rows);
   97    -1     tilt_west(rows);
   98    -1     tilt_south(rows);
   99    -1     tilt_east(rows);
   -1    51     let width = rows[0].len();
   -1    52     let height = rows.len();
   -1    53     tilt(rows, width, height, |a, b| (a, b));
   -1    54     tilt(rows, height, width, |a, b| (b, a));
   -1    55     tilt(rows, width, height, |a, b| (a, height - 1 - b));
   -1    56     tilt(rows, height, width, |a, b| (width - 1 - b, a));
  100    57 }
  101    58 
  102    59 fn hash(rows: &Vec<Vec<Cell>>) -> Vec<(usize, usize)> {
@@ -125,21 +82,19 @@ fn weigh(rows: &Vec<Vec<Cell>>) -> usize {
  125    82     return sum;
  126    83 }
  127    84 
  128    -1 fn part1() {
  129    -1     let mut rows = parse_input();
  130    -1     tilt_north(&mut rows);
  131    -1     let weight = weigh(&rows);
  132    -1     println!("part1: {}", weight);
   -1    85 fn part1(rows: &mut Vec<Vec<Cell>>) -> usize {
   -1    86     let width = rows[0].len();
   -1    87     let height = rows.len();
   -1    88     tilt(rows, width, height, |a, b| (a, b));
   -1    89     return weigh(rows);
  133    90 }
  134    91 
  135    -1 fn part2() {
  136    -1     let mut rows = parse_input();
  137    -1 
   -1    92 fn part2(rows: &mut Vec<Vec<Cell>>) -> usize {
  138    93     let period;
  139    94     let mut history = vec![];
  140    95     history.push(hash(&rows));
  141    96     loop {
  142    -1         cycle(&mut rows);
   -1    97         cycle(rows);
  143    98         let hash = hash(&rows);
  144    99         if let Some(i) = history.iter().position(|h| *h == hash) {
  145   100             period = history.len() - i;
@@ -148,16 +103,16 @@ fn part2() {
  148   103             history.push(hash);
  149   104         }
  150   105     }
  151    -1 
  152   106     for _ in 0..((1_000_000_000 - history.len()) % period) {
  153    -1         cycle(&mut rows);
   -1   107         cycle(rows);
  154   108     }
  155    -1 
  156    -1     let weight = weigh(&rows);
  157    -1     println!("part2: {}", weight);
   -1   109     return weigh(rows);
  158   110 }
  159   111 
  160   112 fn main() {
  161    -1     part1();
  162    -1     part2();
   -1   113     let mut rows1 = parse_input();
   -1   114     let mut rows2 = rows1.clone();
   -1   115 
   -1   116     println!("part1: {}", part1(&mut rows1));
   -1   117     println!("part2: {}", part2(&mut rows2));
  163   118 }