Skip to content

Commit

Permalink
rust day 23
Browse files Browse the repository at this point in the history
  • Loading branch information
OrangeBacon committed Dec 23, 2020
1 parent 2752bab commit fff4af5
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 17 deletions.
14 changes: 6 additions & 8 deletions src/days/day20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ impl Tile {
adj.swap(0, 2);
}
adj.rotate_right(self.rotation);
adj[side].get(0).map(|x|x.id)
adj[side].get(0).map(|x| x.id)
}

/// applies flips and rotation until side side == id
fn set_transform(&mut self, side: usize, id: usize, side2: usize, id2: usize) {
let mut adj = self.adjacency.to_vec();
for i in 0..4 {
if ((id == 0 && adj[side].is_empty()) || (!adj[side].is_empty() && adj[side][0].id == id))
if ((id == 0 && adj[side].is_empty())
|| (!adj[side].is_empty() && adj[side][0].id == id))
&& ((id2 == 0 && adj[side2].is_empty())
|| (!adj[side2].is_empty() && adj[side2][0].id == id2))
{
Expand All @@ -53,7 +54,8 @@ impl Tile {
adj.swap(0, 2);
self.flip = true;
for i in 0..4 {
if ((id == 0 && adj[side].is_empty()) || (!adj[side].is_empty() && adj[side][0].id == id))
if ((id == 0 && adj[side].is_empty())
|| (!adj[side].is_empty() && adj[side][0].id == id))
&& ((id2 == 0 && adj[side2].is_empty())
|| (!adj[side2].is_empty() && adj[side2][0].id == id2))
{
Expand Down Expand Up @@ -199,11 +201,7 @@ pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
let mut image = vec![vec![0usize; image_size]; image_size];

// first cell
image[0][0] = adjacency_sums
.iter()
.find(|(_, v)| *v == 2)
.unwrap()
.0;
image[0][0] = adjacency_sums.iter().find(|(_, v)| *v == 2).unwrap().0;
input[&image[0][0]].borrow_mut().set_transform(0, 0, 3, 0);

// first row
Expand Down
16 changes: 7 additions & 9 deletions src/days/day21.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,17 @@ pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
for line in input.iter() {
for allergen in &line.allergens {
if let Some(current) = ingredients.get(allergen) {
let int = line.ingredients.iter().copied().collect::<HashSet<_>>()
let int = line
.ingredients
.iter()
.copied()
.collect::<HashSet<_>>()
.intersection(current)
.copied()
.collect();
ingredients.insert(allergen, int);
} else {
ingredients.insert(
allergen,
line.ingredients.iter().copied().collect(),
);
ingredients.insert(allergen, line.ingredients.iter().copied().collect());
}
}
}
Expand All @@ -63,10 +64,7 @@ pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {

let mut mappings = BTreeMap::new();
for _ in 0..ingredients.len() {
let (name, ones) = ingredients
.iter()
.find(|&(_, x)| x.len() == 1)
.unwrap();
let (name, ones) = ingredients.iter().find(|&(_, x)| x.len() == 1).unwrap();
let value = *ones.iter().next().unwrap();

mappings.insert(*name, value);
Expand Down
122 changes: 122 additions & 0 deletions src/days/day23.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
use anyhow::Result;
use libaoc::{aoc, AocResult, Timer};
use std::fmt;

struct LinkedList {
indicies: Vec<usize>,
}

impl LinkedList {
fn from(data: &[usize]) -> Self {
let mut indicies = vec![(0, 0); data.len()];
for (i, num) in indicies.iter_mut().enumerate() {
*num = (data[i], *data.get(i + 1).unwrap_or(&data[0]) - 1)
}
indicies.sort_unstable_by(|&(a, _), &(b, _)| a.cmp(&b));
let indicies: Vec<_> = indicies.iter().map(|&(_, i)| i).collect();
LinkedList { indicies }
}

fn remove_after(&mut self, start: usize, count: usize) -> usize {
let ret = self.indicies[start];

let mut end = start;
for _ in 0..=count {
end = self.indicies[end];
}

self.indicies[start] = end;

ret
}

fn insert_after(&mut self, index: usize, data_ptr: usize, data_len: usize) {
let mut end = data_ptr;
for _ in 0..(data_len - 1) {
end = self.indicies[end];
}

self.indicies[end] = self.indicies[index];

self.indicies[index] = data_ptr;
}

fn to_vec(&self) -> Vec<usize> {
let mut result = Vec::with_capacity(self.indicies.len());
result.push(1);

let mut index = 0;
for _ in 0..(self.indicies.len() - 1) {
let data = self.indicies[index];
result.push(data + 1);
index = data
}

result
}
}

impl fmt::Debug for LinkedList {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{:?}", self.to_vec())
}
}

fn game(cups: &[usize], move_count: usize) -> LinkedList {
let max = cups.len();
let mut current_cup = cups[0] - 1;
let mut cups = LinkedList::from(cups);

for _ in 0..move_count {
let c1 = cups.indicies[current_cup];
let c2 = cups.indicies[c1];
let c3 = cups.indicies[c2];
let moved_cups = [c1 + 1, c2 + 1, c3 + 1];

let removed = cups.remove_after(current_cup, 3);

let mut destination = current_cup;
loop {
if destination == 0 {
destination = max;
}
if moved_cups.contains(&destination) {
destination -= 1
} else {
break;
}
}

cups.insert_after(destination - 1, removed, 3);

current_cup = cups.indicies[current_cup];
}

cups
}

#[aoc("82635947", "157047826689", "685974213")]
pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> {
let mut cups: Vec<_> = input
.chars()
.map(|x| x.to_digit(10).unwrap() as usize)
.collect();
timer.lap("Parse");

let mut part1 = game(&cups, 100).to_vec();
while part1[0] != 1 {
part1.rotate_right(1);
}
let part1 = part1[1..]
.iter()
.fold(String::new(), |s, &c| s + &c.to_string());
timer.lap("Part 1");

cups.extend(10..=1_000_000);
let part2 = game(&cups, 10_000_000);
let part2 = (part2.indicies[0]+1) * (part2.indicies[part2.indicies[0]]+1);

timer.lap("Part 2");

Ok(AocResult::new(part1, part2))
}
1 change: 1 addition & 0 deletions src/days/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ mod day19;
mod day20;
mod day21;
mod day22;
mod day23;

0 comments on commit fff4af5

Please sign in to comment.