Compare commits

..

1 commit

Author SHA1 Message Date
9d1d057e09 Refactor to struct and enumerate steps 2019-12-15 23:18:00 +01:00
9 changed files with 40 additions and 579 deletions

View file

@ -1,3 +0,0 @@
(setenv "RUSTFLAGS"
(concat (getenv "RUSTFLAGS")
"-A dead_code"))

View file

@ -1,64 +0,0 @@
use std::io;
fn part1(x: &u32) -> bool {
let matching = x
.to_string()
.chars()
.map(|c| c.to_digit(10).unwrap())
.fold((true, false, 0), |acc, next| {
(acc.0 && next >= acc.2, acc.1 || next == acc.2, next)
});
matching.0 && matching.1
}
fn part2(x: &u32) -> bool {
let matching = x.to_string().chars().map(|c| c.to_digit(10).unwrap()).fold(
(true, false, 0, 0),
|acc, next| {
if next == acc.3 && acc.2 >= 2 {
(acc.0 && next >= acc.3, acc.1, acc.2 + 1, next)
} else if next != acc.3 && acc.2 == 2 {
(acc.0 && next >= acc.3, true, 1, next)
} else if next == acc.3 && acc.2 < 2 {
(acc.0 && next >= acc.3, acc.1, acc.2 + 1, next)
} else {
(acc.0 && next >= acc.3, acc.1, 1, next)
}
},
);
matching.0 && (matching.1 || matching.2 == 2)
}
pub fn main() -> io::Result<()> {
let input = "123257-647015";
let range: Vec<u32> = input
.split("-")
.map(|x| x.parse::<u32>().unwrap())
.take(2)
.collect();
println!("part1 = {}", (range[0]..range[1]).filter(part1).count());
println!("part2 = {}", (range[0]..range[1]).filter(part2).count());
Ok(())
}
#[test]
fn test_part1() {
assert!(part1(&111111));
assert!(!part1(&223450));
assert!(!part1(&123789));
}
#[test]
fn test_part2() {
assert!(!part2(&111111));
assert!(!part2(&223450));
assert!(!part2(&123789));
assert!(part2(&112233));
assert!(part2(&223334));
assert!(!part2(&123444));
assert!(part2(&111122));
}

View file

