Compare commits
3 Commits
5c4e9a9e9d
...
8bc589488c
| Author | SHA1 | Date | |
|---|---|---|---|
| 8bc589488c | |||
| cfb3ae497e | |||
| b922b808fc |
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -15,6 +15,7 @@ dependencies = [
|
|||||||
name = "aoc_2018"
|
name = "aoc_2018"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bmp",
|
||||||
"chrono",
|
"chrono",
|
||||||
"gcd",
|
"gcd",
|
||||||
"itertools",
|
"itertools",
|
||||||
@@ -22,6 +23,21 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bmp"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69985ff4f58085ac696454692d0b646a66ad1f9cc9be294c91dc51bb5df511ae"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ regex = "1.1.0"
|
|||||||
chrono = "0.4.6"
|
chrono = "0.4.6"
|
||||||
itertools = "0.7.11"
|
itertools = "0.7.11"
|
||||||
gcd = "1.1.0"
|
gcd = "1.1.0"
|
||||||
lazy_static = "1.2.0"
|
lazy_static = "1.2.0"
|
||||||
|
bmp = "0.5.0"
|
||||||
1478
input/day17.txt
1478
input/day17.txt
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
use std::collections::HashSet;
|
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
pub fn task1() {
|
pub fn task1() {
|
||||||
let frequency: i32 = utils::read_file("input/day01.txt")
|
let frequency: i32 = utils::read_file("input/day01.txt")
|
||||||
@@ -23,7 +23,8 @@ pub fn task2() {
|
|||||||
} else {
|
} else {
|
||||||
Some((*current, true))
|
Some((*current, true))
|
||||||
}
|
}
|
||||||
}).find(|state| state.1);
|
})
|
||||||
|
.find(|state| state.1);
|
||||||
|
|
||||||
println!("Part 2: {} was there already!", final_state.unwrap().0);
|
println!("Part 2: {} was there already!", final_state.unwrap().0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
use crate::utils;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum Use {
|
enum Use {
|
||||||
@@ -23,7 +23,8 @@ pub fn task1() {
|
|||||||
let width: u32 = m.get(4).unwrap().as_str().parse().unwrap();
|
let width: u32 = m.get(4).unwrap().as_str().parse().unwrap();
|
||||||
let height: u32 = m.get(5).unwrap().as_str().parse().unwrap();
|
let height: u32 = m.get(5).unwrap().as_str().parse().unwrap();
|
||||||
(id, left, top, width, height)
|
(id, left, top, width, height)
|
||||||
}).fold(
|
})
|
||||||
|
.fold(
|
||||||
HashMap::<(u32, u32), Use>::new(),
|
HashMap::<(u32, u32), Use>::new(),
|
||||||
|mut map, (id, left, top, width, height)| {
|
|mut map, (id, left, top, width, height)| {
|
||||||
for x in left..left + width {
|
for x in left..left + width {
|
||||||
@@ -38,7 +39,8 @@ pub fn task1() {
|
|||||||
|
|
||||||
map
|
map
|
||||||
},
|
},
|
||||||
).iter()
|
)
|
||||||
|
.iter()
|
||||||
.filter(|it| *it.1 == Use::Multi)
|
.filter(|it| *it.1 == Use::Multi)
|
||||||
.count();
|
.count();
|
||||||
|
|
||||||
@@ -60,7 +62,8 @@ pub fn task2() {
|
|||||||
let width: u32 = m.get(4).unwrap().as_str().parse().unwrap();
|
let width: u32 = m.get(4).unwrap().as_str().parse().unwrap();
|
||||||
let height: u32 = m.get(5).unwrap().as_str().parse().unwrap();
|
let height: u32 = m.get(5).unwrap().as_str().parse().unwrap();
|
||||||
(id, left, top, width, height)
|
(id, left, top, width, height)
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
let distribution: HashMap<(u32, u32), Use> = claims.iter().fold(
|
let distribution: HashMap<(u32, u32), Use> = claims.iter().fold(
|
||||||
HashMap::<(u32, u32), Use>::new(),
|
HashMap::<(u32, u32), Use>::new(),
|
||||||
@@ -90,7 +93,8 @@ pub fn task2() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}).unwrap();
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
println!("Part 2: {}", winner_id);
|
println!("Part 2: {}", winner_id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
use crate::utils;
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use crate::utils;
|
|
||||||
|
|
||||||
enum Activity {
|
enum Activity {
|
||||||
Starts(u32),
|
Starts(u32),
|
||||||
@@ -35,7 +35,8 @@ pub fn task1() {
|
|||||||
Activity::Starts(number)
|
Activity::Starts(number)
|
||||||
};
|
};
|
||||||
(time, activity)
|
(time, activity)
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
input.sort_by_key(|it| it.0);
|
input.sort_by_key(|it| it.0);
|
||||||
|
|
||||||
let mut current_id: u32 = 0;
|
let mut current_id: u32 = 0;
|
||||||
@@ -104,7 +105,8 @@ pub fn task2() {
|
|||||||
Activity::Starts(number)
|
Activity::Starts(number)
|
||||||
};
|
};
|
||||||
(time, activity)
|
(time, activity)
|
||||||
}).collect();
|
})
|
||||||
|
.collect();
|
||||||
input.sort_by_key(|it| it.0);
|
input.sort_by_key(|it| it.0);
|
||||||
|
|
||||||
let mut current_id: u32 = 0;
|
let mut current_id: u32 = 0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::time::Instant;
|
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
pub fn task1() {
|
pub fn task1() {
|
||||||
let mut input = utils::read_file("input/day05.txt");
|
let mut input = utils::read_file("input/day05.txt");
|
||||||
@@ -24,9 +24,11 @@ pub fn task2() {
|
|||||||
.chars()
|
.chars()
|
||||||
.filter(|ch| ch.eq_ignore_ascii_case(&c))
|
.filter(|ch| ch.eq_ignore_ascii_case(&c))
|
||||||
.collect::<String>(),
|
.collect::<String>(),
|
||||||
).len(),
|
)
|
||||||
|
.len(),
|
||||||
)
|
)
|
||||||
}).min_by_key(|it| it.1)
|
})
|
||||||
|
.min_by_key(|it| it.1)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
println!("Duration: {:?}", Instant::now() - start);
|
println!("Duration: {:?}", Instant::now() - start);
|
||||||
@@ -56,6 +58,7 @@ fn reduce(input: &str) -> String {
|
|||||||
stack.push(c);
|
stack.push(c);
|
||||||
}
|
}
|
||||||
stack
|
stack
|
||||||
}).iter()
|
})
|
||||||
|
.iter()
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ pub fn task1() {
|
|||||||
|
|
||||||
let mut open: HashSet<char> = tasks
|
let mut open: HashSet<char> = tasks
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|task| !depends_on.contains_key(task)).copied()
|
.filter(|task| !depends_on.contains_key(task))
|
||||||
|
.copied()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let mut result = String::new();
|
let mut result = String::new();
|
||||||
|
|||||||
@@ -200,7 +200,8 @@ impl Game {
|
|||||||
// None
|
// None
|
||||||
// }
|
// }
|
||||||
let map = Map::from_game(self, from);
|
let map = Map::from_game(self, from);
|
||||||
map.shortest_path(from, to).map(|path| *path.get(1).unwrap_or(&from))
|
map.shortest_path(from, to)
|
||||||
|
.map(|path| *path.get(1).unwrap_or(&from))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if a full round was played, false if the round aborted because all
|
/// Returns true if a full round was played, false if the round aborted because all
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
use bmp::Image;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::{collections::HashMap, fmt::Display};
|
||||||
|
|
||||||
|
use Tile::*;
|
||||||
fn horizontal(line: &str) -> Option<(i32, i32, i32)> {
|
fn horizontal(line: &str) -> Option<(i32, i32, i32)> {
|
||||||
let regex = Regex::new(r"y=(?P<y>\d+), x=(?P<x1>\d+)..(?P<x2>\d+)").unwrap();
|
let regex = Regex::new(r"y=(?P<y>\d+), x=(?P<x1>\d+)..(?P<x2>\d+)").unwrap();
|
||||||
regex.captures(line).map(|m| {
|
regex.captures(line).map(|m| {
|
||||||
@@ -27,41 +29,156 @@ fn vertical(line: &str) -> Option<(i32, i32, i32)> {
|
|||||||
}
|
}
|
||||||
pub fn task1() {
|
pub fn task1() {
|
||||||
let input = utils::read_file("input/day17.txt");
|
let input = utils::read_file("input/day17.txt");
|
||||||
let clay_tiles: HashSet<Pos> = input.lines().fold(HashSet::new(), |mut tiles, line| {
|
let mut clay_tiles: HashMap<Pos, Tile> =
|
||||||
if let Some((x, y1, y2)) = vertical(line) {
|
input.lines().fold(HashMap::new(), |mut tiles, line| {
|
||||||
for y in y1..=y2 {
|
if let Some((x, y1, y2)) = vertical(line) {
|
||||||
tiles.insert(Pos(x, y));
|
for y in y1..=y2 {
|
||||||
|
tiles.insert(Pos(x, y), Clay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if let Some((y, x1, x2)) = horizontal(line) {
|
||||||
if let Some((y, x1, x2)) = horizontal(line) {
|
for x in x1..=x2 {
|
||||||
for x in x1..=x2 {
|
tiles.insert(Pos(x, y), Clay);
|
||||||
tiles.insert(Pos(x, y));
|
}
|
||||||
}
|
}
|
||||||
}
|
tiles
|
||||||
tiles
|
});
|
||||||
});
|
|
||||||
let (x_min, x_max) = clay_tiles
|
|
||||||
.iter()
|
|
||||||
.map(|p| p.0)
|
|
||||||
.minmax()
|
|
||||||
.into_option()
|
|
||||||
.unwrap();
|
|
||||||
let (y_min, y_max) = clay_tiles
|
let (y_min, y_max) = clay_tiles
|
||||||
.iter()
|
.keys()
|
||||||
.map(|p| p.1)
|
.map(|p| p.1)
|
||||||
.minmax()
|
.minmax()
|
||||||
.into_option()
|
.into_option()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
dbg!(x_min);
|
flow(&mut clay_tiles, y_max, Pos(500, 0), Pos(500, 0));
|
||||||
dbg!(x_max);
|
|
||||||
dbg!(y_min);
|
let water_count = clay_tiles
|
||||||
dbg!(y_max);
|
.iter()
|
||||||
|
.filter(|(_, tile)| **tile == StuckWater || **tile == FallingWater)
|
||||||
|
.filter(|(p, _)| (y_min..=y_max).contains(&p.1))
|
||||||
|
.count();
|
||||||
|
println!("part 1 water count: {water_count}");
|
||||||
|
// print_tiles(&clay_tiles);
|
||||||
|
// 30605 too low
|
||||||
|
print_bmp(&clay_tiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash)]
|
#[allow(dead_code)]
|
||||||
|
fn print_tiles(tiles: &HashMap<Pos, Tile>) {
|
||||||
|
let (x_min, x_max) = tiles.keys().map(|p| p.0).minmax().into_option().unwrap();
|
||||||
|
let (_y_min, y_max) = tiles.keys().map(|p| p.1).minmax().into_option().unwrap();
|
||||||
|
|
||||||
|
for y in 0..=y_max {
|
||||||
|
for x in x_min..=x_max {
|
||||||
|
let s = match tiles.get(&Pos(x, y)) {
|
||||||
|
Some(t) => format!("{t}"),
|
||||||
|
None => " ".to_string(),
|
||||||
|
};
|
||||||
|
print!("{s}");
|
||||||
|
}
|
||||||
|
print!("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_bmp(tiles: &HashMap<Pos, Tile>) {
|
||||||
|
let (x_min, x_max) = tiles.keys().map(|p| p.0).minmax().into_option().unwrap();
|
||||||
|
let (y_min, y_max) = tiles.keys().map(|p| p.1).minmax().into_option().unwrap();
|
||||||
|
|
||||||
|
let mut img = Image::new((x_max - x_min + 1) as u32, (y_max - y_min + 1) as u32);
|
||||||
|
for y in 0..=y_max {
|
||||||
|
for x in x_min..=x_max {
|
||||||
|
let color = match tiles.get(&Pos(x, y)) {
|
||||||
|
Some(t) => match t {
|
||||||
|
Clay => bmp::consts::BROWN,
|
||||||
|
FallingWater => bmp::consts::LIGHT_BLUE,
|
||||||
|
StuckWater => bmp::consts::DARK_BLUE,
|
||||||
|
},
|
||||||
|
None => bmp::consts::WHITE,
|
||||||
|
};
|
||||||
|
img.set_pixel((x - x_min) as u32, (y - y_min) as u32, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
img.save("final.bmp").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns true iff going left/right and hit a wall
|
||||||
|
fn flow(tiles: &mut HashMap<Pos, Tile>, y_max: i32, pos: Pos, from: Pos) -> bool {
|
||||||
|
if pos.1 > y_max {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let Some(Clay) = tiles.get(&pos) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if let Some(StuckWater) = tiles.get(&pos) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if tiles.contains_key(&pos) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tiles.insert(pos, FallingWater);
|
||||||
|
// println!();
|
||||||
|
// print_tiles(tiles);
|
||||||
|
if flow(tiles, y_max, pos.down(), pos) {
|
||||||
|
let bumped_left = flow(tiles, y_max, pos.left(), pos);
|
||||||
|
let bumped_right = flow(tiles, y_max, pos.right(), pos);
|
||||||
|
if from.down() == pos {
|
||||||
|
if bumped_right && bumped_left {
|
||||||
|
fill(tiles, pos);
|
||||||
|
// println!();
|
||||||
|
// print_tiles(tiles);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if from.right() == pos && bumped_right {
|
||||||
|
return true;
|
||||||
|
} else if from.left() == pos && bumped_left {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill(tiles: &mut HashMap<Pos, Tile>, pos: Pos) {
|
||||||
|
if let Some(FallingWater) = tiles.get(&pos) {
|
||||||
|
tiles.insert(pos, StuckWater);
|
||||||
|
fill(tiles, pos.left());
|
||||||
|
fill(tiles, pos.right());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
enum Tile {
|
||||||
|
Clay,
|
||||||
|
FallingWater,
|
||||||
|
StuckWater,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Tile {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let s = match self {
|
||||||
|
Clay => "#",
|
||||||
|
FallingWater => "|",
|
||||||
|
StuckWater => "~",
|
||||||
|
};
|
||||||
|
f.write_str(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
|
||||||
struct Pos(i32, i32);
|
struct Pos(i32, i32);
|
||||||
|
|
||||||
|
impl Pos {
|
||||||
|
fn left(&self) -> Self {
|
||||||
|
Pos(self.0 - 1, self.1)
|
||||||
|
}
|
||||||
|
fn right(&self) -> Self {
|
||||||
|
Pos(self.0 + 1, self.1)
|
||||||
|
}
|
||||||
|
fn down(&self) -> Self {
|
||||||
|
Pos(self.0, self.1 + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -164,10 +164,7 @@ impl Cave {
|
|||||||
})
|
})
|
||||||
.for_each(|node| {
|
.for_each(|node| {
|
||||||
if self.equipment_allowed_for_region(node.0, node.1, node.2) {
|
if self.equipment_allowed_for_region(node.0, node.1, node.2) {
|
||||||
result.push(Edge {
|
result.push(Edge { cost: 1, node })
|
||||||
cost: 1,
|
|
||||||
node,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user