days 14 and 15 i suppose!
This commit is contained in:
parent
dda3e2d511
commit
51777c2af8
7
day14/Cargo.toml
Normal file
7
day14/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "day14"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
regex = "1.11.1"
|
116
day14/src/main.rs
Normal file
116
day14/src/main.rs
Normal file
@ -0,0 +1,116 @@
|
||||
use std::collections::HashSet;
|
||||
use regex::Regex;
|
||||
use std::env;
|
||||
|
||||
use std::fs;
|
||||
|
||||
use crate::Dir::{North, South, East, West };
|
||||
|
||||
type Coord = (i128, i128);
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
enum Dir { North, South, East, West }
|
||||
|
||||
fn step(start: &Coord, d: Dir, steps: i128) -> Coord {
|
||||
match d {
|
||||
North => (start.0, start.1 - steps),
|
||||
South => (start.0, start.1 + steps),
|
||||
East => (start.0 + steps, start.1),
|
||||
West => (start.0 - steps, start.1),
|
||||
}
|
||||
}
|
||||
|
||||
fn walk(start: &Coord, diff: &Coord) -> Coord {
|
||||
(start.0 + diff.0, start.1 + diff.1)
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
struct Robot { start: Coord, velocity: Coord }
|
||||
|
||||
fn main() {
|
||||
println!("Hello, AoC day 13!");
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() != 2 {
|
||||
println!("wrong number of arguments!");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let file_path = &args[1];
|
||||
|
||||
let find_record = Regex::new(r"p=([0-9]+),([0-9]+) v=(-?[0-9]+),(-?[0-9]+)").unwrap();
|
||||
|
||||
let binding = fs::read_to_string(file_path)
|
||||
.expect("should be able to read the file");
|
||||
let robots = binding.lines()
|
||||
.filter_map(|l| find_record.captures(l) )
|
||||
.map(|caps| Robot {
|
||||
start: (caps[1].parse().unwrap(), caps[2].parse().unwrap()),
|
||||
velocity: (caps[3].parse().unwrap(), caps[4].parse().unwrap())
|
||||
})
|
||||
.collect::<Vec<Robot>>();
|
||||
|
||||
let corner = (101, 103);
|
||||
|
||||
let mut new_robots = robots.clone();
|
||||
for _ in 0..100 { iterate(&mut new_robots, corner); }
|
||||
println!("the safety factor after 100 seconsd is {}", safety_factor(&mut new_robots, corner));
|
||||
|
||||
let seconds = 17774;
|
||||
|
||||
let mut new_robots = robots.clone();
|
||||
iterate_n(&mut new_robots, corner, seconds);
|
||||
print_scene(&new_robots, corner);
|
||||
|
||||
}
|
||||
|
||||
fn iterate(robots: &mut Vec<Robot>, corner: Coord) -> usize {
|
||||
let mut positions: HashSet<Coord> = HashSet::new();
|
||||
for r in robots {
|
||||
r.start.0 = (r.start.0 + r.velocity.0).rem_euclid(corner.0);
|
||||
r.start.1 = (r.start.1 + r.velocity.1).rem_euclid(corner.1);
|
||||
positions.insert(r.start);
|
||||
}
|
||||
return positions.len();
|
||||
}
|
||||
|
||||
fn iterate_n(robots: &mut Vec<Robot>, corner: Coord, seconds: i128) -> usize {
|
||||
let mut positions: HashSet<Coord> = HashSet::new();
|
||||
for r in robots {
|
||||
r.start.0 = (r.start.0 + r.velocity.0*seconds).rem_euclid(corner.0);
|
||||
r.start.1 = (r.start.1 + r.velocity.1*seconds).rem_euclid(corner.1);
|
||||
positions.insert(r.start);
|
||||
}
|
||||
return positions.len();
|
||||
}
|
||||
|
||||
fn print_scene(robots: &Vec<Robot>, corner: Coord) {
|
||||
let mut positions: HashSet<Coord> = HashSet::new();
|
||||
for Robot {start, velocity: _} in robots.iter() {
|
||||
positions.insert(*start);
|
||||
}
|
||||
for x in 0..corner.0 {
|
||||
for y in 0..corner.1 {
|
||||
print!("{}", if positions.contains(&(x,y)) { "#" } else { "." });
|
||||
}
|
||||
print!("\n");
|
||||
}
|
||||
}
|
||||
|
||||
fn safety_factor(robots: &mut Vec<Robot>, corner: Coord) -> i128 {
|
||||
let mut q: [i128; 4] = [0,0,0,0];
|
||||
|
||||
let halfs = ((corner.0 - 1) / 2, (corner.1 - 1) / 2);
|
||||
for Robot { start, velocity: _ } in robots {
|
||||
if start.0 < halfs.0 && start.1 < halfs.1 {
|
||||
q[0] += 1;
|
||||
} else if start.0 > halfs.0 && start.1 < halfs.1 {
|
||||
q[1] += 1;
|
||||
} else if start.0 < halfs.0 && start.1 > halfs.1 {
|
||||
q[2] += 1;
|
||||
} else if start.0 > halfs.0 && start.1 > halfs.1 {
|
||||
q[3] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return q[0]*q[1]*q[2]*q[3];
|
||||
}
|
7
day15/Cargo.toml
Normal file
7
day15/Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "day15"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
itertools = "0.13.0"
|
228
day15/src/main.rs
Normal file
228
day15/src/main.rs
Normal file
@ -0,0 +1,228 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::Dir::{North, South, East, West };
|
||||
|
||||
type Coord = (i32, i32);
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
enum Dir { North, South, East, West }
|
||||
|
||||
fn step(start: &Coord, d: Dir, steps: i32) -> Coord {
|
||||
match d {
|
||||
North => (start.0, start.1 - steps),
|
||||
South => (start.0, start.1 + steps),
|
||||
East => (start.0 + steps, start.1),
|
||||
West => (start.0 - steps, start.1),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, AoC day 13!");
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() != 2 {
|
||||
println!("wrong number of arguments!");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let file_path = &args[1];
|
||||
|
||||
let binding = fs::read_to_string(file_path)
|
||||
.expect("should be able to read the file");
|
||||
let (map_string, instructions_string) = binding
|
||||
.split_once("\n\n")
|
||||
.expect("should have a map and an instructions section");
|
||||
|
||||
let mut map = HashMap::new();
|
||||
|
||||
let mut robot = (0,0);
|
||||
let mut y = 0;
|
||||
for line in map_string.lines() {
|
||||
let mut x = 0;
|
||||
for c in line.chars() {
|
||||
if c == '@' {
|
||||
robot = (x,y);
|
||||
map.insert((x,y), '.');
|
||||
} else {
|
||||
map.insert((x,y), c);
|
||||
}
|
||||
x += 1;
|
||||
}
|
||||
y += 1;
|
||||
}
|
||||
|
||||
let binding = instructions_string
|
||||
.lines()
|
||||
.join("");
|
||||
let instructions = binding
|
||||
.chars()
|
||||
.map(|c| match c { '^'=>North, '>'=>East, 'v'=>South, '<'=>West, _=>North });
|
||||
|
||||
for direction in instructions {
|
||||
let next = step(&robot, direction, 1);
|
||||
let neighbor = map.get(&next);
|
||||
if neighbor == Some(&'.') {
|
||||
robot = next;
|
||||
} else if neighbor == Some(&'#') {
|
||||
continue;
|
||||
} else if neighbor == Some(&'O') {
|
||||
let mut steps = 1;
|
||||
let mut stack_top = map.get(&step(&robot, direction, steps));
|
||||
while stack_top == Some(&'O') {
|
||||
steps = steps + 1;
|
||||
stack_top = map.get(&step(&robot, direction, steps));
|
||||
}
|
||||
if stack_top == Some(&'.') {
|
||||
map.insert(step(&robot, direction, steps), 'O');
|
||||
map.insert(next, '.');
|
||||
robot = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("the gps score after all the instructions is {}", sum_of_box_gps(&map));
|
||||
|
||||
let mut map = HashMap::new();
|
||||
|
||||
let mut robot = (0,0);
|
||||
let mut y = 0;
|
||||
for line in map_string.lines() {
|
||||
let mut x = 0;
|
||||
for c in line.chars() {
|
||||
match c {
|
||||
'@' => {
|
||||
robot = (2*x,y);
|
||||
map.insert((2*x,y), '.');
|
||||
map.insert((2*x+1,y), '.');
|
||||
},
|
||||
'.' => {
|
||||
map.insert((2*x, y), '.');
|
||||
map.insert((2*x+1, y), '.');
|
||||
},
|
||||
'O' => {
|
||||
map.insert((2*x, y), '[');
|
||||
map.insert((2*x+1, y), ']');
|
||||
},
|
||||
'#' => {
|
||||
map.insert((2*x, y), '#');
|
||||
map.insert((2*x+1, y), '#');
|
||||
},
|
||||
_ => {
|
||||
map.insert((2*x, y), '.');
|
||||
map.insert((2*x+1, y), '.');
|
||||
}
|
||||
}
|
||||
x += 1;
|
||||
}
|
||||
y += 1;
|
||||
}
|
||||
|
||||
let binding = instructions_string
|
||||
.lines()
|
||||
.join("");
|
||||
let instructions = binding
|
||||
.chars()
|
||||
.map(|c| match c { '^'=>North, '>'=>East, 'v'=>South, '<'=>West, _=>North });
|
||||
|
||||
for direction in instructions {
|
||||
let next = step(&robot, direction, 1);
|
||||
let neighbor = map.get(&next);
|
||||
if neighbor == Some(&'.') {
|
||||
robot = next;
|
||||
} else if neighbor == Some(&'#') {
|
||||
continue;
|
||||
} else if neighbor == Some(&'[') || neighbor == Some(&']') {
|
||||
let mut boxes_to_move: HashSet<Coord> = HashSet::new();
|
||||
let mut unexamined_boxes: HashSet<Coord> = HashSet::new();
|
||||
|
||||
unexamined_boxes.insert(next);
|
||||
|
||||
while !unexamined_boxes.is_empty() {
|
||||
let mut candidate_boxes: HashSet<Coord> = HashSet::new();
|
||||
for spot in unexamined_boxes.drain() {
|
||||
match map.get(&spot) {
|
||||
Some('[') => {
|
||||
let other_half = step(&spot, East, 1);
|
||||
if !boxes_to_move.contains(&other_half) {
|
||||
candidate_boxes.insert(other_half);
|
||||
}
|
||||
candidate_boxes.insert(step(&spot, direction, 1));
|
||||
boxes_to_move.insert(spot);
|
||||
},
|
||||
Some(']') => {
|
||||
let other_half = step(&spot, West, 1);
|
||||
if !boxes_to_move.contains(&other_half) {
|
||||
candidate_boxes.insert(other_half);
|
||||
}
|
||||
candidate_boxes.insert(step(&spot, direction, 1));
|
||||
boxes_to_move.insert(spot);
|
||||
},
|
||||
Some('#') => {
|
||||
boxes_to_move.drain();
|
||||
candidate_boxes.drain();
|
||||
break;
|
||||
},
|
||||
Some('.') => {
|
||||
continue;
|
||||
},
|
||||
_ => {
|
||||
println!("encountered something weird in the map");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
unexamined_boxes = candidate_boxes;
|
||||
}
|
||||
|
||||
if !boxes_to_move.is_empty() {
|
||||
robot = next;
|
||||
let mut fulls: HashMap<Coord, char> = HashMap::new();
|
||||
for b in &boxes_to_move {
|
||||
fulls.insert(step(&b, direction, 1), *map.get(&b).unwrap());
|
||||
}
|
||||
|
||||
for x in boxes_to_move {
|
||||
map.insert(x, '.');
|
||||
}
|
||||
for (x, c) in fulls {
|
||||
map.insert(x, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print_map(&map);
|
||||
|
||||
println!("the gps score after all the instructions in wide mode is {}", sum_of_box_gps(&map));
|
||||
}
|
||||
|
||||
fn sum_of_box_gps(grid: &HashMap<Coord, char>) -> i32 {
|
||||
let mut sum = 0;
|
||||
|
||||
for ((x, y), stuff) in grid {
|
||||
if *stuff == 'O' { sum += x + 100*y; }
|
||||
if *stuff == '[' { sum += x + 100*y; }
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
fn print_map(grid: &HashMap<Coord, char>) {
|
||||
let (mut x_max, mut y_max): (i32, i32) = (0,0);
|
||||
for ((x, y), _) in grid {
|
||||
x_max = x_max.max(*x);
|
||||
y_max = y_max.max(*y)
|
||||
}
|
||||
|
||||
for y in 0..y_max {
|
||||
for x in 0..x_max {
|
||||
print!("{}", grid.get(&(x,y)).unwrap())
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user