adventofcode

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

commit
74af053a50c6371925e64936aca414ee72a46e3a
parent
7a306ce03f2797d2085e4b3df0b2d7c51c18c9d8
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2023-12-18 14:07
refactor

Diffstat

M 2023/16/solution.rs 105 +++++++++++++++++++++++++++++--------------------------------

1 files changed, 50 insertions, 55 deletions


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

@@ -9,10 +9,13 @@ enum Cell {
    9     9     MirrorRight,
   10    10 }
   11    11 
   12    -1 const RIGHT: u8 = 1;
   13    -1 const LEFT: u8 = 2;
   14    -1 const UP: u8 = 4;
   15    -1 const DOWN: u8 = 8;
   -1    12 #[derive(Copy, Clone)]
   -1    13 enum Dir {
   -1    14     Right = 1,
   -1    15     Left = 2,
   -1    16     Up = 4,
   -1    17     Down = 8,
   -1    18 }
   16    19 
   17    20 fn parse_input() -> Vec<Vec<Cell>> {
   18    21     return lib::iter_input()
@@ -32,94 +35,86 @@ fn parse_input() -> Vec<Vec<Cell>> {
   32    35         .collect();
   33    36 }
   34    37 
   35    -1 fn push(map: &Vec<Vec<Cell>>, queue: &mut Vec<(usize, usize, u8)>, x: usize, y: usize, dir: u8) {
   -1    38 fn push(map: &Vec<Vec<Cell>>, queue: &mut Vec<(usize, usize, Dir)>, x: usize, y: usize, dir: Dir) {
   36    39     match dir {
   37    -1         LEFT => {
   -1    40         Dir::Left => {
   38    41             if x > 0 {
   39    42                 queue.push((x - 1, y, dir));
   40    43             }
   41    -1         },
   42    -1         RIGHT => {
   -1    44         }
   -1    45         Dir::Right => {
   43    46             if x + 1 < map[0].len() {
   44    47                 queue.push((x + 1, y, dir));
   45    48             }
   46    -1         },
   47    -1         UP => {
   -1    49         }
   -1    50         Dir::Up => {
   48    51             if y > 0 {
   49    52                 queue.push((x, y - 1, dir));
   50    53             }
   51    -1         },
   52    -1         DOWN => {
   -1    54         }
   -1    55         Dir::Down => {
   53    56             if y + 1 < map.len() {
   54    57                 queue.push((x, y + 1, dir));
   55    58             }
   56    -1         },
   57    -1         _ => unreachable!(),
   58    -1     }
   -1    59         }
   -1    60     };
   59    61 }
   60    62 
   61    -1 fn count(map: &Vec<Vec<Cell>>, start: (usize, usize, u8)) -> usize {
   -1    63 fn count(map: &Vec<Vec<Cell>>, start: (usize, usize, Dir)) -> usize {
   62    64     let mut visited = vec![vec![0; map[0].len()]; map.len()];
   63    65     let mut queue = vec![start];
   64    66 
   65    67     while let Some((x, y, dir)) = queue.pop() {
   66    -1         if visited[y][x] & dir != 0 {
   -1    68         if visited[y][x] & (dir as u8) != 0 {
   67    69             continue;
   68    -1         } else {
   69    -1             visited[y][x] |= dir;
   70    70         }
   71    71 
   72    72         match map[y][x] {
   73    -1             Cell::Empty => match dir {
   74    -1                 RIGHT => push(&map, &mut queue, x, y, dir),
   75    -1                 LEFT => push(&map, &mut queue, x, y, dir),
   76    -1                 UP => push(&map, &mut queue, x, y, dir),
   77    -1                 DOWN => push(&map, &mut queue, x, y, dir),
   78    -1                 _ => unreachable!(),
   79    -1             },
   -1    73             Cell::Empty => {
   -1    74                 push(&map, &mut queue, x, y, dir);
   -1    75             }
   80    76             Cell::SplitHorizontal => {
   81    77                 if visited[y][x] != 0 {
   82    78                     continue;
   83    79                 }
   84    80                 match dir {
   85    -1                     RIGHT => push(&map, &mut queue, x, y, dir),
   86    -1                     LEFT => push(&map, &mut queue, x, y, dir),
   87    -1                     UP | DOWN => {
   88    -1                         push(&map, &mut queue, x, y, LEFT);
   89    -1                         push(&map, &mut queue, x, y, RIGHT);
   -1    81                     Dir::Right | Dir::Left => {
   -1    82                         push(&map, &mut queue, x, y, dir);
   -1    83                     }
   -1    84                     Dir::Up | Dir::Down => {
   -1    85                         push(&map, &mut queue, x, y, Dir::Left);
   -1    86                         push(&map, &mut queue, x, y, Dir::Right);
   90    87                     }
   91    -1                     _ => unreachable!(),
   92    88                 };
   93    -1             },
   -1    89             }
   94    90             Cell::SplitVertical => {
   95    91                 if visited[y][x] != 0 {
   96    92                     continue;
   97    93                 }
   98    94                 match dir {
   99    -1                     UP => push(&map, &mut queue, x, y, dir),
  100    -1                     DOWN => push(&map, &mut queue, x, y, dir),
  101    -1                     LEFT | RIGHT => {
  102    -1                         push(&map, &mut queue, x, y, UP);
  103    -1                         push(&map, &mut queue, x, y, DOWN);
   -1    95                     Dir::Up | Dir::Down => {
   -1    96                         push(&map, &mut queue, x, y, dir);
   -1    97                     }
   -1    98                     Dir::Left | Dir::Right => {
   -1    99                         push(&map, &mut queue, x, y, Dir::Up);
   -1   100                         push(&map, &mut queue, x, y, Dir::Down);
  104   101                     }
  105    -1                     _ => unreachable!(),
  106   102                 };
  107    -1             },
   -1   103             }
  108   104             Cell::MirrorRight => match dir {
  109    -1                 UP => push(&map, &mut queue, x, y, RIGHT),
  110    -1                 RIGHT => push(&map, &mut queue, x, y, UP),
  111    -1                 DOWN => push(&map, &mut queue, x, y, LEFT),
  112    -1                 LEFT => push(&map, &mut queue, x, y, DOWN),
  113    -1                 _ => unreachable!(),
   -1   105                 Dir::Up => push(&map, &mut queue, x, y, Dir::Right),
   -1   106                 Dir::Right => push(&map, &mut queue, x, y, Dir::Up),
   -1   107                 Dir::Down => push(&map, &mut queue, x, y, Dir::Left),
   -1   108                 Dir::Left => push(&map, &mut queue, x, y, Dir::Down),
  114   109             },
  115   110             Cell::MirrorLeft => match dir {
  116    -1                 DOWN => push(&map, &mut queue, x, y, RIGHT),
  117    -1                 LEFT => push(&map, &mut queue, x, y, UP),
  118    -1                 UP => push(&map, &mut queue, x, y, LEFT),
  119    -1                 RIGHT => push(&map, &mut queue, x, y, DOWN),
  120    -1                 _ => unreachable!(),
   -1   111                 Dir::Down => push(&map, &mut queue, x, y, Dir::Right),
   -1   112                 Dir::Left => push(&map, &mut queue, x, y, Dir::Up),
   -1   113                 Dir::Up => push(&map, &mut queue, x, y, Dir::Left),
   -1   114                 Dir::Right => push(&map, &mut queue, x, y, Dir::Down),
  121   115             },
  122   116         }
   -1   117         visited[y][x] |= dir as u8;
  123   118     }
  124   119 
  125   120     let mut sum = 0;
@@ -137,17 +132,17 @@ fn count(map: &Vec<Vec<Cell>>, start: (usize, usize, u8)) -> usize {
  137   132 fn main() {
  138   133     let map = parse_input();
  139   134 
  140    -1     let sum1 = count(&map, (0, 0, RIGHT));
   -1   135     let sum1 = count(&map, (0, 0, Dir::Right));
  141   136     println!("part1: {}", sum1);
  142   137 
  143   138     let mut sum2 = 0;
  144   139     for x in 0..map[0].len() {
  145    -1         sum2 = sum2.max(count(&map, (x, 0, DOWN)));
  146    -1         sum2 = sum2.max(count(&map, (x, map.len() - 1, UP)));
   -1   140         sum2 = sum2.max(count(&map, (x, 0, Dir::Down)));
   -1   141         sum2 = sum2.max(count(&map, (x, map.len() - 1, Dir::Up)));
  147   142     }
  148   143     for y in 0..map.len() {
  149    -1         sum2 = sum2.max(count(&map, (0, y, RIGHT)));
  150    -1         sum2 = sum2.max(count(&map, (map[0].len() - 1, y, LEFT)));
   -1   144         sum2 = sum2.max(count(&map, (0, y, Dir::Right)));
   -1   145         sum2 = sum2.max(count(&map, (map[0].len() - 1, y, Dir::Left)));
  151   146     }
  152   147     println!("part2: {}", sum2);
  153   148 }