Skip to content

Commit fff4af5

Browse files
committed
rust day 23
1 parent 2752bab commit fff4af5

File tree

4 files changed

+136
-17
lines changed

4 files changed

+136
-17
lines changed

src/days/day20.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@ impl Tile {
3434
adj.swap(0, 2);
3535
}
3636
adj.rotate_right(self.rotation);
37-
adj[side].get(0).map(|x|x.id)
37+
adj[side].get(0).map(|x| x.id)
3838
}
3939

4040
/// applies flips and rotation until side side == id
4141
fn set_transform(&mut self, side: usize, id: usize, side2: usize, id2: usize) {
4242
let mut adj = self.adjacency.to_vec();
4343
for i in 0..4 {
44-
if ((id == 0 && adj[side].is_empty()) || (!adj[side].is_empty() && adj[side][0].id == id))
44+
if ((id == 0 && adj[side].is_empty())
45+
|| (!adj[side].is_empty() && adj[side][0].id == id))
4546
&& ((id2 == 0 && adj[side2].is_empty())
4647
|| (!adj[side2].is_empty() && adj[side2][0].id == id2))
4748
{
@@ -53,7 +54,8 @@ impl Tile {
5354
adj.swap(0, 2);
5455
self.flip = true;
5556
for i in 0..4 {
56-
if ((id == 0 && adj[side].is_empty()) || (!adj[side].is_empty() && adj[side][0].id == id))
57+
if ((id == 0 && adj[side].is_empty())
58+
|| (!adj[side].is_empty() && adj[side][0].id == id))
5759
&& ((id2 == 0 && adj[side2].is_empty())
5860
|| (!adj[side2].is_empty() && adj[side2][0].id == id2))
5961
{
@@ -199,11 +201,7 @@ pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
199201
let mut image = vec![vec![0usize; image_size]; image_size];
200202

201203
// first cell
202-
image[0][0] = adjacency_sums
203-
.iter()
204-
.find(|(_, v)| *v == 2)
205-
.unwrap()
206-
.0;
204+
image[0][0] = adjacency_sums.iter().find(|(_, v)| *v == 2).unwrap().0;
207205
input[&image[0][0]].borrow_mut().set_transform(0, 0, 3, 0);
208206

209207
// first row

src/days/day21.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,17 @@ pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
2828
for line in input.iter() {
2929
for allergen in &line.allergens {
3030
if let Some(current) = ingredients.get(allergen) {
31-
let int = line.ingredients.iter().copied().collect::<HashSet<_>>()
31+
let int = line
32+
.ingredients
33+
.iter()
34+
.copied()
35+
.collect::<HashSet<_>>()
3236
.intersection(current)
3337
.copied()
3438
.collect();
3539
ingredients.insert(allergen, int);
3640
} else {
37-
ingredients.insert(
38-
allergen,
39-
line.ingredients.iter().copied().collect(),
40-
);
41+
ingredients.insert(allergen, line.ingredients.iter().copied().collect());
4142
}
4243
}
4344
}
@@ -63,10 +64,7 @@ pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
6364

6465
let mut mappings = BTreeMap::new();
6566
for _ in 0..ingredients.len() {
66-
let (name, ones) = ingredients
67-
.iter()
68-
.find(|&(_, x)| x.len() == 1)
69-
.unwrap();
67+
let (name, ones) = ingredients.iter().find(|&(_, x)| x.len() == 1).unwrap();
7068
let value = *ones.iter().next().unwrap();
7169

7270
mappings.insert(*name, value);

src/days/day23.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use anyhow::Result;
2+
use libaoc::{aoc, AocResult, Timer};
3+
use std::fmt;
4+
5+
struct LinkedList {
6+
indicies: Vec<usize>,
7+
}
8+
9+
impl LinkedList {
10+
fn from(data: &[usize]) -> Self {
11+
let mut indicies = vec![(0, 0); data.len()];
12+
for (i, num) in indicies.iter_mut().enumerate() {
13+
*num = (data[i], *data.get(i + 1).unwrap_or(&data[0]) - 1)
14+
}
15+
indicies.sort_unstable_by(|&(a, _), &(b, _)| a.cmp(&b));
16+
let indicies: Vec<_> = indicies.iter().map(|&(_, i)| i).collect();
17+
LinkedList { indicies }
18+
}
19+
20+
fn remove_after(&mut self, start: usize, count: usize) -> usize {
21+
let ret = self.indicies[start];
22+
23+
let mut end = start;
24+
for _ in 0..=count {
25+
end = self.indicies[end];
26+
}
27+
28+
self.indicies[start] = end;
29+
30+
ret
31+
}
32+
33+
fn insert_after(&mut self, index: usize, data_ptr: usize, data_len: usize) {
34+
let mut end = data_ptr;
35+
for _ in 0..(data_len - 1) {
36+
end = self.indicies[end];
37+
}
38+
39+
self.indicies[end] = self.indicies[index];
40+
41+
self.indicies[index] = data_ptr;
42+
}
43+
44+
fn to_vec(&self) -> Vec<usize> {
45+
let mut result = Vec::with_capacity(self.indicies.len());
46+
result.push(1);
47+
48+
let mut index = 0;
49+
for _ in 0..(self.indicies.len() - 1) {
50+
let data = self.indicies[index];
51+
result.push(data + 1);
52+
index = data
53+
}
54+
55+
result
56+
}
57+
}
58+
59+
impl fmt::Debug for LinkedList {
60+
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
61+
write!(f, "{:?}", self.to_vec())
62+
}
63+
}
64+
65+
fn game(cups: &[usize], move_count: usize) -> LinkedList {
66+
let max = cups.len();
67+
let mut current_cup = cups[0] - 1;
68+
let mut cups = LinkedList::from(cups);
69+
70+
for _ in 0..move_count {
71+
let c1 = cups.indicies[current_cup];
72+
let c2 = cups.indicies[c1];
73+
let c3 = cups.indicies[c2];
74+
let moved_cups = [c1 + 1, c2 + 1, c3 + 1];
75+
76+
let removed = cups.remove_after(current_cup, 3);
77+
78+
let mut destination = current_cup;
79+
loop {
80+
if destination == 0 {
81+
destination = max;
82+
}
83+
if moved_cups.contains(&destination) {
84+
destination -= 1
85+
} else {
86+
break;
87+
}
88+
}
89+
90+
cups.insert_after(destination - 1, removed, 3);
91+
92+
current_cup = cups.indicies[current_cup];
93+
}
94+
95+
cups
96+
}
97+
98+
#[aoc("82635947", "157047826689", "685974213")]
99+
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
100+
let mut cups: Vec<_> = input
101+
.chars()
102+
.map(|x| x.to_digit(10).unwrap() as usize)
103+
.collect();
104+
timer.lap("Parse");
105+
106+
let mut part1 = game(&cups, 100).to_vec();
107+
while part1[0] != 1 {
108+
part1.rotate_right(1);
109+
}
110+
let part1 = part1[1..]
111+
.iter()
112+
.fold(String::new(), |s, &c| s + &c.to_string());
113+
timer.lap("Part 1");
114+
115+
cups.extend(10..=1_000_000);
116+
let part2 = game(&cups, 10_000_000);
117+
let part2 = (part2.indicies[0]+1) * (part2.indicies[part2.indicies[0]]+1);
118+
119+
timer.lap("Part 2");
120+
121+
Ok(AocResult::new(part1, part2))
122+
}

src/days/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ mod day19;
2020
mod day20;
2121
mod day21;
2222
mod day22;
23+
mod day23;

0 commit comments

Comments
 (0)