@ -1,244 +0,0 @@
use std;
use std::convert::TryInto;
fn get_modes(x: i32) -> (i32, i32, i32, i32) {
(
x as i32 % 100,
(x as i32 / 100) % 10,
(x as i32 / 1000) % 10,
x as i32 / 10000,
)
}
fn get_param(input: Vec<i32>, mode: i32, idx: usize) -> i32 {
match mode {
0 => {
let new_idx: usize = input[idx as usize].try_into().unwrap();
input[new_idx]
}
1 => input[idx],
_ => panic!("invalid input"),
}
}
fn set_param(input: &mut Vec<i32>, mode: i32, idx: i32, value: i32) -> () {
match mode {
0 => {
let new_idx: usize = input[idx as usize].try_into().unwrap();
input[new_idx] = value;
}
_ => {
panic!("invalid mode for output");
}
}
}
pub fn compute_intcode_extended(p: &mut Vec<i32>, inp: Vec<i32>) -> (Vec<i32>, Vec<i32>) {
let mut idx = 0;
let mut output: Vec<i32> = Vec::new();
let mut input = inp.into_iter();
while idx < p.len() - 1 {
let (opcode, m1, m2, m3) = get_modes(p[idx]);
match opcode {
1 => {
let left = get_param(p.to_vec(), m1, idx + 1);
let right = get_param(p.to_vec(), m2, idx + 2);
let res = left + right;
set_param(p, m3, idx as i32 + 3, res);
idx += 4;
}
2 => {
let left = get_param(p.to_vec(), m1, idx + 1);
let right = get_param(p.to_vec(), m2, idx + 2);
let res = left * right;
set_param(p, m3, idx as i32 + 3, res);
idx += 4;
}
3 => {
let new_idx: usize = p[idx as usize + 1].try_into().unwrap();
p[new_idx] = input.next().expect("no next input!");
idx += 2;
}
4 => {
let value = get_param(p.to_vec(), m1, idx + 1);
output.push(value);
idx += 2;
}
5 => {
let left = get_param(p.to_vec(), m1, idx + 1);
let right = get_param(p.to_vec(), m2, idx + 2);
if left != 0 {
idx = right as usize;
} else {
idx += 3;
}
}
6 => {
let left = get_param(p.to_vec(), m1, idx + 1);
let right = get_param(p.to_vec(), m2, idx + 2);
if left == 0 {
idx = right as usize;
} else {
idx += 3;
}
}
7 => {
let left = get_param(p.to_vec(), m1, idx + 1);
let right = get_param(p.to_vec(), m2, idx + 2);
set_param(p, m3, idx as i32 + 3, (left < right) as i32);
idx += 4;
}
8 => {
let left = get_param(p.to_vec(), m1, idx + 1);
let right = get_param(p.to_vec(), m2, idx + 2);
set_param(p, m3, idx as i32 + 3, (left == right) as i32);
idx += 4;
}
99 => {
break;
}
_ => panic!("invalid opcode: {}", opcode),
}
}
(p.to_vec(), output.to_vec())
}
pub fn main() -> std::io::Result<()> {
let input: Vec<i32> = std::include_str!("../day5-input.txt")
.trim()
.split(",")
.map(|x| x.parse().ok().expect(&format!("{} not a number", x)))
.collect();
let (_, output) = compute_intcode_extended(&mut input.clone(), vec![1]);
println!("part 1 = {}", output.last().unwrap());
let (_, output) = compute_intcode_extended(&mut input.clone(), vec![5]);
println!("part 2 = {}", output[0]);
Ok(())
}
#[test]
fn test_halt() {
let (result, _) = compute_intcode_extended(&mut vec![99], vec![1]);
assert_eq!(result, vec![99]);
}
#[test]
fn test_write_to_memory() {
let (result, _) = compute_intcode_extended(&mut vec![3, 3, 99, 0], vec![20]);
assert_eq!(20, result[3]);
}
#[test]
fn test_write_to_output() {
let (_, output) = compute_intcode_extended(&mut vec![4, 2, 99], vec![1]);
assert_eq!(99, output[0]);
}
#[test]
fn test_add() {
let (result, _) = compute_intcode_extended(&mut vec![1, 2, 2, 0, 99], vec![1]);
assert_eq!(4, result[0]);
}
#[test]
fn test_mul() {
let (result, _) = compute_intcode_extended(&mut vec![2, 2, 4, 0, 99], vec![1]);
assert_eq!(396, result[0]);
}
#[test]
fn test_immediate_mode() {
let (result, _) = compute_intcode_extended(&mut vec![1102, 2, 4, 0, 99], vec![1]);
assert_eq!(8, result[0]);
}
#[test]
fn test_position_mode_equal() {
let (_, output) =
compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], vec![8]);
assert_eq!(1, output[0]);
}
#[test]
fn test_position_mode_not_equal() {
let (_, output) =
compute_intcode_extended(&mut vec![3, 9, 8, 9, 10, 9, 4, 9, 99, -1, 8], vec![10]);
assert_eq!(0, output[0]);
}
#[test]
fn test_position_mode_less_than() {
let (_, output) =
compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], vec![3]);
assert_eq!(1, output[0]);
}
#[test]
fn test_position_mode_greater_than() {
let (_, output) =
compute_intcode_extended(&mut vec![3, 9, 7, 9, 10, 9, 4, 9, 99, -1, 8], vec![10]);
assert_eq!(0, output[0]);
}
#[test]
fn test_immediate_mode_equal() {
let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], vec![8]);
assert_eq!(1, output[0]);
}
#[test]
fn test_immediate_mode_not_equal() {
let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1108, -1, 8, 3, 4, 3, 99], vec![10]);
assert_eq!(0, output[0]);
}
#[test]
fn test_immediate_mode_less_than() {
let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], vec![3]);
assert_eq!(1, output[0]);
}
#[test]
fn test_immediate_mode_greater_than() {
let (_, output) = compute_intcode_extended(&mut vec![3, 3, 1107, -1, 8, 3, 4, 3, 99], vec![10]);
assert_eq!(0, output[0]);
}
#[test]
fn test_position_jump_zero() {
let (_, output) = compute_intcode_extended(
&mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
vec![0],
);
assert_eq!(0, output[0]);
}
#[test]
fn test_position_jump_one() {
let (_, output) = compute_intcode_extended(
&mut vec![3, 12, 6, 12, 15, 1, 13, 14, 13, 4, 13, 99, -1, 0, 1, 9],
vec![100],
);
assert_eq!(1, output[0]);
}
#[test]
fn test_immediate_jump_zero() {
let (_, output) = compute_intcode_extended(
&mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
vec![0],
);
assert_eq!(0, output[0]);
}
#[test]
fn test_immediate_jump_one() {
let (_, output) = compute_intcode_extended(
&mut vec![3, 3, 1105, -1, 9, 1101, 0, 0, 12, 4, 12, 99, 1],
vec![100],
);
assert_eq!(1, output[0]);
}

