mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Implement day 15 of 2016.
This commit is contained in:
@@ -5,3 +5,4 @@ authors = ["Bert Peters <bert@bertptrs.nl>"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.32"
|
clap = "2.32"
|
||||||
|
regex = "1.0"
|
||||||
|
|||||||
6
2016/inputs/15.txt
Normal file
6
2016/inputs/15.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Disc #1 has 13 positions; at time=0, it is at position 11.
|
||||||
|
Disc #2 has 5 positions; at time=0, it is at position 0.
|
||||||
|
Disc #3 has 17 positions; at time=0, it is at position 11.
|
||||||
|
Disc #4 has 3 positions; at time=0, it is at position 0.
|
||||||
|
Disc #5 has 7 positions; at time=0, it is at position 2.
|
||||||
|
Disc #6 has 19 positions; at time=0, it is at position 17.
|
||||||
@@ -29,6 +29,24 @@ pub fn prime_sieve(dest: &mut[bool]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Greatest common divisor
|
||||||
|
pub fn gcd(a: i32, b: i32) -> i32 {
|
||||||
|
if a < b {
|
||||||
|
gcd(b, a)
|
||||||
|
} else {
|
||||||
|
if a % b == 0 {
|
||||||
|
b
|
||||||
|
} else {
|
||||||
|
gcd(a % b, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Least common multiple
|
||||||
|
pub fn lcm(a: i32, b: i32) -> i32 {
|
||||||
|
a * b / gcd(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
/// Solution trait
|
/// Solution trait
|
||||||
///
|
///
|
||||||
/// Every day's solution should implement this function so that it can
|
/// Every day's solution should implement this function so that it can
|
||||||
@@ -60,4 +78,15 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(output, input);
|
assert_eq!(output, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gcd() {
|
||||||
|
assert_eq!(12, gcd(24, 36));
|
||||||
|
assert_eq!(1, gcd(1, 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_lcm() {
|
||||||
|
assert_eq!(12, lcm(6, 4));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
69
2016/src/day15.rs
Normal file
69
2016/src/day15.rs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
use std::io;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use regex;
|
||||||
|
use common;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Day15 {
|
||||||
|
disks: Vec<(i32, i32)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Day15 {
|
||||||
|
pub fn new() -> Day15 {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_disks(&mut self, input: &mut io::Read) {
|
||||||
|
// Note: this implementation assumes the input is sorted.
|
||||||
|
let re = regex::Regex::new(r"Disc #(\d+) has (\d+) positions; at time=0, it is at position (\d+).")
|
||||||
|
.unwrap();
|
||||||
|
let reader = io::BufReader::new(input);
|
||||||
|
for line in reader.lines() {
|
||||||
|
let contents = line.unwrap();
|
||||||
|
let groups = re.captures(&contents).unwrap();
|
||||||
|
let disk_size: i32 = groups.get(2).unwrap().as_str().parse().unwrap();
|
||||||
|
let start_pos: i32 = groups.get(3).unwrap().as_str().parse().unwrap();
|
||||||
|
self.disks.push((disk_size, start_pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn first_pass(&self) -> i32 {
|
||||||
|
let mut to_wait = 0;
|
||||||
|
let mut multiplier = 1;
|
||||||
|
for (i, (size, start)) in self.disks.iter().enumerate() {
|
||||||
|
while (i as i32 + start + to_wait + 1) % size != 0 {
|
||||||
|
to_wait += multiplier;
|
||||||
|
}
|
||||||
|
multiplier = common::lcm(*size, multiplier);
|
||||||
|
}
|
||||||
|
to_wait
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl common::Solution for Day15 {
|
||||||
|
fn part1(&mut self, input: &mut io::Read) -> String {
|
||||||
|
self.read_disks(input);
|
||||||
|
format!("{}", self.first_pass())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(&mut self, input: &mut io::Read) -> String {
|
||||||
|
self.read_disks(input);
|
||||||
|
self.disks.push((11, 0));
|
||||||
|
format!("{}", self.first_pass())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use common::Solution;
|
||||||
|
|
||||||
|
const SAMPLE: &str = "Disc #1 has 5 positions; at time=0, it is at position 4.\n\
|
||||||
|
Disc #2 has 2 positions; at time=0, it is at position 1.";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn sample_part1() {
|
||||||
|
let mut instance = Day15::new();
|
||||||
|
assert_eq!("5", instance.part1(&mut SAMPLE.as_bytes()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
extern crate regex;
|
||||||
use clap::{Arg, App};
|
use clap::{Arg, App};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod day1;
|
pub mod day1;
|
||||||
|
pub mod day15;
|
||||||
|
|
||||||
fn get_impl(day: i32) -> Box<common::Solution> {
|
fn get_impl(day: i32) -> Box<common::Solution> {
|
||||||
match day {
|
match day {
|
||||||
1 => { Box::new(day1::Day1::new()) }
|
1 => { Box::new(day1::Day1::new()) }
|
||||||
|
15 => { Box::new(day15::Day15::new()) }
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Unimplemented day {}", day)
|
panic!("Unimplemented day {}", day)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user