clippy fixes

clippy fixes #2

clippy fixed #3

removed unnecessary stuff
This commit is contained in:
2023-05-20 22:44:52 +02:00
parent ef2340eaae
commit b480601ee8
16 changed files with 127 additions and 149 deletions

View File

@@ -1,6 +1,6 @@
use crate::utils;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use crate::utils;
pub fn task1() { pub fn task1() {
let input = utils::read_file("input/day02.txt"); let input = utils::read_file("input/day02.txt");
@@ -83,7 +83,7 @@ pub fn task2_linear() {
// has that prefix. // has that prefix.
let mut root = Node::default(); let mut root = Node::default();
for id in input.lines() { for id in input.lines() {
add_id_to_tree(&mut root, &id); add_id_to_tree(&mut root, id);
} }
// find a match.. // find a match..
@@ -92,11 +92,11 @@ pub fn task2_linear() {
} }
fn find_some_match(node: &Node) -> Option<String> { fn find_some_match(node: &Node) -> Option<String> {
if let Some(result) = check_children_for_match(&node) { if let Some(result) = check_children_for_match(node) {
return Some(result); Some(result)
} else { } else {
for child in node.outgoing.values() { for child in node.outgoing.values() {
if let Some(result) = find_some_match(&child) { if let Some(result) = find_some_match(child) {
return Some(result); return Some(result);
} }
} }
@@ -113,14 +113,14 @@ fn find_some_match(node: &Node) -> Option<String> {
/// suffixes that appear more than once in a child node. Then we look at /// suffixes that appear more than once in a child node. Then we look at
/// all possible suffixes from all child nodes. If one suffix appears exactly /// all possible suffixes from all child nodes. If one suffix appears exactly
/// twice, we have a match. /// twice, we have a match.
fn check_children_for_match<'a>(node: &Node<'a>) -> Option<String> { fn check_children_for_match(node: &Node<'_>) -> Option<String> {
let edges: Vec<_> = node.outgoing.keys().collect(); let edges: Vec<_> = node.outgoing.keys().collect();
// create a set of candidate suffixes for each edge // create a set of candidate suffixes for each edge
let suffix_candidates: HashMap<char, HashSet<&str>> = edges let suffix_candidates: HashMap<char, HashSet<&str>> = edges
.iter() .iter()
.map(|c| { .map(|c| {
let mut suffix_count = HashMap::<&str, HashSet<&str>>::new(); let mut suffix_count = HashMap::<&str, HashSet<&str>>::new();
let ref ids = node.outgoing.get(&c).unwrap().same_prefix; let ids = &node.outgoing.get(c).unwrap().same_prefix;
for id in ids { for id in ids {
suffix_count suffix_count
.entry(&id[node.depth + 1..]) .entry(&id[node.depth + 1..])
@@ -136,7 +136,8 @@ fn check_children_for_match<'a>(node: &Node<'a>) -> Option<String> {
.map(|(suffix, _)| *suffix) .map(|(suffix, _)| *suffix)
.collect(), .collect(),
) )
}).collect(); })
.collect();
// go over all suffixes and count their occurences. If # = 2, match! // go over all suffixes and count their occurences. If # = 2, match!
let mut suffix_counter: HashMap<&str, usize> = HashMap::new(); let mut suffix_counter: HashMap<&str, usize> = HashMap::new();
for suffix_set in suffix_candidates.values() { for suffix_set in suffix_candidates.values() {
@@ -144,15 +145,10 @@ fn check_children_for_match<'a>(node: &Node<'a>) -> Option<String> {
*suffix_counter.entry(suffix).or_insert(0) += 1; *suffix_counter.entry(suffix).or_insert(0) += 1;
} }
} }
if let Some(suffix) =
suffix_counter suffix_counter
.iter() .iter()
.find_map(|(suffix, count)| if *count == 2 { Some(suffix) } else { None }) .find_map(|(suffix, count)| if *count == 2 { Some(suffix) } else { None })
{ .map(|suffix| format!("{}{}", node.prefix, &suffix))
Some(format!("{}{}", node.prefix, &suffix))
} else {
None
}
} }
#[derive(Default, Debug)] #[derive(Default, Debug)]
@@ -165,12 +161,12 @@ struct Node<'a> {
fn add_id_to_tree<'a>(root: &mut Node<'a>, id: &'a str) { fn add_id_to_tree<'a>(root: &mut Node<'a>, id: &'a str) {
let mut current = root; let mut current = root;
current.same_prefix.insert(&id); current.same_prefix.insert(id);
for (i, c) in id.chars().enumerate() { for (i, c) in id.chars().enumerate() {
{ {
let mut next = current.outgoing.entry(c).or_insert(Node::default()); let mut next = current.outgoing.entry(c).or_insert(Node::default());
next.depth = i + 1; next.depth = i + 1;
next.same_prefix.insert(&id); next.same_prefix.insert(id);
next.prefix = &id[..=i]; next.prefix = &id[..=i];
} }
current = { current }.outgoing.get_mut(&c).unwrap(); current = { current }.outgoing.get_mut(&c).unwrap();

View File

@@ -16,7 +16,7 @@ pub fn task1() {
.lines() .lines()
.map(|line| { .map(|line| {
// #12 @ 590,968: 25x14 // #12 @ 590,968: 25x14
let m = re.captures(&line).unwrap(); let m = re.captures(line).unwrap();
let id: u32 = m.get(1).unwrap().as_str().parse().unwrap(); let id: u32 = m.get(1).unwrap().as_str().parse().unwrap();
let left: u32 = m.get(2).unwrap().as_str().parse().unwrap(); let left: u32 = m.get(2).unwrap().as_str().parse().unwrap();
let top: u32 = m.get(3).unwrap().as_str().parse().unwrap(); let top: u32 = m.get(3).unwrap().as_str().parse().unwrap();
@@ -28,7 +28,7 @@ pub fn task1() {
|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 {
for y in top..top + height { for y in top..top + height {
if let None = map.get(&(x, y)) { if map.get(&(x, y)).is_none() {
map.insert((x, y), Use::Single(id)); map.insert((x, y), Use::Single(id));
} else { } else {
map.insert((x, y), Use::Multi); map.insert((x, y), Use::Multi);
@@ -53,7 +53,7 @@ pub fn task2() {
let claims: Vec<_> = input let claims: Vec<_> = input
.lines() .lines()
.map(|line| { .map(|line| {
let m = re.captures(&line).unwrap(); let m = re.captures(line).unwrap();
let id: u32 = m.get(1).unwrap().as_str().parse().unwrap(); let id: u32 = m.get(1).unwrap().as_str().parse().unwrap();
let left: u32 = m.get(2).unwrap().as_str().parse().unwrap(); let left: u32 = m.get(2).unwrap().as_str().parse().unwrap();
let top: u32 = m.get(3).unwrap().as_str().parse().unwrap(); let top: u32 = m.get(3).unwrap().as_str().parse().unwrap();
@@ -67,7 +67,7 @@ pub fn task2() {
|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 {
for y in *top..*top + *height { for y in *top..*top + *height {
if let None = map.get(&(x, y)) { if map.get(&(x, y)).is_none() {
map.insert((x, y), Use::Single(*id)); map.insert((x, y), Use::Single(*id));
} else { } else {
map.insert((x, y), Use::Multi); map.insert((x, y), Use::Multi);

View File

@@ -29,7 +29,7 @@ pub fn task1() {
} else if line.contains("wakes up") { } else if line.contains("wakes up") {
Activity::Awakens Activity::Awakens
} else { } else {
let number: u32 = line.split(' ').find(|part| part.starts_with("#")).unwrap()[1..] let number: u32 = line.split(' ').find(|part| part.starts_with('#')).unwrap()[1..]
.parse() .parse()
.unwrap(); .unwrap();
Activity::Starts(number) Activity::Starts(number)
@@ -45,7 +45,7 @@ pub fn task1() {
let minute = Duration::minutes(1); let minute = Duration::minutes(1);
for (time, activity) in input.into_iter() { for (time, activity) in input.into_iter() {
// for all minutes since last time slot fill arrays // for all minutes since last time slot fill arrays
let mut iter_time = last_time.clone(); let mut iter_time = last_time;
while iter_time < time { while iter_time < time {
if current_state == State::Asleep && iter_time.hour() == 0 { if current_state == State::Asleep && iter_time.hour() == 0 {
sleep_map.entry(current_id).or_insert([0; 60])[iter_time.minute() as usize] += 1; sleep_map.entry(current_id).or_insert([0; 60])[iter_time.minute() as usize] += 1;
@@ -98,7 +98,7 @@ pub fn task2() {
} else if line.contains("wakes up") { } else if line.contains("wakes up") {
Activity::Awakens Activity::Awakens
} else { } else {
let number: u32 = line.split(' ').find(|part| part.starts_with("#")).unwrap()[1..] let number: u32 = line.split(' ').find(|part| part.starts_with('#')).unwrap()[1..]
.parse() .parse()
.unwrap(); .unwrap();
Activity::Starts(number) Activity::Starts(number)
@@ -114,7 +114,7 @@ pub fn task2() {
let minute = Duration::minutes(1); let minute = Duration::minutes(1);
for (time, activity) in input.into_iter() { for (time, activity) in input.into_iter() {
// for all minutes since last time slot fill arrays // for all minutes since last time slot fill arrays
let mut iter_time = last_time.clone(); let mut iter_time = last_time;
while iter_time < time { while iter_time < time {
if current_state == State::Asleep && iter_time.hour() == 0 { if current_state == State::Asleep && iter_time.hour() == 0 {
sleep_map.entry(current_id).or_insert([0; 60])[iter_time.minute() as usize] += 1; sleep_map.entry(current_id).or_insert([0; 60])[iter_time.minute() as usize] += 1;

View File

@@ -1,3 +1,5 @@
use std::cmp::Ordering::{Equal, Greater, Less};
use crate::utils; use crate::utils;
pub fn task1() { pub fn task1() {
@@ -12,7 +14,8 @@ pub fn task1() {
split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(),
split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(),
) )
}).collect(); })
.collect();
let max_x = coordinates.iter().max_by_key(|it| it.0).unwrap().0; let max_x = coordinates.iter().max_by_key(|it| it.0).unwrap().0;
let max_y = coordinates.iter().max_by_key(|it| it.1).unwrap().1; let max_y = coordinates.iter().max_by_key(|it| it.1).unwrap().1;
@@ -26,22 +29,17 @@ pub fn task1() {
area.push(vec); area.push(vec);
} }
for (_, (a, b)) in coordinates.iter().enumerate() { for (a, b) in coordinates.iter() {
for x in 0..area.len() { for (x, col) in area.iter_mut().enumerate() {
for y in 0..area[x].len() { for (y, cell) in col.iter_mut().enumerate() {
let d = (i32::abs(*a as i32 - x as i32) + i32::abs(*b as i32 - y as i32)) as u16; let d = (i32::abs(*a as i32 - x as i32) + i32::abs(*b as i32 - y as i32)) as u16;
area[x][y] = match area[x][y] { *cell = match *cell {
None => Single(d, (*a, *b)), None => Single(d, (*a, *b)),
Single(dd, (aa, bb)) => { Single(dd, (aa, bb)) => match dd.cmp(&d) {
if dd < d { Less => Single(dd, (aa, bb)),
Single(dd, (aa, bb)) Equal => Single(d, (*a, *b)),
} else if dd > d { Greater => Multi(d),
Single(d, (*a, *b)) },
} else {
// equal
Multi(d)
}
}
Multi(dd) => { Multi(dd) => {
if d < dd { if d < dd {
Single(d, (*a, *b)) Single(d, (*a, *b))
@@ -60,18 +58,15 @@ pub fn task1() {
.map(|(_, (a, b))| { .map(|(_, (a, b))| {
let count = area let count = area
.iter() .iter()
.flat_map(|v| v) .flatten()
.filter(|entry| { .filter(|entry| {
if let Single(_, (x, y)) = entry { if let Single(_, (x, y)) = entry {
if a == x && b == y { a == x && b == y
true
} else { } else {
false false
} }
} else { })
false .count();
}
}).count();
let infinite = area[0].iter().any(|bla| bla.belongs_to_point(*a, *b)) let infinite = area[0].iter().any(|bla| bla.belongs_to_point(*a, *b))
|| area[area.len() - 1] || area[area.len() - 1]
.iter() .iter()
@@ -82,7 +77,8 @@ pub fn task1() {
.any(|line| line[line.len() - 1].belongs_to_point(*a, *b)); .any(|line| line[line.len() - 1].belongs_to_point(*a, *b));
// println!("{} has size {} (infinite: {:?})", i, count, infinite); // println!("{} has size {} (infinite: {:?})", i, count, infinite);
(count, infinite) (count, infinite)
}).collect::<Vec<_>>(); })
.collect::<Vec<_>>();
println!( println!(
"Overall occupation: {} of {}", "Overall occupation: {} of {}",
@@ -127,7 +123,8 @@ pub fn task2() {
split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(),
split.next().unwrap().parse().unwrap(), split.next().unwrap().parse().unwrap(),
) )
}).collect(); })
.collect();
let max_x = coordinates.iter().max_by_key(|it| it.0).unwrap().0; let max_x = coordinates.iter().max_by_key(|it| it.0).unwrap().0;
let max_y = coordinates.iter().max_by_key(|it| it.1).unwrap().1; let max_y = coordinates.iter().max_by_key(|it| it.1).unwrap().1;
@@ -141,10 +138,13 @@ pub fn task2() {
.map(|(a, b)| { .map(|(a, b)| {
(i32::abs(*a as i32 - x as i32) + i32::abs(*b as i32 - y as i32)) (i32::abs(*a as i32 - x as i32) + i32::abs(*b as i32 - y as i32))
as usize as usize
}).sum::<usize>() })
}).filter(|it| *it < 10000) .sum::<usize>()
})
.filter(|it| *it < 10000)
.count() .count()
}).sum(); })
.sum();
println!("Part 2: {}", result); println!("Part 2: {}", result);
} }

View File

@@ -18,13 +18,12 @@ pub fn task1() {
let mut open: HashSet<char> = tasks let mut open: HashSet<char> = tasks
.iter() .iter()
.filter(|task| !depends_on.contains_key(task)) .filter(|task| !depends_on.contains_key(task)).copied()
.map(|c| *c)
.collect(); .collect();
let mut result = String::new(); let mut result = String::new();
while open.len() > 0 { while !open.is_empty() {
let next = open.iter().min().unwrap().clone(); let next = *open.iter().min().unwrap();
open.remove(&next); open.remove(&next);
result.push(next); result.push(next);
let newly_open: HashSet<char> = depends_on let newly_open: HashSet<char> = depends_on
@@ -32,7 +31,7 @@ pub fn task1() {
.filter(|(_task, deps)| deps.iter().all(|dep| result.chars().any(|c| c == *dep))) .filter(|(_task, deps)| deps.iter().all(|dep| result.chars().any(|c| c == *dep)))
.map(|(task, _)| *task) .map(|(task, _)| *task)
.collect(); .collect();
open = open.union(&newly_open).map(|c| *c).collect(); open = open.union(&newly_open).copied().collect();
for c in newly_open { for c in newly_open {
depends_on.remove(&c); depends_on.remove(&c);
} }

View File

@@ -2,7 +2,7 @@ use crate::utils;
pub fn both() { pub fn both() {
let input: Vec<usize> = utils::read_file("input/day08.txt") let input: Vec<usize> = utils::read_file("input/day08.txt")
.split(" ") .split(' ')
.map(|x| x.parse().unwrap()) .map(|x| x.parse().unwrap())
.collect(); .collect();
@@ -23,13 +23,13 @@ impl Node {
let num_meta: usize = input[1]; let num_meta: usize = input[1];
let mut children = Vec::new(); let mut children = Vec::new();
while num_children > 0 { while num_children > 0 {
let (node, rest) = Node::extract_from(&rest_input); let (node, rest) = Node::extract_from(rest_input);
children.push(node); children.push(node);
rest_input = rest; rest_input = rest;
num_children -= 1; num_children -= 1;
} }
let metadata = rest_input[..num_meta].iter().map(|x| *x).collect(); let metadata = rest_input[..num_meta].to_vec();
(Node { metadata, children }, &rest_input[num_meta..]) (Node { metadata, children }, &rest_input[num_meta..])
} }
@@ -39,14 +39,14 @@ impl Node {
.children .children
.iter() .iter()
.map(|child| { .map(|child| {
let s: usize = child.metadata_sum().clone(); let s: usize = child.metadata_sum();
s s
}) })
.sum::<usize>() .sum::<usize>()
} }
fn task2(&self) -> usize { fn task2(&self) -> usize {
if self.children.len() > 0 { if !self.children.is_empty() {
self.metadata self.metadata
.iter() .iter()
.map(|meta| match self.children.get(*meta - 1) { .map(|meta| match self.children.get(*meta - 1) {

View File

@@ -30,7 +30,7 @@ pub fn task1() {
let mut time = 0; let mut time = 0;
loop { loop {
time += 1; time += 1;
let new_lights = lights.iter().map(|light| light.move_copy()).collect(); let new_lights: Vec<Light> = lights.iter().map(|light| light.move_copy()).collect();
// print_lights(&new_lights); // print_lights(&new_lights);
let new_area = get_area(&new_lights); let new_area = get_area(&new_lights);
// println!("Area: {} ", new_area); // println!("Area: {} ", new_area);
@@ -45,7 +45,7 @@ pub fn task1() {
print_lights(&lights); print_lights(&lights);
} }
fn get_area(lights: &Vec<Light>) -> usize { fn get_area(lights: &[Light]) -> usize {
let xmin = lights.iter().map(|it| it.x).min().unwrap(); let xmin = lights.iter().map(|it| it.x).min().unwrap();
let xmax = lights.iter().map(|it| it.x).max().unwrap(); let xmax = lights.iter().map(|it| it.x).max().unwrap();
let ymin = lights.iter().map(|it| it.y).min().unwrap(); let ymin = lights.iter().map(|it| it.y).min().unwrap();
@@ -53,7 +53,7 @@ fn get_area(lights: &Vec<Light>) -> usize {
(xmax - xmin) as usize * (ymax - ymin) as usize (xmax - xmin) as usize * (ymax - ymin) as usize
} }
fn print_lights(lights: &Vec<Light>) { fn print_lights(lights: &[Light]) {
let xmin = lights.iter().map(|it| it.x).min().unwrap(); let xmin = lights.iter().map(|it| it.x).min().unwrap();
let xmax = lights.iter().map(|it| it.x).max().unwrap(); let xmax = lights.iter().map(|it| it.x).max().unwrap();
let ymin = lights.iter().map(|it| it.y).min().unwrap(); let ymin = lights.iter().map(|it| it.y).min().unwrap();
@@ -64,14 +64,12 @@ fn print_lights(lights: &Vec<Light>) {
let mut screen: Vec<Vec<u8>> = Vec::with_capacity(height as usize); let mut screen: Vec<Vec<u8>> = Vec::with_capacity(height as usize);
for _ in 0..=height { for _ in 0..=height {
let mut chars = Vec::with_capacity(width as usize); let mut chars = Vec::with_capacity(width as usize);
for _ in 0..=width { chars.resize(width as usize + 1, b'.');
chars.push('.' as u8);
}
screen.push(chars); screen.push(chars);
} }
lights lights
.iter() .iter()
.for_each(|light| screen[(light.y - ymin) as usize][(light.x - xmin) as usize] = '#' as u8); .for_each(|light| screen[(light.y - ymin) as usize][(light.x - xmin) as usize] = b'#');
for line in screen.iter() { for line in screen.iter() {
println!("{}", String::from_utf8(line.clone()).unwrap()); println!("{}", String::from_utf8(line.clone()).unwrap());
} }

View File

@@ -56,9 +56,9 @@ pub fn task2_fast() {
let serial = 6392; let serial = 6392;
let mut cache: Vec<Vec<i32>> = Vec::with_capacity(301); let mut cache: Vec<Vec<i32>> = Vec::with_capacity(301);
for x in 0 as usize..=300 { for x in 0_usize..=300 {
let mut v: Vec<i32> = Vec::with_capacity(301); let mut v: Vec<i32> = Vec::with_capacity(301);
for y in 0 as usize..=300 { for y in 0_usize..=300 {
if x == 0 || y == 0 { if x == 0 || y == 0 {
v.push(0); v.push(0);
} else { } else {
@@ -72,10 +72,10 @@ pub fn task2_fast() {
} }
let values = &cache; let values = &cache;
for x in 0 as usize..=300 { for x in 0_usize..=300 {
for y in 0 as usize..=300 { for y in 0_usize..=300 {
if x != 0 && y != 0 { if x != 0 && y != 0 {
let cached = area_sum(&values, x, y, 1); let cached = area_sum(values, x, y, 1);
let calc = fuel_level(x as i32, y as i32, serial); let calc = fuel_level(x as i32, y as i32, serial);
//println!("{},{}: {} ({})", x, y, values[x][y], calc); //println!("{},{}: {} ({})", x, y, values[x][y], calc);
assert_eq!(calc, cached); assert_eq!(calc, cached);
@@ -87,7 +87,7 @@ pub fn task2_fast() {
.map(|square_size| { .map(|square_size| {
let result = (1..=301 - square_size) let result = (1..=301 - square_size)
.flat_map(|x: usize| (1..=301 - square_size).map(move |y: usize| (x, y))) .flat_map(|x: usize| (1..=301 - square_size).map(move |y: usize| (x, y)))
.map(|(x, y)| (x, y, area_sum(&values, x, y, square_size))) .map(|(x, y)| (x, y, area_sum(values, x, y, square_size)))
.max_by_key(|(_, _, value)| *value) .max_by_key(|(_, _, value)| *value)
.unwrap(); .unwrap();
(result.0, result.1, result.2, square_size) (result.0, result.1, result.2, square_size)
@@ -96,7 +96,7 @@ pub fn task2_fast() {
println!("{:?}", result); println!("{:?}", result);
} }
fn area_sum(values: &Vec<Vec<i32>>, x: usize, y: usize, length: usize) -> i32 { fn area_sum(values: &[Vec<i32>], x: usize, y: usize, length: usize) -> i32 {
values[x + length - 1][y + length - 1] + values[x - 1][y - 1] values[x + length - 1][y + length - 1] + values[x - 1][y - 1]
- values[x - 1][y + length - 1] - values[x - 1][y + length - 1]
- values[x + length - 1][y - 1] - values[x + length - 1][y - 1]
@@ -108,7 +108,7 @@ fn fuel_level(x: i32, y: i32, serial: i32) -> i32 {
power += serial; power += serial;
power *= rack_id; power *= rack_id;
power = power / 100 % 10; power = power / 100 % 10;
power = power - 5; power -= 5;
power power
} }

View File

@@ -18,7 +18,7 @@ pub fn task1() {
input.next(); input.next();
for line in input { for line in input {
let key = line.split(" => ").nth(0).unwrap(); let key = line.split(" => ").next().unwrap();
transformations.insert(key.to_string(), line.chars().last().unwrap()); transformations.insert(key.to_string(), line.chars().last().unwrap());
} }

View File

@@ -24,8 +24,7 @@ fn read_input() -> (Vec<Vec<char>>, Vec<Cart>) {
for (x, c) in line.chars().enumerate() { for (x, c) in line.chars().enumerate() {
if tiles.contains(&c) { if tiles.contains(&c) {
map[x][y] = c; map[x][y] = c;
} else { } else if c != ' ' {
if c != ' ' {
map[x][y] = match c { map[x][y] = match c {
'>' => '-', '>' => '-',
'<' => '-', '<' => '-',
@@ -43,7 +42,6 @@ fn read_input() -> (Vec<Vec<char>>, Vec<Cart>) {
} }
} }
} }
}
(map, carts) (map, carts)
} }
@@ -57,7 +55,7 @@ struct Cart {
active: bool, active: bool,
} }
fn perform_round(map: &Vec<Vec<char>>, carts: &mut Vec<Cart>) { fn perform_round(map: &[Vec<char>], carts: &mut Vec<Cart>) {
carts.sort_unstable_by(|a, b| { carts.sort_unstable_by(|a, b| {
if a.y == b.y { if a.y == b.y {
a.x.cmp(&b.x) a.x.cmp(&b.x)

View File

@@ -19,7 +19,7 @@ pub fn task1() {
println!("Final full round was {}", round); println!("Final full round was {}", round);
println!( println!(
"Result: {}", "Result: {}",
game.units.iter().map(|it| it.health).sum::<i32>() * round as i32 game.units.iter().map(|it| it.health).sum::<i32>() * round
); );
} }
@@ -56,7 +56,7 @@ pub fn task2() {
} }
println!( println!(
"Result: {}", "Result: {}",
game.units.iter().map(|it| it.health).sum::<i32>() * round as i32 game.units.iter().map(|it| it.health).sum::<i32>() * round
); );
} }
println!("Searching stopped with lowest win {:?}", lowest_win); // 7169 too low println!("Searching stopped with lowest win {:?}", lowest_win); // 7169 too low
@@ -158,7 +158,7 @@ impl Game {
from: Position, from: Position,
target_type: WarriorType, target_type: WarriorType,
) -> Option<Position> { ) -> Option<Position> {
let mut map = Map::from_game(&self, from); let mut map = Map::from_game(self, from);
for unit in self.units.iter() { for unit in self.units.iter() {
if unit.warrior_type == target_type { if unit.warrior_type == target_type {
@@ -199,13 +199,8 @@ impl Game {
// } else { // } else {
// None // None
// } // }
let map = Map::from_game(&self, from); let map = Map::from_game(self, from);
if let Some(path) = map.shortest_path(from, to) { map.shortest_path(from, to).map(|path| *path.get(1).unwrap_or(&from))
// println!("{:?}", path);
Some(*path.get(1).unwrap_or(&from))
} else {
None
}
} }
/// 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
@@ -284,7 +279,7 @@ impl Game {
} }
curr += 1; curr += 1;
} }
return true; true
} }
fn from_input(input: &Vec<&str>, goblin_attack: i32, elve_attack: i32) -> Self { fn from_input(input: &Vec<&str>, goblin_attack: i32, elve_attack: i32) -> Self {
@@ -354,7 +349,7 @@ impl Display for Game {
} }
} }
f.write_str(&line)?; f.write_str(&line)?;
f.write_str(&"\n")?; f.write_str("\n")?;
} }
Ok(()) Ok(())
} }
@@ -387,7 +382,7 @@ impl Display for Map {
}); });
} }
f.write_str(&line)?; f.write_str(&line)?;
f.write_str(&"\n")?; f.write_str("\n")?;
} }
Ok(()) Ok(())
} }
@@ -411,7 +406,7 @@ impl Map {
} }
fields[clear.0][clear.1] = MapTile::Empty; fields[clear.0][clear.1] = MapTile::Empty;
Map { Map {
fields: fields, fields,
width: game.width, width: game.width,
height: game.height, height: game.height,
} }
@@ -487,10 +482,6 @@ impl Map {
} }
candidates.sort_unstable(); candidates.sort_unstable();
if let Some(x) = candidates.first() { candidates.first().copied()
Some(*x)
} else {
None
}
} }
} }

View File

@@ -10,7 +10,7 @@ pub fn task1() {
let input = &input[1..]; let input = &input[1..];
let mut map: HashMap<Point, Tile> = HashMap::new(); let mut map: HashMap<Point, Tile> = HashMap::new();
add_default_neighbors_for_room(&mut map, Point(0, 0)); add_default_neighbors_for_room(&mut map, Point(0, 0));
parse_input(&mut map, &input, Point(0, 0)); parse_input(&mut map, input, Point(0, 0));
// print_map(&map); // print_map(&map);
@@ -33,14 +33,14 @@ fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) ->
} }
let mut position = position; let mut position = position;
let mut input = input; let mut input = input;
let mut iterator = input.chars(); let iterator = input.chars();
while let Some(c) = iterator.next() { for c in iterator {
match c { match c {
'(' => { '(' => {
let (parts, rest) = split_parts(&input); let (parts, rest) = split_parts(input);
let mut middle_points: HashSet<Point> = HashSet::new(); let mut middle_points: HashSet<Point> = HashSet::new();
for part in parts { for part in parts {
if part.len() > 0 { if !part.is_empty() {
for x in parse_input(map, part, position) { for x in parse_input(map, part, position) {
middle_points.insert(x); middle_points.insert(x);
} }
@@ -48,7 +48,7 @@ fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) ->
} }
let mut end_points: HashSet<Point> = HashSet::new(); let mut end_points: HashSet<Point> = HashSet::new();
for point in middle_points { for point in middle_points {
if rest.len() > 0 { if !rest.is_empty() {
for x in parse_input(map, rest, point) { for x in parse_input(map, rest, point) {
end_points.insert(x); end_points.insert(x);
} }
@@ -122,7 +122,7 @@ fn split_parts(input: &str) -> (Vec<&str>, &str) {
} }
} }
let closing_index = let closing_index =
closing_index.expect(&format!("No matching closing parenthesis in {}", input)); closing_index.unwrap_or_else(|| panic!("No matching closing parenthesis in {}", input));
(parts, &input[closing_index + 1..]) (parts, &input[closing_index + 1..])
} }
@@ -132,9 +132,7 @@ fn add_default_neighbors_for_room(map: &mut HashMap<Point, Tile>, position: Poin
map.insert(p, Wall); map.insert(p, Wall);
} }
for p in position.neighbors() { for p in position.neighbors() {
if !map.contains_key(&p) { map.entry(p).or_insert(Unknown);
map.insert(p, Unknown);
}
} }
} }

View File

@@ -60,7 +60,7 @@ impl Cave {
fn erosion_index(&mut self, x: usize, y: usize) -> usize { fn erosion_index(&mut self, x: usize, y: usize) -> usize {
if let Some(value) = self.map.get(&(x, y)) { if let Some(value) = self.map.get(&(x, y)) {
return *value; *value
} else { } else {
let geo_index = match (x, y) { let geo_index = match (x, y) {
(0, 0) => 0, (0, 0) => 0,
@@ -71,7 +71,7 @@ impl Cave {
}; };
let erosion_index = (geo_index + self.depth) % 20183; let erosion_index = (geo_index + self.depth) % 20183;
self.map.insert((x, y), erosion_index); self.map.insert((x, y), erosion_index);
return erosion_index; erosion_index
} }
} }
@@ -166,7 +166,7 @@ impl Cave {
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, cost: 1,
node: node, node,
}) })
} }
}); });

View File

@@ -80,7 +80,7 @@ pub fn task2() {
} else { } else {
for child in cube.children() { for child in cube.children() {
heap.push(Candidate { heap.push(Candidate {
count: bots.iter().filter(|bot| child.intersects(&bot)).count(), count: bots.iter().filter(|bot| child.intersects(bot)).count(),
cube: child, cube: child,
}) })
} }
@@ -96,7 +96,7 @@ pub fn task2() {
let best = candidate_points let best = candidate_points
.iter() .iter()
.filter(|(_, count)| *count == best_candidate_count) .filter(|(_, count)| *count == best_candidate_count)
.min_by_key(|(point, _)| origin.distance(&point)); .min_by_key(|(point, _)| origin.distance(point));
println!("{:?}", best); println!("{:?}", best);
if let Some((best, _)) = best { if let Some((best, _)) = best {
@@ -136,7 +136,7 @@ impl Bot {
} }
fn dist(&self, p: &Point) -> isize { fn dist(&self, p: &Point) -> isize {
self.center.distance(&p) self.center.distance(p)
} }
} }

View File

@@ -3,7 +3,7 @@ use std::cmp::Reverse;
use std::collections::HashMap; use std::collections::HashMap;
pub fn task1() { pub fn task1() {
let input = "Immune System: let _input = "Immune System:
17 units each with 5390 hit points (weak to radiation, bludgeoning) with an attack that does 4507 fire damage at initiative 2 17 units each with 5390 hit points (weak to radiation, bludgeoning) with an attack that does 4507 fire damage at initiative 2
989 units each with 1274 hit points (immune to fire; weak to bludgeoning, slashing) with an attack that does 25 slashing damage at initiative 3 989 units each with 1274 hit points (immune to fire; weak to bludgeoning, slashing) with an attack that does 25 slashing damage at initiative 3
@@ -41,7 +41,7 @@ Infection:
println!( println!(
"Standing units after the game: {}", "Standing units after the game: {}",
game.groups.iter().map(|(_, it)| it.units).sum::<i64>() game.groups.values().map(|it| it.units).sum::<i64>()
); );
// 21107 too high // 21107 too high
@@ -79,7 +79,7 @@ impl Game {
fn round(&mut self) { fn round(&mut self) {
let mut target: HashMap<usize, usize> = HashMap::new(); let mut target: HashMap<usize, usize> = HashMap::new();
// lock targets ordered by effective power // lock targets ordered by effective power
let mut all_by_power: Vec<&Group> = self.groups.iter().map(|(_, it)| it).collect(); let mut all_by_power: Vec<&Group> = self.groups.values().collect();
all_by_power.sort_unstable_by_key(|a| Reverse((a.effective_power(), a.initiative))); all_by_power.sort_unstable_by_key(|a| Reverse((a.effective_power(), a.initiative)));
// for group in all_by_power.iter() { // for group in all_by_power.iter() {
// println!( // println!(
@@ -93,8 +93,7 @@ impl Game {
for group in all_by_power.iter() { for group in all_by_power.iter() {
if let Some(t) = self if let Some(t) = self
.groups .groups
.iter() .values()
.map(|(_, it)| it)
.filter(|it| it.team != group.team) .filter(|it| it.team != group.team)
.filter(|it| !target.values().any(|t| *t == it.id)) .filter(|it| !target.values().any(|t| *t == it.id))
// .filter(|it| group.compute_attack_damage_to(&it) >= it.hp_each) // .filter(|it| group.compute_attack_damage_to(&it) >= it.hp_each)
@@ -108,13 +107,13 @@ impl Game {
// }) // })
.max_by_key(|it| { .max_by_key(|it| {
( (
group.compute_attack_damage_to(&it), group.compute_attack_damage_to(it),
it.effective_power(), it.effective_power(),
it.initiative, it.initiative,
) )
}) })
{ {
if group.compute_attack_damage_to(&t) <= 0 { if group.compute_attack_damage_to(t) <= 0 {
println!( println!(
"Didn't find a target where {:?} can deal positive damage.", "Didn't find a target where {:?} can deal positive damage.",
group group
@@ -127,8 +126,7 @@ impl Game {
} }
// attack ordered by initiative // attack ordered by initiative
let mut all_ids_by_initiative: Vec<usize> = let mut all_ids_by_initiative: Vec<usize> = self.groups.values().map(|it| it.id).collect();
self.groups.iter().map(|(_, it)| it.id).collect();
all_ids_by_initiative.sort_unstable_by_key(|id| Reverse(self.groups[id].initiative)); all_ids_by_initiative.sort_unstable_by_key(|id| Reverse(self.groups[id].initiative));
for active_id in all_ids_by_initiative { for active_id in all_ids_by_initiative {
@@ -139,7 +137,7 @@ impl Game {
} }
if let Some(enemy_id) = target.get(&active_id) { if let Some(enemy_id) = target.get(&active_id) {
let enemy = &self.groups[enemy_id]; let enemy = &self.groups[enemy_id];
let damage: i64 = self.groups[&active_id].compute_attack_damage_to(&enemy); let damage: i64 = self.groups[&active_id].compute_attack_damage_to(enemy);
let dying_units = damage / enemy.hp_each; let dying_units = damage / enemy.hp_each;
if let Some(enemy) = self.groups.get_mut(enemy_id) { if let Some(enemy) = self.groups.get_mut(enemy_id) {
enemy.units -= dying_units; enemy.units -= dying_units;
@@ -157,7 +155,7 @@ impl Game {
} }
fn is_over(&self) -> bool { fn is_over(&self) -> bool {
self.groups.len() == 0 self.groups.is_empty()
|| self.groups.iter().all(|(_, it)| it.team == Team::Infection) || self.groups.iter().all(|(_, it)| it.team == Team::Infection)
|| self || self
.groups .groups
@@ -199,10 +197,10 @@ impl Group {
let mut weaknesses: Vec<String> = Vec::new(); let mut weaknesses: Vec<String> = Vec::new();
let mut immunities: Vec<String> = Vec::new(); let mut immunities: Vec<String> = Vec::new();
for part in m[3].split("; ") { for part in m[3].split("; ") {
if part.starts_with("weak to ") { if let Some(stripped) = part.strip_prefix("weak to ") {
weaknesses = part[8..].split(", ").map(|it| it.to_string()).collect(); weaknesses = stripped.split(", ").map(|it| it.to_string()).collect();
} else if part.starts_with("immune to ") { } else if let Some(stripped) = part.strip_prefix("immune to ") {
immunities = part[10..].split(", ").map(|it| it.to_string()).collect(); immunities = stripped.split(", ").map(|it| it.to_string()).collect();
} }
} }

View File

@@ -2,7 +2,7 @@ use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
pub fn read_file(path: &str) -> String { pub fn read_file(path: &str) -> String {
let mut f = File::open(path).expect(&format!("file '{}' not found", path)); let mut f = File::open(path).unwrap_or_else(|_| panic!("file '{}' not found", path));
let mut contents = String::new(); let mut contents = String::new();
f.read_to_string(&mut contents) f.read_to_string(&mut contents)