View file

@ -1,68 +0,0 @@
use std::collections::HashMap;
use std::iter::FromIterator;
fn create_orbit_map(input: &str) -> HashMap<String, String> {
let mut orbit_map: HashMap<String, String> = HashMap::new();
input
.lines()
.map(|line| line.split(")").map(String::from).collect())
.for_each(|pair: Vec<String>| {
orbit_map.entry(pair[1].clone()).or_insert(pair[0].clone());
});
orbit_map
}
fn part1(input: &str) -> usize {
let orbit_map = create_orbit_map(input);
let mut cnt: usize = 0;
for obj in orbit_map.keys() {
let mut key = obj;
while let Some(val) = orbit_map.get(key) {
cnt += 1;
key = val;
}
}
cnt
}
fn part2(input: &str) -> usize {
let orbit_map = create_orbit_map(input);
let my_traj: HashMap<String, usize> = HashMap::from_iter(
std::iter::successors(orbit_map.get("YOU").map(|el| (el, 0)), |(nxt, n)| {
(orbit_map.get(*nxt).map(|el| (el, n + 1 as usize)))
})
.map(|(el, n)| (String::from(el), n)),
);
let mut santa_transfers = 0;
let mut santa = orbit_map.get("SAN").unwrap();
loop {
if my_traj.contains_key(santa) {
return my_traj.get(santa).unwrap() + santa_transfers;
} else {
santa = orbit_map.get(santa).expect("no common orbits found");
santa_transfers += 1;
}
}
}
pub fn main() -> std::io::Result<()> {
let input = std::include_str!("../day6-input.txt").trim();
println!("part1 = {:?}", part1(input));
println!("part2 = {:?}", part2(input));
Ok(())
}
#[test]
fn test_day6_part1() {
let input = "COM)B\nB)C\nC)D\nD)E\nE)F\nB)G\nG)H\nD)I\nE)J\nJ)K\nK)L";
assert_eq!(part1(input), 42);
}
#[test]
fn test_day6_part2() {
let input = "COM)B\nB)C\nC)D\nD)E\nE)F\nB)G\nG)H\nD)I\nE)J\nJ)K\nK)L\nK)YOU\nI)SAN";
assert_eq!(part2(input), 4);
}

View file

