diff options
| author | nekineki <nekineki@nekineki.net> | 2023-12-20 09:44:30 +0100 |
|---|---|---|
| committer | nekineki <nekineki@nekineki.net> | 2023-12-20 10:20:36 +0100 |
| commit | cf07a9e62ac5c37809d34db21c80688407293215 (patch) | |
| tree | 556195554c4fa58cbac6e4413e57c79e4d469fd2 /2023 | |
| parent | 9abea8684fc36394b5d46dd006ada4320aa84880 (diff) | |
day18 part2
Diffstat (limited to '2023')
| -rw-r--r-- | 2023/day18.rs | 152 |
1 files changed, 65 insertions, 87 deletions
diff --git a/2023/day18.rs b/2023/day18.rs index 66e3831..53e4684 100644 --- a/2023/day18.rs +++ b/2023/day18.rs @@ -1,6 +1,4 @@ -#![allow(dead_code)] -#![allow(unused_variables)] -#![allow(unused_mut)] +use num::abs; use std::env; use std::fs::File; use std::io::Read; @@ -9,40 +7,67 @@ use std::io::Read; struct Line { dir: char, len: usize, - color: String, } -fn flood(mut m: Vec<Vec<usize>>) -> (Vec<Vec<usize>>, usize) { - let mut changes = 0; - for y in 1..m.len() - 1 { - for x in 1..m[0].len() - 1 { - if m[y][x] == 2 { - for (yy, xx) in [(y - 1, x), (y + 1, x), (y, x + 1), (y, x - 1)] { - if m[yy][xx] == 0 { - changes += 1; - m[yy][xx] = 2; - } - } +fn hex_to_line(hex: &str) -> Line { + let len = hex[2..7] + .chars() + .fold(0, |x, y| x * 16 + y.to_digit(16).unwrap()); + let dir = match hex.chars().nth(7).unwrap() { + '0' => 'R', + '1' => 'D', + '2' => 'L', + '3' => 'U', + _ => panic!(), + }; + return Line { + dir: dir, + len: len as usize, + }; +} + +fn lines_to_coords(path: &Vec<Line>) -> Vec<(i64, i64)> { + let mut coords: Vec<(i64, i64)> = Vec::new(); + coords.push((0, 0)); + + let mut x: i64 = 0; + let mut y: i64 = 0; + + for l in path { + match l.dir { + 'R' => { + x += l.len as i64; + coords.push((x, y)); } + 'L' => { + x -= l.len as i64; + coords.push((x, y)); + } + 'U' => { + y -= l.len as i64; + coords.push((x, y)); + } + 'D' => { + y += l.len as i64; + coords.push((x, y)); + } + _ => panic!(), } } - - (m, changes) + coords.push((0, 0)); + coords } -fn print_m(m: &Vec<Vec<usize>>) { - for l in m { - for a in l { - if a == &0 { - print!("."); - } else if a == &1 { - print!("#"); - } else { - print!("{}", a); - } - } - println!(); +fn shoelace(coords: &Vec<(i64, i64)>) -> i64 { + let mut area: i64 = 0; + let mut perimeter: i64 = 0; + for ((x0, y0), (x1, y1)) in coords.iter().zip(coords.iter().skip(1)) { + // area += (y0+y1) * (x0 - x1); + area += x0 * y1 - x1 * y0; + perimeter += abs(y1 - y0) + abs(x1 - x0); } + + area / 2 + perimeter / 2 + 1 } fn main() { @@ -57,73 +82,26 @@ fn main() { f.read_to_string(&mut content).expect("cannot read file"); let lines = content.trim_end().split('\n'); - let mut path: Vec<Line> = Vec::new(); + let mut lines1: Vec<Line> = Vec::new(); + let mut lines2: Vec<Line> = Vec::new(); for line in lines { let (a, ar) = line.split_once(' ').unwrap(); - let (b, c) = ar.split_once(' ').unwrap(); + let (b, hex) = ar.split_once(' ').unwrap(); let a = a.chars().next().unwrap(); let b = b.parse().unwrap(); // let c:u32 = c[2..c.len()-1].parse().unwrap(); - path.push(Line { - dir: a, - len: b, - color: c.to_string(), - }); - } - - let mut res1 = 0; - - let mut field = vec![vec![0; 600]; 600]; - let x0 = 300; - let y0 = 300; - let mut x = x0; - let mut y = y0; - field[y0 + 1][x0 + 1] = 2; - res1 += 1; - - for l in path { - match l.dir { - 'R' => { - for i in x..x + l.len { - field[y][i] = 1; - } - x += l.len; - res1 += l.len; - } - 'L' => { - for i in x - l.len..=x { - field[y][i] = 1; - } - x -= l.len; - res1 += l.len; - } - 'U' => { - for i in y - l.len..=y { - field[i][x] = 1; - } - y -= l.len; - res1 += l.len; - } - 'D' => { - for i in y..y + l.len { - field[i][x] = 1; - } - y += l.len; - res1 += l.len; - } - _ => panic!(), - } + lines1.push(Line { dir: a, len: b }); + lines2.push(hex_to_line(hex)); } - let mut changes = 1; - while changes != 0 { - (field, changes) = flood(field); - res1 += changes; - // print_m(&field); - } + let coords1 = lines_to_coords(&lines1); + let coords2 = lines_to_coords(&lines2); - let mut res2 = 0; + let res1 = shoelace(&coords1); + let res2 = shoelace(&coords2); println!("res1: {}", res1); println!("res2: {}", res2); + assert_eq!(res1, 31171); + assert_eq!(res2, 131431655002266); } |
