First 2 days and a half

This commit is contained in:
Vladan Popovic 2019-12-11 23:34:00 +01:00
parent 812bc86697
commit f22ef7f7ba
7 changed files with 245 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
target
*-input.txt

6
Cargo.lock generated Normal file
View File

@ -0,0 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aoc"
version = "0.1.0"

9
Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "aoc"
version = "0.1.0"
authors = ["Vladan Popovic <vladan.popovic@ericsson.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

29
src/day_one.rs Normal file
View File

@ -0,0 +1,29 @@
fn fuel_for(mass: u64) -> u64 {
(mass / 3).saturating_sub(2)
}
fn total_fuel(mass: u64) -> u64 {
std::iter::successors(Some(fuel_for(mass)), |&fuel| Some(fuel_for(fuel)))
.take_while(|&fuel| fuel > 0)
.sum()
}
pub fn main(masses: Vec<u64>) {
let total: u64 = masses.into_iter().map(total_fuel).sum();
println!("Fuel needed for bringing Santa home is: {}", total);
}
#[test]
fn test_part1() {
assert_eq!(fuel_for(12), 2);
assert_eq!(fuel_for(14), 2);
assert_eq!(fuel_for(1969), 654);
assert_eq!(fuel_for(100756), 33583);
}
#[test]
fn test_part2() {
assert_eq!(total_fuel(14), 2);
assert_eq!(total_fuel(1969), 966);
assert_eq!(total_fuel(100756), 50346);
}

82
src/day_three.rs Normal file
View File

@ -0,0 +1,82 @@
use std::collections::BTreeSet;
use std::fs::File;
use std::io::{self, BufRead, BufReader};
use std::iter::{repeat, successors};
fn next(c: (i32, i32), direction: &str) -> (i32, i32) {
match direction {
"R" => (c.0 + 1, c.1),
"L" => (c.0 - 1, c.1),
"U" => (c.0, c.1 + 1),
"D" => (c.0, c.1 - 1),
_ => panic!("Wrong direction format!"),
}
}
fn direction_length(entry: String) -> (String, usize) {
/// Creates a (direction, length) pair to later produce a string
/// on a direction with the given length. E.g. given "R10" the output of
(
entry.chars().nth(0).unwrap().to_string(),
entry[1..].parse().unwrap(),
)
}
fn to_coordinates(entries: Vec<String>) -> BTreeSet<(i32, i32)> {
let mut wire = BTreeSet::new();
let mut it = entries
.into_iter()
.map(direction_length)
.flat_map(|(direction, length)| repeat(direction).take(length));
successors(
it.next()
.map(|direction| (next((0, 0), direction.as_ref()))),
|c| it.next().map(|direction| (next(*c, direction.as_ref()))),
)
.for_each(|c| {
wire.insert(c);
});
wire
}
fn distance(position: (i32, i32)) -> i32 {
position.0.abs() + position.1.abs()
}
pub fn main() -> io::Result<()> {
let f = BufReader::new(File::open("day3-input.txt")?);
let entries: Vec<BTreeSet<(i32, i32)>> = f
.lines()
.map(|line| line.unwrap().split(",").map(String::from).collect())
.map(to_coordinates)
.collect();
let closest: Option<i32> = entries[0]
.intersection(&entries[1])
.cloned()
.map(distance)
.min();
println!("{:?}", closest);
Ok(())
}
#[test]
fn test_coordinates_for_entry() {
let mut expected: BTreeSet<(i32, i32)> = BTreeSet::new();
for i in 1..11 {
expected.insert((i, 0));
}
assert_eq!(to_coordinates(vec!["R10".to_owned()]), expected);
expected = BTreeSet::new();
expected.insert((1, 0));
expected.insert((2, 0));
expected.insert((2, 1));
expected.insert((2, 2));
let input = "R2,U2".to_owned().split(",").map(String::from).collect();
assert_eq!(to_coordinates(input), expected);
}

95
src/day_two.rs Normal file
View File

@ -0,0 +1,95 @@
use std;
fn compute_intcode(p: &mut Vec<usize>) -> Vec<usize> {
for idx in (0..(p.len())).step_by(4) {
match p[idx] {
1 => {
let left = p[idx + 1];
let right = p[idx + 2];
let res = p[idx + 3];
p[res] = p[left] + p[right];
}
2 => {
let left = p[idx + 1];
let right = p[idx + 2];
let res = p[idx + 3];
p[res] = p[left] * p[right];
}
99 => break,
_ => panic!("Something went wrong!"),
}
}
p.to_vec()
}
pub fn part_one() {
let mut input: Vec<usize> = std::include_str!("../day2-input.txt")
.trim()
.split(",")
.map(|x| x.parse().unwrap())
.collect();
input[1] = 12;
input[2] = 2;
println!("Intcode [0] is: {}", compute_intcode(&mut input)[0]);
}
pub fn part_two() {
let mut input: Vec<usize> = std::include_str!("../day2-input.txt")
.trim()
.split(",")
.map(|x| x.parse().unwrap())
.collect();
input[1] = 0;
input[2] = 0;
let lookup_num = 19690720;
let mut found = false;
for i in 0..99 {
input[1] = i;
for j in 0..99 {
input[2] = j;
let mut input_guess = input.clone();
let computed = compute_intcode(&mut input_guess);
found = computed[0] == lookup_num;
if found {
let (noun, verb) = (computed[1], computed[2]);
println!(
"100 * noun({}) + verb({}) = {}",
noun,
verb,
100 * noun + verb
);
break;
}
}
if found {
break;
}
}
}
#[test]
fn test_part_one() {
assert_eq!(
compute_intcode(&mut vec!(1, 0, 0, 0, 99)),
vec!(2, 0, 0, 0, 99)
);
assert_eq!(
compute_intcode(&mut vec!(2, 3, 0, 3, 99)),
vec!(2, 3, 0, 6, 99)
);
assert_eq!(
compute_intcode(&mut vec!(2, 4, 4, 5, 99, 0)),
vec!(2, 4, 4, 5, 99, 9801)
);
assert_eq!(
compute_intcode(&mut vec!(1, 1, 1, 4, 99, 5, 6, 0, 99)),
vec!(30, 1, 1, 4, 2, 5, 6, 0, 99)
);
}

22
src/main.rs Normal file
View File

@ -0,0 +1,22 @@
mod day_one;
mod day_three;
mod day_two;
use std::fs::File;
use std::io::{self, BufRead, BufReader};
fn main() -> io::Result<()> {
let f = BufReader::new(File::open("day1-input.txt")?);
let masses: Vec<u64> = f
.lines()
.map(|line| line.unwrap().parse().unwrap())
.collect();
day_one::main(masses);
day_two::part_one();
day_two::part_two();
day_three::main()?;
Ok(())
}