@ -1,139 +0,0 @@
use crate::day5::compute_intcode_extended;
pub fn permutations(start: usize, size: usize) -> Permutations {
Permutations {
idxs: (start..size).collect(),
swaps: vec![start; size],
i: 0,
}
}
pub struct Permutations {
idxs: Vec<usize>,
swaps: Vec<usize>,
i: usize,
}
impl Iterator for Permutations {
type Item = Vec<usize>;
fn next(&mut self) -> Option<Self::Item> {
if self.i > 0 {
loop {
if self.i >= self.swaps.len() {
return None;
}
if self.swaps[self.i] < self.i {
break;
}
self.swaps[self.i] = 0;
self.i += 1;
}
self.idxs.swap(self.i, (self.i & 1) * self.swaps[self.i]);
self.swaps[self.i] += 1;
}
self.i = 1;
Some(self.idxs.clone())
}
}
fn compute_thruster(input: &mut Vec<i32>, settings: Vec<usize>) -> i32 {
let mut signal = 0;
for phase in settings {
signal = compute_intcode_extended(input, vec![phase as i32, signal]).1[0];
}
signal
}
fn part1() -> i32 {
let input: Vec<i32> = std::include_str!("../day7-input.txt")
.trim()
.split(",")
.map(|x| x.parse().ok().expect(&format!("{} not a number", x)))
.collect();
let mut max_thruster = std::i32::MIN;
for settings in permutations(0, 5).collect::<Vec<_>>() {
let thrust = compute_thruster(&mut input.clone(), settings);
max_thruster = max_thruster.max(thrust);
}
max_thruster
}
fn compute_feedback(input: &mut Vec<i32>, mut settings: Vec<i32>) -> Vec<i32> {
settings.push(0);
println!("{:?}", settings);
let signal = compute_intcode_extended(input, settings).1;
println!("{:?}", signal);
signal
}
fn part2() -> i32 {
let mut input: Vec<i32> = std::include_str!("../day7-input.txt")
.trim()
.split(",")
.map(|x| x.parse().ok().expect(&format!("{} not a number", x)))
.collect();
let mut max_thruster = std::i32::MIN;
for settings in permutations(5, 5).collect::<Vec<_>>() {
let thrust = compute_thruster(&mut input, settings);
max_thruster = max_thruster.max(thrust);
}
max_thruster
}
pub fn main() {
println!("part1 = {}", part1());
println!("part2 = {}", part2());
}
#[test]
fn test_compute_thruster_1() {
let mut input = vec![
3, 15, 3, 16, 1002, 16, 10, 16, 1, 16, 15, 15, 4, 15, 99, 0, 0,
];
let settings = vec![4, 3, 2, 1, 0];
assert_eq!(compute_thruster(&mut input, settings), 43210);
}
#[test]
fn test_compute_thruster_2() {
let mut input = vec![
3, 23, 3, 24, 1002, 24, 10, 24, 1002, 23, -1, 23, 101, 5, 23, 23, 1, 24, 23, 23, 4, 23, 99,
0, 0,
];
let settings = vec![0, 1, 2, 3, 4];
assert_eq!(compute_thruster(&mut input, settings), 54321);
}
#[test]
fn test_compute_thruster_3() {
let mut input = vec![
3, 31, 3, 32, 1002, 32, 10, 32, 1001, 31, -2, 31, 1007, 31, 0, 33, 1002, 33, 7, 33, 1, 33,
31, 31, 1, 32, 31, 31, 4, 31, 99, 0, 0, 0,
];
let settings = vec![1, 0, 4, 3, 2];
assert_eq!(compute_thruster(&mut input, settings), 65210);
}
#[test]
fn test_compute_feedback_1() {
let mut input = vec![
3, 26, 1001, 26, -4, 26, 3, 27, 1002, 27, 2, 27, 1, 27, 26, 27, 4, 27, 1001, 28, -1, 28,
1005, 28, 6, 99, 0, 0, 5,
];
let settings = vec![5, 6, 7, 8, 9];
assert_eq!(compute_feedback(&mut input, settings), [139629729]);
}
#[test]
fn test_compute_feedback_2() {
let mut input = vec![
3, 52, 1001, 52, -5, 52, 3, 53, 1, 52, 56, 54, 1007, 54, 5, 55, 1005, 55, 26, 1001, 54, -5,
54, 1105, 1, 12, 1, 53, 54, 53, 1008, 54, 0, 55, 1001, 55, 1, 55, 2, 53, 55, 53, 4, 53,
1001, 56, -1, 56, 1005, 56, 6, 99, 0, 0, 0, 0, 10,
];
let settings = vec![9, 7, 8, 5, 6];
assert_eq!(compute_feedback(&mut input, settings), [18216]);
}

