summaryrefslogtreecommitdiff
path: root/2023
diff options
context:
space:
mode:
authornekineki <nekineki@nekineki.net>2023-12-20 09:44:30 +0100
committernekineki <nekineki@nekineki.net>2023-12-20 10:20:36 +0100
commitcf07a9e62ac5c37809d34db21c80688407293215 (patch)
tree556195554c4fa58cbac6e4413e57c79e4d469fd2 /2023
parent9abea8684fc36394b5d46dd006ada4320aa84880 (diff)
day18 part2
Diffstat (limited to '2023')
-rw-r--r--2023/day18.rs152
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);
}