Format all
This commit is contained in:
@@ -10,7 +10,7 @@ struct Machine {
|
||||
#[allow(dead_code)]
|
||||
lights: Vec<u64>,
|
||||
buttons: Vec<Vec<usize>>,
|
||||
joltages: Vec<u64>
|
||||
joltages: Vec<u64>,
|
||||
}
|
||||
|
||||
impl FromStr for Machine {
|
||||
@@ -19,42 +19,46 @@ impl FromStr for Machine {
|
||||
let groups: Vec<_> = s.split(' ').collect();
|
||||
|
||||
let lights_part = groups[0];
|
||||
let lights = lights_part[1..lights_part.len()-1]
|
||||
let lights = lights_part[1..lights_part.len() - 1]
|
||||
.chars()
|
||||
.map(|c| if c == '#' { 1 } else { 0 })
|
||||
.collect();
|
||||
|
||||
let buttons: Vec<_> = (1..groups.len()-1)
|
||||
let buttons: Vec<_> = (1..groups.len() - 1)
|
||||
.map(|i| parse_button_group(groups[i]))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
let joltages_part = groups[groups.len()-1];
|
||||
let joltages: Vec<_> = joltages_part[1..joltages_part.len()-1]
|
||||
let joltages_part = groups[groups.len() - 1];
|
||||
let joltages: Vec<_> = joltages_part[1..joltages_part.len() - 1]
|
||||
.split(',')
|
||||
.map(|j_s| j_s.parse::<u64>())
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(Machine { lights, buttons , joltages })
|
||||
Ok(Machine {
|
||||
lights,
|
||||
buttons,
|
||||
joltages,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_button_group(s: &str) -> Result<Vec<usize>, ParseIntError> {
|
||||
s[1..s.len()-1].split(',')
|
||||
s[1..s.len() - 1]
|
||||
.split(',')
|
||||
.map(str::parse::<usize>)
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
fn parity_solve(machine: &Machine, target: &[u64]) -> Vec<u64> {
|
||||
let mut solutions: Vec<u64> = Vec::new();
|
||||
for selection in 0..(1 << machine.buttons.len()) {
|
||||
let mut parity = target.iter().rev()
|
||||
let mut parity = target
|
||||
.iter()
|
||||
.rev()
|
||||
.fold(0, |state, x| (state << 1) | (x & 1));
|
||||
for (i, button) in machine.buttons.iter().enumerate() {
|
||||
if selection & (1 << i) != 0 {
|
||||
parity = button.iter().fold(parity, |parity, j| {
|
||||
parity ^ (1 << j)
|
||||
});
|
||||
parity = button.iter().fold(parity, |parity, j| parity ^ (1 << j));
|
||||
}
|
||||
}
|
||||
if parity == 0 {
|
||||
@@ -65,7 +69,11 @@ fn parity_solve(machine: &Machine, target: &[u64]) -> Vec<u64> {
|
||||
}
|
||||
|
||||
fn minimum_solve(machine: &Machine) -> u64 {
|
||||
fn apply_button<'a>(machine: &Machine, button_idx: usize, current: &'a mut Vec<u64>) -> Option<&'a mut Vec<u64>> {
|
||||
fn apply_button<'a>(
|
||||
machine: &Machine,
|
||||
button_idx: usize,
|
||||
current: &'a mut Vec<u64>,
|
||||
) -> Option<&'a mut Vec<u64>> {
|
||||
for i in &machine.buttons[button_idx] {
|
||||
if current[*i] == 0 {
|
||||
return None;
|
||||
@@ -76,8 +84,12 @@ fn minimum_solve(machine: &Machine) -> u64 {
|
||||
}
|
||||
|
||||
fn recurse(machine: &Machine, target: &[u64], max_cnt: i64) -> Option<u64> {
|
||||
if target.iter().sum::<u64>() == 0 { return Some(0) };
|
||||
if max_cnt <= 0 { return None };
|
||||
if target.iter().sum::<u64>() == 0 {
|
||||
return Some(0);
|
||||
};
|
||||
if max_cnt <= 0 {
|
||||
return None;
|
||||
};
|
||||
|
||||
let parity_solutions = parity_solve(machine, target);
|
||||
|
||||
@@ -85,8 +97,8 @@ fn minimum_solve(machine: &Machine) -> u64 {
|
||||
let mut current_storage = target.to_vec();
|
||||
for parity_sln in parity_solutions {
|
||||
current_storage.copy_from_slice(target);
|
||||
let current = (0..machine.buttons.len())
|
||||
.fold(Some(&mut current_storage), |state, i| {
|
||||
let current =
|
||||
(0..machine.buttons.len()).fold(Some(&mut current_storage), |state, i| {
|
||||
if parity_sln & (1 << i) != 0 {
|
||||
apply_button(machine, i, state?)
|
||||
} else {
|
||||
@@ -96,17 +108,19 @@ fn minimum_solve(machine: &Machine) -> u64 {
|
||||
let Some(current) = current else { continue };
|
||||
let parity_ones = parity_sln.count_ones() as i64;
|
||||
|
||||
let new_max_cnt =
|
||||
(match min_presses {
|
||||
None => max_cnt,
|
||||
Some(ms) => min(ms as i64, max_cnt)
|
||||
} - parity_ones) / 2;
|
||||
let new_max_cnt = (match min_presses {
|
||||
None => max_cnt,
|
||||
Some(ms) => min(ms as i64, max_cnt),
|
||||
} - parity_ones)
|
||||
/ 2;
|
||||
let new_target: Vec<_> = current.iter().map(|&x| x / 2).collect();
|
||||
let Some(sln) = recurse(machine, &new_target, new_max_cnt) else { continue };
|
||||
let Some(sln) = recurse(machine, &new_target, new_max_cnt) else {
|
||||
continue;
|
||||
};
|
||||
let presses = parity_ones as u64 + 2u64 * sln;
|
||||
min_presses = Some(match min_presses {
|
||||
None => presses,
|
||||
Some(ms) => min(ms, presses)
|
||||
Some(ms) => min(ms, presses),
|
||||
});
|
||||
}
|
||||
min_presses
|
||||
@@ -119,7 +133,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
let f = File::open("10-input.txt")?;
|
||||
let reader = BufReader::new(f);
|
||||
|
||||
let machines: Vec<_> = reader.lines()
|
||||
let machines: Vec<_> = reader
|
||||
.lines()
|
||||
.map(|l| Ok(l?.parse::<Machine>()?))
|
||||
.collect::<Result<_, Box<dyn Error>>>()?;
|
||||
println!("Parsed {} machines", machines.len());
|
||||
|
||||
@@ -1,30 +1,31 @@
|
||||
use std::{collections::HashMap, fs::File, io::{self, BufRead, BufReader}};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::File,
|
||||
io::{self, BufRead, BufReader},
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
enum GraphNode {
|
||||
Output,
|
||||
Branch(Vec<String>)
|
||||
Branch(Vec<String>),
|
||||
}
|
||||
|
||||
fn count_paths(
|
||||
node: &str,
|
||||
nodes: &HashMap<String, GraphNode>,
|
||||
memo: &mut HashMap<String, usize>
|
||||
memo: &mut HashMap<String, usize>,
|
||||
) -> usize {
|
||||
if let Some(&count) = memo.get(node) {
|
||||
return count;
|
||||
}
|
||||
|
||||
let count =
|
||||
match nodes.get(node) {
|
||||
None => 0,
|
||||
Some(GraphNode::Output) => 1,
|
||||
Some(GraphNode::Branch(children)) => {
|
||||
children.iter()
|
||||
.map(|c| count_paths(c, nodes, memo))
|
||||
.sum()
|
||||
}
|
||||
};
|
||||
let count = match nodes.get(node) {
|
||||
None => 0,
|
||||
Some(GraphNode::Output) => 1,
|
||||
Some(GraphNode::Branch(children)) => {
|
||||
children.iter().map(|c| count_paths(c, nodes, memo)).sum()
|
||||
}
|
||||
};
|
||||
memo.insert(node.to_string(), count);
|
||||
count
|
||||
}
|
||||
@@ -33,7 +34,8 @@ fn main() -> Result<(), io::Error> {
|
||||
let f = File::open("11-input.txt")?;
|
||||
let reader = BufReader::new(f);
|
||||
|
||||
let nodes: HashMap<String, GraphNode> = reader.lines()
|
||||
let nodes: HashMap<String, GraphNode> = reader
|
||||
.lines()
|
||||
.map(|line| {
|
||||
let line = line?;
|
||||
let parts: Vec<_> = line.split(' ').collect();
|
||||
@@ -48,23 +50,38 @@ fn main() -> Result<(), io::Error> {
|
||||
.collect::<Result<_, io::Error>>()?;
|
||||
|
||||
let svr_paths = count_paths("svr", &nodes, &mut HashMap::new());
|
||||
let missing_fft_paths = count_paths("svr",
|
||||
&(nodes.clone()
|
||||
.into_iter()
|
||||
.filter(|(k, _)| k != "fft")
|
||||
.collect()), &mut HashMap::new());
|
||||
let missing_dac_paths = count_paths("svr",
|
||||
&(nodes.clone()
|
||||
.into_iter()
|
||||
.filter(|(k, _)| k != "dac")
|
||||
.collect()), &mut HashMap::new());
|
||||
let missing_both_paths = count_paths("svr",
|
||||
&(nodes.clone()
|
||||
.into_iter()
|
||||
.filter(|(k, _)| k != "fft" && k != "dac")
|
||||
.collect()), &mut HashMap::new());
|
||||
let missing_fft_paths = count_paths(
|
||||
"svr",
|
||||
&(nodes
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|(k, _)| k != "fft")
|
||||
.collect()),
|
||||
&mut HashMap::new(),
|
||||
);
|
||||
let missing_dac_paths = count_paths(
|
||||
"svr",
|
||||
&(nodes
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|(k, _)| k != "dac")
|
||||
.collect()),
|
||||
&mut HashMap::new(),
|
||||
);
|
||||
let missing_both_paths = count_paths(
|
||||
"svr",
|
||||
&(nodes
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|(k, _)| k != "fft" && k != "dac")
|
||||
.collect()),
|
||||
&mut HashMap::new(),
|
||||
);
|
||||
|
||||
println!(
|
||||
"Result {}",
|
||||
svr_paths + missing_both_paths - missing_fft_paths - missing_dac_paths
|
||||
);
|
||||
|
||||
println!("Result {}", svr_paths + missing_both_paths - missing_fft_paths - missing_dac_paths);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
use std::convert::Infallible;
|
||||
use std::error::Error;
|
||||
use std::num::ParseIntError;
|
||||
use std::string::ParseError;
|
||||
use std::{fs::File, io::{self, BufRead, BufReader}, str::FromStr};
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufRead, BufReader},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
struct Piece {
|
||||
cells: Vec<Vec<bool>>
|
||||
cells: Vec<Vec<bool>>,
|
||||
}
|
||||
|
||||
impl FromStr for Piece {
|
||||
type Err = Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let cells =
|
||||
s.split('\n').map(|row| {
|
||||
row.chars().filter_map(|c| {
|
||||
match c {
|
||||
let cells = s
|
||||
.split('\n')
|
||||
.map(|row| {
|
||||
row.chars()
|
||||
.filter_map(|c| match c {
|
||||
'#' => Some(true),
|
||||
'.' => Some(false),
|
||||
_ => None
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
Ok(Piece { cells })
|
||||
@@ -40,17 +43,14 @@ impl Piece {
|
||||
}
|
||||
|
||||
fn true_area(&self) -> u64 {
|
||||
self.cells.iter()
|
||||
.flatten()
|
||||
.filter(|&&b| b)
|
||||
.count() as u64
|
||||
self.cells.iter().flatten().filter(|&&b| b).count() as u64
|
||||
}
|
||||
}
|
||||
|
||||
struct Region {
|
||||
width: u64,
|
||||
height: u64,
|
||||
requirements: Vec<u64>
|
||||
requirements: Vec<u64>,
|
||||
}
|
||||
|
||||
impl FromStr for Region {
|
||||
@@ -61,26 +61,36 @@ impl FromStr for Region {
|
||||
let (width_str, height_str) = area_str.split_once('x').unwrap();
|
||||
let width = width_str.parse::<u64>()?;
|
||||
let height = height_str.parse::<u64>()?;
|
||||
let requirements = requirements_str.split(' ')
|
||||
.filter_map(|s| s.parse::<u64>().ok())
|
||||
.collect();
|
||||
Ok(Region { width, height, requirements })
|
||||
let requirements = requirements_str
|
||||
.split(' ')
|
||||
.filter_map(|s| s.parse::<u64>().ok())
|
||||
.collect();
|
||||
Ok(Region {
|
||||
width,
|
||||
height,
|
||||
requirements,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn is_solveable(pieces: &[Piece], region: &Region) -> bool {
|
||||
// Lower area bound = perfectly packed
|
||||
let region_area = region.width * region.height;
|
||||
let used_area: u64 = pieces.iter()
|
||||
let used_area: u64 = pieces
|
||||
.iter()
|
||||
.zip(region.requirements.iter())
|
||||
.map(|(piece, cnt)| piece.true_area() * cnt)
|
||||
.sum();
|
||||
if used_area > region_area { return false };
|
||||
if used_area > region_area {
|
||||
return false;
|
||||
};
|
||||
|
||||
// Upper area bound = 3x3 pieces
|
||||
let available_3x3s = region.width / 3 * region.height / 3;
|
||||
let piece_cnt: u64 = region.requirements.iter().sum();
|
||||
if piece_cnt <= available_3x3s { return true };
|
||||
if piece_cnt <= available_3x3s {
|
||||
return true;
|
||||
};
|
||||
|
||||
println!("Non-trivial solution");
|
||||
false
|
||||
@@ -90,24 +100,23 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
let f = File::open("12-input.txt")?;
|
||||
let reader = BufReader::new(f);
|
||||
|
||||
let lines: Vec<_> = reader.lines().collect::<Result<_,_>>()?;
|
||||
let lines: Vec<_> = reader.lines().collect::<Result<_, _>>()?;
|
||||
let (lines_pieces, lines_regions) = lines.split_at(30);
|
||||
|
||||
let pieces: Vec<_> = lines_pieces.chunks(5)
|
||||
.map(|lines| {
|
||||
Ok(lines[1..lines.len()-1].join("\n").parse::<Piece>()?)
|
||||
})
|
||||
let pieces: Vec<_> = lines_pieces
|
||||
.chunks(5)
|
||||
.map(|lines| Ok(lines[1..lines.len() - 1].join("\n").parse::<Piece>()?))
|
||||
.collect::<Result<_, Box<dyn Error>>>()?;
|
||||
|
||||
let regions: Vec<_> = lines_regions.iter()
|
||||
.map(|line| {
|
||||
Ok(line.parse::<Region>()?)
|
||||
})
|
||||
let regions: Vec<_> = lines_regions
|
||||
.iter()
|
||||
.map(|line| Ok(line.parse::<Region>()?))
|
||||
.collect::<Result<_, Box<dyn Error>>>()?;
|
||||
|
||||
let result: u64 = regions.iter()
|
||||
let result: u64 = regions
|
||||
.iter()
|
||||
.filter(|region| is_solveable(&pieces, region))
|
||||
.count() as u64;
|
||||
println!("Result: {}", result);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,7 @@ fn main() -> Result<(), io::Error> {
|
||||
let f = File::open("2-input.txt")?;
|
||||
let reader = BufReader::new(f);
|
||||
let range_line = reader.lines().next().unwrap()?;
|
||||
let mut ranges: Vec<_> = range_line.split(",")
|
||||
.map(parse_range)
|
||||
.collect();
|
||||
let mut ranges: Vec<_> = range_line.split(",").map(parse_range).collect();
|
||||
ranges.sort_unstable();
|
||||
|
||||
let mut total: i64 = 0;
|
||||
|
||||
@@ -4,13 +4,9 @@ use std::{
|
||||
};
|
||||
|
||||
fn max_joltage(s: &str) -> u64 {
|
||||
let values: Vec<_> = s
|
||||
.chars()
|
||||
.map(|x| x.to_digit(10).unwrap())
|
||||
.collect();
|
||||
let values: Vec<_> = s.chars().map(|x| x.to_digit(10).unwrap()).collect();
|
||||
|
||||
let max_idx = |xs: &[u32]| {
|
||||
|
||||
xs.iter()
|
||||
.enumerate()
|
||||
.fold(0, |max, (i, &x)| if x > xs[max] { i } else { max })
|
||||
@@ -27,11 +23,7 @@ fn main() -> Result<(), io::Error> {
|
||||
let f = File::open("3-input.txt")?;
|
||||
let reader = BufReader::new(f);
|
||||
|
||||
let total: u64 = reader.lines()
|
||||
.map(|l| {
|
||||
max_joltage(&l.unwrap())
|
||||
})
|
||||
.sum();
|
||||
let total: u64 = reader.lines().map(|l| max_joltage(&l.unwrap())).sum();
|
||||
println!("Result: {}", total);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -15,9 +15,7 @@ const NEIGHBOURS: [(i32, i32); 8] = [
|
||||
];
|
||||
|
||||
fn parse_grid_line(line: &str) -> Vec<bool> {
|
||||
line.chars()
|
||||
.map(|c| c == '@')
|
||||
.collect()
|
||||
line.chars().map(|c| c == '@').collect()
|
||||
}
|
||||
|
||||
fn get_grid_cell(grid: &[Vec<bool>], x: i32, y: i32) -> bool {
|
||||
@@ -65,7 +63,7 @@ fn main() -> Result<(), io::Error> {
|
||||
.lines()
|
||||
.map(|line| Ok(parse_grid_line(&line?)))
|
||||
.collect::<Result<_, io::Error>>()?;
|
||||
|
||||
|
||||
let mut current_grid = original_grid.clone();
|
||||
let last_grid = loop {
|
||||
let next_grid = update_grid(¤t_grid);
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
use std::{error::Error, fs::File, io::{BufRead, BufReader}, num::ParseIntError, str::FromStr};
|
||||
use std::{
|
||||
error::Error,
|
||||
fs::File,
|
||||
io::{BufRead, BufReader},
|
||||
num::ParseIntError,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Node {
|
||||
@@ -12,7 +18,7 @@ impl Node {
|
||||
let dx = i64::from(a.x) - i64::from(b.x);
|
||||
let dy = i64::from(a.y) - i64::from(b.y);
|
||||
let dz = i64::from(a.z) - i64::from(b.z);
|
||||
dx*dx + dy*dy + dz*dz
|
||||
dx * dx + dy * dy + dz * dz
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +37,7 @@ impl FromStr for Node {
|
||||
#[derive(Debug)]
|
||||
struct DisjointSet<T> {
|
||||
nodes: Vec<T>,
|
||||
parents: Vec<usize>
|
||||
parents: Vec<usize>,
|
||||
}
|
||||
|
||||
impl<T> DisjointSet<T> {
|
||||
@@ -67,13 +73,14 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
let f = File::open("8-input.txt")?;
|
||||
let reader = BufReader::new(f);
|
||||
|
||||
let nodes: Vec<_> = reader.lines()
|
||||
let nodes: Vec<_> = reader
|
||||
.lines()
|
||||
.map(|l| Ok(l?.parse::<Node>()?))
|
||||
.collect::<Result<_, Box<dyn Error>>>()?;
|
||||
|
||||
let mut edges: Vec<(i64, usize, usize)> = Vec::new();
|
||||
for i in 0..nodes.len() {
|
||||
for j in i+1..nodes.len() {
|
||||
for j in i + 1..nodes.len() {
|
||||
let sqr_dist = Node::square_dist(&nodes[i], &nodes[j]);
|
||||
edges.push((sqr_dist, i, j));
|
||||
}
|
||||
@@ -81,7 +88,8 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
edges.sort_unstable_by_key(|(d, _, _)| *d);
|
||||
|
||||
let mut ds: DisjointSet<_> = DisjointSet::new(nodes);
|
||||
let connections: Vec<_> = edges.iter()
|
||||
let connections: Vec<_> = edges
|
||||
.iter()
|
||||
.filter_map(|(_, i, j)| ds.union(*i, *j).map(|_| (*i, *j)))
|
||||
.collect();
|
||||
|
||||
@@ -91,4 +99,4 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
let last_to = &nodes[last_connection.1];
|
||||
println!("Result {}", u64::from(last_from.x) * u64::from(last_to.x));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::str::FromStr;
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ParseVertexError;
|
||||
|
||||
@@ -17,11 +16,10 @@ impl Display for ParseVertexError {
|
||||
|
||||
impl Error for ParseVertexError {}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Vertex {
|
||||
x: i64,
|
||||
y: i64
|
||||
y: i64,
|
||||
}
|
||||
|
||||
impl FromStr for Vertex {
|
||||
@@ -29,20 +27,23 @@ impl FromStr for Vertex {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut values = s.split(',').map(str::parse::<i64>);
|
||||
|
||||
let Some(Ok(x)) = values.next() else { return Err(ParseVertexError) };
|
||||
let Some(Ok(y)) = values.next() else { return Err(ParseVertexError) };
|
||||
let Some(Ok(x)) = values.next() else {
|
||||
return Err(ParseVertexError);
|
||||
};
|
||||
let Some(Ok(y)) = values.next() else {
|
||||
return Err(ParseVertexError);
|
||||
};
|
||||
Ok(Vertex { x, y })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
struct Segment {
|
||||
lo: i64,
|
||||
hi: i64,
|
||||
truncate_lo: bool,
|
||||
truncate_hi: bool,
|
||||
dist: Option<i64>
|
||||
dist: Option<i64>,
|
||||
}
|
||||
|
||||
impl Segment {
|
||||
@@ -52,9 +53,7 @@ impl Segment {
|
||||
hi: max(start.x, end.x),
|
||||
truncate_lo: false,
|
||||
truncate_hi: false,
|
||||
dist:
|
||||
if start.x < end.x { Some(start.y) }
|
||||
else { None }
|
||||
dist: if start.x < end.x { Some(start.y) } else { None },
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,7 +76,6 @@ impl Debug for Segment {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn rect_area(x1: i64, x2: i64, y1: i64, y2: i64) -> i64 {
|
||||
(1 + i64::abs(x1 - x2)) * (1 + i64::abs(y1 - y2))
|
||||
}
|
||||
@@ -87,7 +85,9 @@ fn rect_from_point(state: &[Segment], v: &Vertex) -> i64 {
|
||||
|
||||
let mut max_y = i64::MIN;
|
||||
for segment in state {
|
||||
if segment.hi <= v.x { continue }
|
||||
if segment.hi <= v.x {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(seg_y) = segment.dist else { break };
|
||||
if seg_y >= max_y {
|
||||
@@ -103,7 +103,9 @@ fn rect_from_point(state: &[Segment], v: &Vertex) -> i64 {
|
||||
|
||||
let mut max_y = i64::MIN;
|
||||
for segment in state.iter().rev() {
|
||||
if segment.lo >= v.x { continue }
|
||||
if segment.lo >= v.x {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Some(seg_y) = segment.dist else { break };
|
||||
if seg_y >= max_y {
|
||||
@@ -125,8 +127,16 @@ fn update_state(state: &mut Vec<Segment>, incoming: Segment) {
|
||||
if incoming.lo <= current.lo && current.hi <= incoming.hi {
|
||||
state.remove(i);
|
||||
} else if current.lo < incoming.lo && incoming.hi < current.hi {
|
||||
state.push(Segment { hi: incoming.lo, truncate_hi: true, ..current });
|
||||
state.push(Segment { lo: incoming.hi, truncate_lo: true, ..current });
|
||||
state.push(Segment {
|
||||
hi: incoming.lo,
|
||||
truncate_hi: true,
|
||||
..current
|
||||
});
|
||||
state.push(Segment {
|
||||
lo: incoming.hi,
|
||||
truncate_lo: true,
|
||||
..current
|
||||
});
|
||||
state.remove(i);
|
||||
} else if current.lo < incoming.lo && incoming.lo < current.hi {
|
||||
state[i].hi = incoming.lo;
|
||||
@@ -143,11 +153,11 @@ fn update_state(state: &mut Vec<Segment>, incoming: Segment) {
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let f = File::open("9-input.txt")?;
|
||||
let reader = BufReader::new(f);
|
||||
let vertices: Vec<_> = reader.lines()
|
||||
let vertices: Vec<_> = reader
|
||||
.lines()
|
||||
.map(|l| Ok(l?.parse::<Vertex>()?))
|
||||
.collect::<Result<_, Box<dyn Error>>>()?;
|
||||
|
||||
|
||||
let mut horizontal_edges: Vec<(usize, usize)> = Vec::new();
|
||||
for i in 0..vertices.len() {
|
||||
let j = (i + 1) % vertices.len();
|
||||
@@ -158,7 +168,13 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
horizontal_edges.sort_unstable_by_key(|e| vertices[e.0].y);
|
||||
|
||||
let mut max_area: i64 = 0;
|
||||
let mut state = vec![Segment { lo: i64::MIN, hi: i64::MAX, truncate_lo: false, truncate_hi: false, dist: None }];
|
||||
let mut state = vec![Segment {
|
||||
lo: i64::MIN,
|
||||
hi: i64::MAX,
|
||||
truncate_lo: false,
|
||||
truncate_hi: false,
|
||||
dist: None,
|
||||
}];
|
||||
for e in horizontal_edges {
|
||||
let start = &vertices[e.0];
|
||||
let end = &vertices[e.1];
|
||||
@@ -169,4 +185,4 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
println!("Result {}", max_area);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user