pub fn task1() { let square_size = 3; let serial = 6392; let result = (1..=300 - square_size) .flat_map(|x: i32| (1..=300 - square_size).map(move |y: i32| (x, y))) .map(|(x, y)| { let power: i32 = (x..x + square_size) .map(|x| { (y..y + square_size) .map(move |y| fuel_level(x, y, serial)) .sum::() }) .sum(); (x, y, power) }) .max_by_key(|(_, _, value)| *value); println!("{:?}", result); } pub fn task2() { let serial = 6392; let mut values: Vec> = Vec::with_capacity(301); for x in 0..=300 { let mut v: Vec = Vec::with_capacity(301); for y in 0..=300 { v.push(fuel_level(x, y, serial)); } values.push(v); } let values = &values; let result = (1..300) .map(|square_size| { let result = (1..=300 - square_size) .flat_map(|x: i32| (1..=300 - square_size).map(move |y: i32| (x, y))) .map(|(x, y)| { let power: i32 = (x..x + square_size) .map(|x| { (y..y + square_size) .map(move |y| values[x as usize][y as usize]) .sum::() }) .sum(); (x, y, power) }) .max_by_key(|(_, _, value)| *value) .unwrap(); (result.0, result.1, result.2, square_size) }) .max_by_key(|result| result.2); println!("{:?}", result); } pub fn task2_fast() { let serial = 6392; let mut cache: Vec> = Vec::with_capacity(301); for x in 0_usize..=300 { let mut v: Vec = Vec::with_capacity(301); for y in 0_usize..=300 { if x == 0 || y == 0 { v.push(0); } else { v.push( fuel_level(x as i32, y as i32, serial) + v[v.len() - 1] + cache[x - 1][y] - cache[x - 1][y - 1], ) } } cache.push(v); } let values = &cache; for x in 0_usize..=300 { for y in 0_usize..=300 { if x != 0 && y != 0 { let cached = area_sum(values, x, y, 1); let calc = fuel_level(x as i32, y as i32, serial); //println!("{},{}: {} ({})", x, y, values[x][y], calc); assert_eq!(calc, cached); } } } let result = (1..=300) .map(|square_size| { let result = (1..=301 - square_size) .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))) .max_by_key(|(_, _, value)| *value) .unwrap(); (result.0, result.1, result.2, square_size) }) .max_by_key(|result| result.2); println!("{:?}", result); } fn area_sum(values: &[Vec], x: usize, y: usize, length: usize) -> i32 { values[x + length - 1][y + length - 1] + values[x - 1][y - 1] - values[x - 1][y + length - 1] - values[x + length - 1][y - 1] } fn fuel_level(x: i32, y: i32, serial: i32) -> i32 { let rack_id = x + 10; let mut power = rack_id * y; power += serial; power *= rack_id; power = power / 100 % 10; power -= 5; power } mod test { #[test] fn name() { use super::fuel_level; assert_eq!(fuel_level(3, 5, 8), 4); assert_eq!(fuel_level(122, 79, 57), -5); assert_eq!(fuel_level(217, 196, 39), 0); assert_eq!(fuel_level(101, 153, 71), 4); } }