Skip to content

Instantly share code, notes, and snippets.

@0e4ef622
Last active December 6, 2018 06:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 0e4ef622/52e30856965cbad10848a0c26c8b169b to your computer and use it in GitHub Desktop.
Save 0e4ef622/52e30856965cbad10848a0c26c8b169b to your computer and use it in GitHub Desktop.
aoc day 4
#[derive(Clone, Copy)]
enum Event {
Begin(usize),
Sleep,
Wake,
}
#[derive(Clone, Copy)]
struct Entry {
minute: usize,
event: Event,
time: u128,
}
unsafe fn parse_num(digits: &[u8]) -> usize {
let mut n = 0;
for &g in digits.iter() {
n *= 10;
n += (g - b'0') as usize;
}
n
}
fn parse_no_sort(input: &str) -> Vec<Entry> {
let mut entries = Vec::with_capacity(1130);
for line in input.lines() {
let bline = line.as_bytes();
unsafe {
let time = u128::from_be(std::ptr::read_unaligned(line.as_ptr().offset(1) as *const u128));
let minute = (*bline.get_unchecked(15) - b'0') as usize * 10 + (*bline.get_unchecked(16) - b'0') as usize;
let event_str = &bline.get_unchecked(19..);
let event = if *event_str.get_unchecked(0) == b'f' {
Event::Sleep
} else if *event_str.get_unchecked(0) == b'w' {
Event::Wake
} else {
Event::Begin(parse_num(bline.get_unchecked(26..line.len()-13)))
};
entries.push(Entry {
time,
minute,
event,
});
}
}
entries
}
fn parse(input: &str) -> Vec<Entry> {
let mut v = parse_no_sort(input);
v.sort_unstable_by_key(|v| v.time);
v
}
use hashbrown::HashMap;
pub fn part1(input: &str) -> usize {
let entries = parse(input);
let mut map = HashMap::new();
let mut current_id = 0;
let mut sleep_start = 0;
for entry in entries {
match entry.event {
Event::Begin(id) => {
current_id = id;
map.entry(id).or_insert((0, [0; 60]));
}
Event::Sleep => sleep_start = entry.minute,
Event::Wake => {
let v = map.get_mut(&current_id).unwrap();
for n in &mut v.1[sleep_start..entry.minute] {
*n += 1;
}
v.0 += entry.minute - sleep_start;
}
}
}
let entry = map.into_iter()
.max_by_key(|v| v.1 .0)
.unwrap();
let id = entry.0;
let min = entry.1 .1
.iter()
.enumerate()
.max_by_key(|v| v.1)
.unwrap().0;
id * min
}
pub fn part2(input: &str) -> usize {
let entries = parse(input);
let mut map = HashMap::new();
let mut current_id = 0;
let mut sleep_start = 0;
for entry in entries {
match entry.event {
Event::Begin(id) => {
current_id = id;
map.entry(id).or_insert([0; 60]);
}
Event::Sleep => sleep_start = entry.minute,
Event::Wake => {
let v = map.get_mut(&current_id).unwrap();
for n in &mut v[sleep_start..entry.minute] {
*n += 1;
}
}
}
}
let entry = map.into_iter()
.map(|(a,b)| (a, b.iter().cloned().enumerate().max_by_key(|v| v.1).unwrap()))
.max_by_key(|v| v.1 .1)
.unwrap();
let id = entry.0;
let min = entry.1 .0;
id * min
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment