adventofcode

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

commit
9d096be059fc0df2a322a48dfc7649a78ac975c1
parent
ee2b0b6598ed8ab2200e5afbd853ea978fe9f3da
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2022-12-22 10:14
hardcode (wrong result)

Diffstat

M 2022/22/solution.rs 272 ++++++++++++++++++++++++++++++++++++++++++++++---------------

1 files changed, 207 insertions, 65 deletions


diff --git a/2022/22/solution.rs b/2022/22/solution.rs

@@ -1,31 +1,27 @@
    1    -1 use std::collections::HashSet;
    2    -1 
    3     1 #[path = "../lib.rs"] mod lib;
    4     2 
    5    -1 fn get_input() -> (HashSet<(usize, usize)>, Vec<(usize, usize)>, Vec<(usize, bool)>) {
    6    -1     let mut walls = HashSet::new();
    7    -1     let mut offsets = vec![];
   -1     3 #[derive(PartialEq)]
   -1     4 enum Tile {
   -1     5     Free,
   -1     6     Wall,
   -1     7     Out,
   -1     8 }
   -1     9 
   -1    10 fn get_input() -> (Vec<Vec<Tile>>, Vec<(usize, bool)>) {
   -1    11     let mut map = vec![];
    8    12     let mut path = vec![];
    9    -1     let mut map = true;
   -1    13     let mut map_done = false;
   10    14 
   11    -1     for (y, line) in lib::iter_input().enumerate() {
   12    -1         let mut offset = 0;
   -1    15     for line in lib::iter_input() {
   13    16         if line == "" {
   14    -1             map = false;
   15    -1         } else if map {
   16    -1             for (x, c) in line.chars().enumerate() {
   17    -1                 match c {
   18    -1                     ' ' => {
   19    -1                         offset = x;
   20    -1                     },
   21    -1                     '#' => {
   22    -1                         walls.insert((x, y));
   23    -1                     }
   24    -1                     '.' => {},
   25    -1                     _ => unreachable!(),
   26    -1                 };
   27    -1             }
   28    -1             offsets.push((offset, line.len()));
   -1    17             map_done = true;
   -1    18         } else if !map_done {
   -1    19             map.push(line.chars().map(|c| match c {
   -1    20                 '.' => Tile::Free,
   -1    21                 '#' => Tile::Wall,
   -1    22                 ' ' => Tile::Out,
   -1    23                 _ => unreachable!(),
   -1    24             }).collect());
   29    25         } else {
   30    26             let mut s = String::new();
   31    27             for c in line.chars() {
@@ -41,20 +37,17 @@ fn get_input() -> (HashSet<(usize, usize)>, Vec<(usize, usize)>, Vec<(usize, boo
   41    37         }
   42    38     }
   43    39 
   44    -1     return (walls, offsets, path);
   -1    40     return (map, path);
   45    41 }
   46    42 
   47    -1 fn main() {
   48    -1     let (walls, offsets, path) = get_input();
   49    -1     println!("walls: {:?}", walls);
   50    -1     println!("offsets: {:?}", offsets);
   51    -1     println!("path: {:?}", path);
   -1    43 fn part1(map: &Vec<Vec<Tile>>, path: &Vec<(usize, bool)>) -> usize {
   -1    44     let height = map.len();
   52    45 
   53    46     let mut y = 0;
   54    -1     let mut x = offsets[y].0;
   -1    47     let mut x = 0;
   55    48     let mut dir = 0;
   56    49 
   57    -1     while walls.contains(&(x, y)) {
   -1    50     while map[y][x] != Tile::Free {
   58    51         x += 1;
   59    52     }
   60    53 
@@ -65,51 +58,43 @@ fn main() {
   65    58 
   66    59             match dir {
   67    60                 0 => {
   68    -1                     let (offset, len) = offsets[y];
   69    -1                     if x2 + 1 < len {
   70    -1                         x2 += 1;
   71    -1                     } else {
   72    -1                         x2 = offset;
   -1    61                     let width = map[y2].len();
   -1    62                     x2 = (x2 + 1) % width;
   -1    63                     while map[y2][x2] == Tile::Out {
   -1    64                         x2 = (x2 + 1) % width;
   73    65                     }
   74    66                 },
   75    67                 1 => {
   76    -1                     let offset = offsets.iter().enumerate().find(|(_, (offset, len))| x >= *offset && x < *len).map(|(i, _)| i).unwrap();
   77    -1                     let len = offsets.iter().enumerate().rfind(|(_, (offset, len))| x >= *offset && x < *len).map(|(i, _)| i).unwrap() + 1;
   78    -1                     println!("  {} {}", offset, len);
   79    -1 
   80    -1                     if y2 + 1 < len {
   81    -1                         y2 += 1;
   82    -1                     } else {
   83    -1                         y2 = offset;
   -1    68                     y2 = (y2 + 1) % height;
   -1    69                     while map[y2].len() <= x || map[y2][x2] == Tile::Out {
   -1    70                         y2 = (y2 + 1) % height;
   84    71                     }
   85    72                 },
   86    73                 2 => {
   87    -1                     let (offset, len) = offsets[y];
   88    -1                     if x2 > offset {
   89    -1                         x2 -= 1;
   90    -1                     } else {
   91    -1                         x2 = len - 1;
   -1    74                     let width = map[y2].len();
   -1    75                     x2 = (x2 + width - 1) % width;
   -1    76                     while map[y2][x2] == Tile::Out {
   -1    77                         x2 = (x2 + width - 1) % width;
   92    78                     }
   93    79                 },
   94    80                 3 => {
   95    -1                     let offset = offsets.iter().enumerate().find(|(_, (offset, len))| x >= *offset && x < *len).map(|(i, _)| i).unwrap();
   96    -1                     let len = offsets.iter().enumerate().rfind(|(_, (offset, len))| x >= *offset && x < *len).map(|(i, _)| i).unwrap() + 1;
   97    -1                     println!("  {} {}", offset, len);
   98    -1 
   99    -1                     if y2 > offset {
  100    -1                         y2 -= 1;
  101    -1                     } else {
  102    -1                         y2 = len - 1;
   -1    81                     y2 = (y2 + height - 1) % height;
   -1    82                     while map[y2].len() <= x || map[y2][x2] == Tile::Out {
   -1    83                         y2 = (y2 + height - 1) % height;
  103    84                     }
  104    85                 },
  105    86                 _ => unreachable!(),
  106    87             }
  107    88 
  108    -1             if walls.contains(&(x2, y2)) {
  109    -1                 break;
  110    -1             } else {
  111    -1                 x = x2;
  112    -1                 y = y2;
   -1    89             match map[y2][x2] {
   -1    90                 Tile::Free => {
   -1    91                     x = x2;
   -1    92                     y = y2;
   -1    93                 },
   -1    94                 Tile::Wall => {
   -1    95                     break;
   -1    96                 },
   -1    97                 Tile::Out => unreachable!(),
  113    98             }
  114    99         }
  115   100 
@@ -118,10 +103,167 @@ fn main() {
  118   103         } else {
  119   104             dir = (dir + 3) % 4;
  120   105         }
   -1   106     }
   -1   107 
   -1   108     return 1000 * (y + 1) + 4 * (x + 1) + dir;
   -1   109 }
   -1   110 
   -1   111 fn wrap2(x: usize, y: usize, dir: usize) -> (usize, usize, usize) {
   -1   112     // hardcoded cube topology
   -1   113 
   -1   114     let dx = x % 50;
   -1   115     let dy = y % 50;
   -1   116 
   -1   117     return match (x / 50, y / 50, dir) {
   -1   118         (1, 0, 0) => (
   -1   119             x + 1, y, dir
   -1   120         ),
   -1   121         (1, 0, 1) => (
   -1   122             x, y + 1, dir
   -1   123         ),
   -1   124         (1, 0, 2) => (
   -1   125             0 * 50,
   -1   126             (3 * 50 - 1) - dy,
   -1   127             0,
   -1   128         ),
   -1   129         (1, 0, 3) => (
   -1   130             0 * 50,
   -1   131             3 * 50 + dx,
   -1   132             0,
   -1   133         ),
   -1   134         (2, 0, 0) => (
   -1   135             2 * 50 - 1,
   -1   136             (3 * 50 - 1) - dy,
   -1   137             2,
   -1   138         ),
   -1   139         (2, 0, 1) => (
   -1   140             2 * 50 - 1,
   -1   141             (2 * 50 - 1) - dx,
   -1   142             2,
   -1   143         ),
   -1   144         (2, 0, 2) => (
   -1   145             x - 1, y, dir
   -1   146         ),
   -1   147         (2, 0, 3) => (
   -1   148             0 * 50 + dx,
   -1   149             4 * 50 - 1,
   -1   150             3,
   -1   151         ),
   -1   152         (1, 1, 0) => (
   -1   153             2 * 50 + dy,
   -1   154             1 * 50 - 1,
   -1   155             3,
   -1   156         ),
   -1   157         (1, 1, 1) => (
   -1   158             x, y + 1, dir
   -1   159         ),
   -1   160         (1, 1, 2) => (
   -1   161             0 * 50 + dy,
   -1   162             2 * 50,
   -1   163             1,
   -1   164         ),
   -1   165         (1, 1, 3) => (
   -1   166             x, y - 1, dir,
   -1   167         ),
   -1   168         (0, 2, 0) => (
   -1   169             x + 1, y, dir
   -1   170         ),
   -1   171         (0, 2, 1) => (
   -1   172             x, y + 1, dir
   -1   173         ),
   -1   174         (0, 2, 2) => (
   -1   175             1 * 50,
   -1   176             (1 * 50 - 1) - dy,
   -1   177             0,
   -1   178         ),
   -1   179         (0, 2, 3) => (
   -1   180             1 * 50,
   -1   181             1 * 50 + dy,
   -1   182             0,
   -1   183         ),
   -1   184         (1, 2, 0) => (
   -1   185             3 * 50 - 1,
   -1   186             (1 * 50 - 1) - dy,
   -1   187             2,
   -1   188         ),
   -1   189         (1, 2, 1) => (
   -1   190             1 * 50 - 1,
   -1   191             3 * 50 + dy,
   -1   192             2,
   -1   193         ),
   -1   194         (1, 2, 2) => (
   -1   195             x - 1, y, dir
   -1   196         ),
   -1   197         (1, 2, 3) => (
   -1   198             x, y - 1, dir
   -1   199         ),
   -1   200         (0, 3, 0) => (
   -1   201             1 * 50 + dy,
   -1   202             3 * 50 - 1,
   -1   203             3,
   -1   204         ),
   -1   205         (0, 3, 1) => (
   -1   206             2 * 50 + dx,
   -1   207             0 * 50,
   -1   208             1,
   -1   209         ),
   -1   210         (0, 3, 2) => (
   -1   211             1 * 50 + dx,
   -1   212             0 * 50,
   -1   213             1,
   -1   214         ),
   -1   215         (0, 3, 3) => (
   -1   216             x, y - 1, dir
   -1   217         ),
   -1   218         _ => unreachable!(),
   -1   219     };
   -1   220 }
   -1   221 
   -1   222 fn part2(map: &Vec<Vec<Tile>>, path: &Vec<(usize, bool)>) -> usize {
   -1   223     let mut y = 0;
   -1   224     let mut x = 0;
   -1   225     let mut dir = 0;
   -1   226 
   -1   227     while map[y][x] != Tile::Free {
   -1   228         x += 1;
   -1   229     }
   -1   230 
   -1   231     for (steps, turn) in path.iter() {
   -1   232         for _ in 0..*steps {
   -1   233             let (x2, y2, dir2) = match dir {
   -1   234                 0 => if (x + 1) % 50 == 0 { wrap2(x, y, dir) } else { (x + 1, y, dir) },
   -1   235                 1 => if (y + 1) % 50 == 0 { wrap2(x, y, dir) } else { (x, y + 1, dir) },
   -1   236                 2 => if x % 50 == 0 { wrap2(x, y, dir) } else { (x - 1, y, dir) },
   -1   237                 3 => if y % 50 == 0 { wrap2(x, y, dir) } else { (x, y - 1, dir) },
   -1   238                 _ => unreachable!(),
   -1   239             };
   -1   240 
   -1   241             match map[y2][x2] {
   -1   242                 Tile::Free => {
   -1   243                     x = x2;
   -1   244                     y = y2;
   -1   245                     dir = dir2;
   -1   246                 },
   -1   247                 Tile::Wall => {
   -1   248                     break;
   -1   249                 },
   -1   250                 Tile::Out => unreachable!(),
   -1   251             }
   -1   252         }
  121   253 
  122    -1         println!("{},{}", x, y);
   -1   254         if *turn {
   -1   255             dir = (dir + 1) % 4;
   -1   256         } else {
   -1   257             dir = (dir + 3) % 4;
   -1   258         }
  123   259     }
  124   260 
  125    -1     println!("{},{} {}", x, y, dir);
  126    -1     println!("part1: {}", 1000 * y + 4 * x + dir);
   -1   261     return 1000 * (y + 1) + 4 * (x + 1) + dir;
   -1   262 }
   -1   263 
   -1   264 fn main() {
   -1   265     let (map, path) = get_input();
   -1   266 
   -1   267     println!("part1: {}", part1(&map, &path));
   -1   268     println!("part2: {}", part2(&map, &path));
  127   269 }