Compare commits
No commits in common. "987760422a1c99d925e25afd2387c810546dd2b0" and "b67eea9efeeb8a0d53047c9cc2b9f152d2fe9bd9" have entirely different histories.
987760422a
...
b67eea9efe
@ -1,2 +0,0 @@
|
|||||||
Player 1 starting position: 4
|
|
||||||
Player 2 starting position: 5
|
|
||||||
@ -1,171 +0,0 @@
|
|||||||
use advent::prelude::*;
|
|
||||||
use aoc_runner_derive::aoc;
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
struct Player {
|
|
||||||
tally: usize,
|
|
||||||
score: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Player {
|
|
||||||
fn space(&self) -> usize {
|
|
||||||
(self.tally % 10) + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
struct Die {
|
|
||||||
roll_count: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Die {
|
|
||||||
fn roll(&mut self) -> usize {
|
|
||||||
let val = (self.roll_count % 100) + 1;
|
|
||||||
self.roll_count += 1;
|
|
||||||
val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn take_turn(p: &mut Player, die: &mut Die) -> bool {
|
|
||||||
p.tally += die.roll() + die.roll() + die.roll();
|
|
||||||
p.score += p.space();
|
|
||||||
|
|
||||||
if p.score >= 1000 {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day21, part1)]
|
|
||||||
fn part1(input: &str) -> Result<usize> {
|
|
||||||
let mut p: Vec<_> = input
|
|
||||||
.lines()
|
|
||||||
.map(|l| l.split_once(": ").unwrap())
|
|
||||||
.map(|(_, space)| space.parse().expect("couldn't parse starting spaceition"))
|
|
||||||
.map(|space: usize| Player {
|
|
||||||
tally: space - 1,
|
|
||||||
score: 0,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let mut die = Die::default();
|
|
||||||
loop {
|
|
||||||
if take_turn(&mut p[0], &mut die) {
|
|
||||||
return Ok(die.roll_count * p[1].score);
|
|
||||||
}
|
|
||||||
//println!( "Player 1 space {} for a total score of {}.", p[0].space(), p[0].score);
|
|
||||||
|
|
||||||
if take_turn(&mut p[1], &mut die) {
|
|
||||||
return Ok(die.roll_count * p[0].score);
|
|
||||||
}
|
|
||||||
//println!( "Player 2 space {} for a total score of {}.", p[1].space(), p[1].score);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn play_part2(p1: Player, p2: Player) -> (usize, usize) {
|
|
||||||
fn play_part2_rec(
|
|
||||||
mut p1: Player,
|
|
||||||
mut p2: Player,
|
|
||||||
r1: usize,
|
|
||||||
r2: usize,
|
|
||||||
r3: usize,
|
|
||||||
r4: usize,
|
|
||||||
r5: usize,
|
|
||||||
r6: usize,
|
|
||||||
) -> (usize, usize) {
|
|
||||||
//println!( "p1 {} {} p2 {} {} die {} {} {} {} {} {}", p1.score, p1.space(), p2.score, p2.space(), r1, r2, r3, r4, r5, r6,);
|
|
||||||
p1.tally += r1 + r2 + r3;
|
|
||||||
p1.score += p1.space();
|
|
||||||
if p1.score >= 21 {
|
|
||||||
return (1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
p2.tally += r4 + r5 + r6;
|
|
||||||
p2.score += p2.space();
|
|
||||||
if p2.score >= 21 {
|
|
||||||
return (0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut p1_score = 0;
|
|
||||||
let mut p2_score = 0;
|
|
||||||
|
|
||||||
for i in [1, 2, 3] {
|
|
||||||
for j in [1, 2, 3] {
|
|
||||||
for k in [1, 2, 3] {
|
|
||||||
for x in [1, 2, 3] {
|
|
||||||
for y in [1, 2, 3] {
|
|
||||||
for z in [1, 2, 3] {
|
|
||||||
let (p1s, p2s) = play_part2_rec(p1, p2, i, j, k, x, y, z);
|
|
||||||
p1_score += p1s;
|
|
||||||
p2_score += p2s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(p1_score, p2_score)
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut p1_score = 0;
|
|
||||||
let mut p2_score = 0;
|
|
||||||
|
|
||||||
for i in [1, 2, 3] {
|
|
||||||
for j in [1, 2, 3] {
|
|
||||||
for k in [1, 2, 3] {
|
|
||||||
for x in [1, 2, 3] {
|
|
||||||
for y in [1, 2, 3] {
|
|
||||||
for z in [1, 2, 3] {
|
|
||||||
let (p1s, p2s) = play_part2_rec(p1, p2, i, j, k, x, y, z);
|
|
||||||
p1_score += p1s;
|
|
||||||
p2_score += p2s;
|
|
||||||
println!("Running score {} vs {}", p1_score, p2_score);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(p1_score, p2_score)
|
|
||||||
}
|
|
||||||
|
|
||||||
//#[aoc(day21, part2)]
|
|
||||||
fn part2(input: &str) -> Result<usize> {
|
|
||||||
let p: Vec<_> = input
|
|
||||||
.lines()
|
|
||||||
.map(|l| l.split_once(": ").unwrap())
|
|
||||||
.map(|(_, space)| space.parse().expect("couldn't parse starting spaceition"))
|
|
||||||
.map(|space: usize| Player {
|
|
||||||
tally: space - 1,
|
|
||||||
score: 0,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
let (p1_wins, p2_wins) = play_part2(p[0], p[1]);
|
|
||||||
Ok(if p1_wins > p2_wins { p1_wins } else { p2_wins })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_part1() -> Result<()> {
|
|
||||||
let input = r#"
|
|
||||||
Player 1 starting position: 4
|
|
||||||
Player 2 starting position: 8
|
|
||||||
"#
|
|
||||||
.trim();
|
|
||||||
assert_eq!(part1(input)?, 739785);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
//#[test]
|
|
||||||
fn test_part2() -> Result<()> {
|
|
||||||
let input = r#"
|
|
||||||
Player 1 starting position: 4
|
|
||||||
Player 2 starting position: 8
|
|
||||||
"#
|
|
||||||
.trim();
|
|
||||||
assert_eq!(part2(input)?, 444356092776315);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,144 +0,0 @@
|
|||||||
use advent::prelude::*;
|
|
||||||
use aoc_runner_derive::aoc;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Instruction {
|
|
||||||
on: bool,
|
|
||||||
x_rng: RangeInclusive<i64>,
|
|
||||||
y_rng: RangeInclusive<i64>,
|
|
||||||
z_rng: RangeInclusive<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for Instruction {
|
|
||||||
type Err = Infallible;
|
|
||||||
|
|
||||||
fn from_str(input: &str) -> std::result::Result<Instruction, Infallible> {
|
|
||||||
// on x=11..13,y=11..13,z=11..13
|
|
||||||
// off x=9..11,y=9..11,z=9..11
|
|
||||||
let (verb, rest) = input.split_once(' ').unwrap();
|
|
||||||
let on = match verb {
|
|
||||||
"on" => true,
|
|
||||||
"off" => false,
|
|
||||||
_ => unreachable!("unexpected instruction type"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let parts: Vec<_> = rest.split(',').collect();
|
|
||||||
let parse_rng = |s: &str| -> RangeInclusive<i64> {
|
|
||||||
s.split_once('=')
|
|
||||||
.unwrap()
|
|
||||||
.1
|
|
||||||
.split_once("..")
|
|
||||||
.map(|(lo, hi)| (lo.parse().unwrap(), hi.parse().unwrap()))
|
|
||||||
.map(|(lo, hi)| lo..=hi)
|
|
||||||
.unwrap()
|
|
||||||
};
|
|
||||||
let x_rng = parse_rng(parts[0]);
|
|
||||||
let y_rng = parse_rng(parts[1]);
|
|
||||||
let z_rng = parse_rng(parts[2]);
|
|
||||||
Ok(Instruction {
|
|
||||||
on,
|
|
||||||
x_rng,
|
|
||||||
y_rng,
|
|
||||||
z_rng,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn part1_apply(insts: Vec<Instruction>) -> usize {
|
|
||||||
let mut grid = HashSet::new();
|
|
||||||
for inst in &insts {
|
|
||||||
dbg!(&inst);
|
|
||||||
for x in inst.x_rng.clone() {
|
|
||||||
for y in inst.y_rng.clone() {
|
|
||||||
for z in inst.z_rng.clone() {
|
|
||||||
if inst.on {
|
|
||||||
grid.insert((x, y, z));
|
|
||||||
} else {
|
|
||||||
grid.remove(&(x, y, z));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
grid.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inbounds(r: &RangeInclusive<i64>) -> bool {
|
|
||||||
// lazy but good enough for part1
|
|
||||||
r.start().abs() <= 50
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day22, part1)]
|
|
||||||
fn part1(input: &str) -> Result<usize> {
|
|
||||||
let insts: Vec<Instruction> = input
|
|
||||||
.lines()
|
|
||||||
.map(|l| l.parse().expect("failed to parse instruction"))
|
|
||||||
.filter(|i: &Instruction| inbounds(&i.x_rng) && inbounds(&i.y_rng) && inbounds(&i.z_rng))
|
|
||||||
.collect();
|
|
||||||
dbg!(&insts);
|
|
||||||
Ok(part1_apply(insts))
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
#[aoc(day22, part2)]
|
|
||||||
fn part2(input: &str) -> Result<usize> {
|
|
||||||
todo!("part2");
|
|
||||||
Ok(0)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_part1() -> Result<()> {
|
|
||||||
let input = r#"
|
|
||||||
on x=10..12,y=10..12,z=10..12
|
|
||||||
on x=11..13,y=11..13,z=11..13
|
|
||||||
off x=9..11,y=9..11,z=9..11
|
|
||||||
on x=10..10,y=10..10,z=10..10
|
|
||||||
"#
|
|
||||||
.trim();
|
|
||||||
assert_eq!(part1(input)?, 39);
|
|
||||||
|
|
||||||
let input = r#"
|
|
||||||
on x=-20..26,y=-36..17,z=-47..7
|
|
||||||
on x=-20..33,y=-21..23,z=-26..28
|
|
||||||
on x=-22..28,y=-29..23,z=-38..16
|
|
||||||
on x=-46..7,y=-6..46,z=-50..-1
|
|
||||||
on x=-49..1,y=-3..46,z=-24..28
|
|
||||||
on x=2..47,y=-22..22,z=-23..27
|
|
||||||
on x=-27..23,y=-28..26,z=-21..29
|
|
||||||
on x=-39..5,y=-6..47,z=-3..44
|
|
||||||
on x=-30..21,y=-8..43,z=-13..34
|
|
||||||
on x=-22..26,y=-27..20,z=-29..19
|
|
||||||
off x=-48..-32,y=26..41,z=-47..-37
|
|
||||||
on x=-12..35,y=6..50,z=-50..-2
|
|
||||||
off x=-48..-32,y=-32..-16,z=-15..-5
|
|
||||||
on x=-18..26,y=-33..15,z=-7..46
|
|
||||||
off x=-40..-22,y=-38..-28,z=23..41
|
|
||||||
on x=-16..35,y=-41..10,z=-47..6
|
|
||||||
off x=-32..-23,y=11..30,z=-14..3
|
|
||||||
on x=-49..-5,y=-3..45,z=-29..18
|
|
||||||
off x=18..30,y=-20..-8,z=-3..13
|
|
||||||
on x=-41..9,y=-7..43,z=-33..15
|
|
||||||
on x=-54112..-39298,y=-85059..-49293,z=-27449..7877
|
|
||||||
on x=967..23432,y=45373..81175,z=27513..53682
|
|
||||||
"#
|
|
||||||
.trim();
|
|
||||||
assert_eq!(part1(input)?, 590784);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
#[test]
|
|
||||||
fn test_part2()->Result<()> {
|
|
||||||
let input = r#"
|
|
||||||
"#
|
|
||||||
.trim();
|
|
||||||
assert_eq!(part2(input)?, usize::MAX);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
@ -10,8 +10,6 @@ pub mod day17;
|
|||||||
//pub mod day18;
|
//pub mod day18;
|
||||||
pub mod day2;
|
pub mod day2;
|
||||||
pub mod day20;
|
pub mod day20;
|
||||||
pub mod day21;
|
|
||||||
pub mod day22;
|
|
||||||
pub mod day3;
|
pub mod day3;
|
||||||
pub mod day4;
|
pub mod day4;
|
||||||
pub mod day5;
|
pub mod day5;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use advent::prelude::*;
|
use advent::prelude::*;
|
||||||
use aoc_runner_derive::aoc;
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
|
||||||
#[aoc(dayX, part1)]
|
#[aoc(dayX, part1)]
|
||||||
fn part1(input: &str) -> Result<usize> {
|
fn part1(input: &str) -> Result<usize> {
|
||||||
|
|||||||
@ -5,7 +5,7 @@ pub mod prelude {
|
|||||||
fmt::{Debug, Display, Error, Formatter},
|
fmt::{Debug, Display, Error, Formatter},
|
||||||
io::Read,
|
io::Read,
|
||||||
num::ParseIntError,
|
num::ParseIntError,
|
||||||
ops::{Index, IndexMut, RangeInclusive},
|
ops::{Index, IndexMut},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user