View file

@ -1,6 +1,3 @@
use std::fs::File;
use std::io::{self, BufRead, BufReader};
fn fuel_for(mass: u64) -> u64 {
(mass / 3).saturating_sub(2)
}
@ -11,16 +8,9 @@ fn total_fuel(mass: u64) -> u64 {
.sum()
}
pub fn main() -> io::Result<()> {
let f = BufReader::new(File::open("day1-input.txt")?);
let total: u64 = f
.lines()
.map(|line| line.unwrap().parse().unwrap())
.map(total_fuel)
.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);
Ok(())
}
#[test]

View file

@ -81,6 +81,7 @@ fn first(input: &str) -> Option<i32> {
.cloned()
.map(|c| {
let other = entries[1].get(&c);
println!("{:?}", (c, other));
(c.0 + other.unwrap().0) as i32
})
.min()

View file

@ -1,6 +1,6 @@
use std;
fn compute_intcode(p: &mut Vec<usize>) {
fn compute_intcode(p: &mut Vec<usize>) -> Vec<usize> {
for idx in (0..(p.len())).step_by(4) {
match p[idx] {
1 => {
@ -16,9 +16,10 @@ fn compute_intcode(p: &mut Vec<usize>) {
p[res] = p[left] * p[right];
}
99 => break,
_ => panic!("invalid opcode"),
_ => panic!("Something went wrong!"),
}
}
p.to_vec()
}
pub fn part_one() {
@ -31,9 +32,7 @@ pub fn part_one() {
input[1] = 12;
input[2] = 2;
compute_intcode(&mut input);
println!("Intcode [0] is: {}", input[0]);
println!("Intcode [0] is: {}", compute_intcode(&mut input)[0]);
}
pub fn part_two() {
@ -53,8 +52,8 @@ pub fn part_two() {
input[1] = i;
for j in 0..99 {
input[2] = j;
let mut computed = input.clone();
compute_intcode(&mut computed);
let mut input_guess = input.clone();
let computed = compute_intcode(&mut input_guess);
found = computed[0] == lookup_num;
@ -77,19 +76,20 @@ pub fn part_two() {
#[test]
fn test_part_one() {
let mut intcode = vec![1, 0, 0, 0, 99];
compute_intcode(&mut intcode);
assert_eq!(intcode, vec!(2, 0, 0, 0, 99));
let mut intcode = vec![2, 3, 0, 3, 99];
compute_intcode(&mut intcode);
assert_eq!(intcode, vec!(2, 3, 0, 6, 99));
let mut intcode = vec![2, 4, 4, 5, 99, 0];
compute_intcode(&mut intcode);
assert_eq!(intcode, vec!(2, 4, 4, 5, 99, 9801));
let mut intcode = vec![1, 1, 1, 4, 99, 5, 6, 0, 99];
compute_intcode(&mut intcode);
assert_eq!(intcode, vec!(30, 1, 1, 4, 2, 5, 6, 0, 99));
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)
);
}

View file

@ -1,34 +1,22 @@
#[allow(dead_code)]
mod day1;
mod day2;
mod day3;
mod day4;
mod day5;
mod day6;
mod day7;
mod day_one;
mod day_three;
mod day_two;
fn main() -> std::io::Result<()> {
println!("========================= DAY 7");
day7::main();
use std::fs::File;
use std::io::{self, BufRead, BufReader};
//println!("========================= DAY 6");
//day6::main()?;
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);
//println!("========================= DAY 5");
//day5::main()?;
day_two::part_one();
day_two::part_two();
//println!("========================= DAY 4");
//day4::main()?;
//println!("========================= DAY 3");
//day3::main()?;
//println!("========================= DAY 2");
//day2::part_one();
//day2::part_two();
//println!("========================= DAY 1");
//day1::main()?;
day_three::main()?;
Ok(())
}