1+ use aoc_rust_common:: Solution ;
2+ use std:: fmt:: Display ;
13use std:: collections:: HashMap ;
2-
3- use chrono:: offset:: TimeZone ;
4- use chrono:: offset:: Utc ;
5- use chrono:: DateTime ;
6- use chrono:: Timelike ;
4+ use chrono:: { DateTime , Utc , Timelike , NaiveDateTime } ;
75use regex:: Regex ;
86
9- #[ derive( Debug , PartialEq , PartialOrd , Ord , Eq , Copy , Clone ) ]
10- enum EventType {
11- Wake ,
12- Sleep ,
13- Shift ( usize ) ,
14- }
7+ pub struct Day04 ;
158
169#[ derive( Debug , PartialEq , PartialOrd , Ord , Eq , Copy , Clone ) ]
17- struct Event {
18- time : DateTime < Utc > ,
19- event : EventType ,
20- }
21-
22- #[ derive( Default ) ]
23- pub struct Day04 {
24- events : Vec < Event > ,
25- }
10+ enum EventType { Wake , Sleep , Shift ( usize ) }
11+ #[ derive( Debug , PartialEq , PartialOrd , Ord , Eq , Copy , Clone ) ]
12+ struct Event { time : DateTime < Utc > , event : EventType }
2613
27- fn read_events ( input : String ) -> Vec < Event > {
14+ fn get_sleeps ( input : & str ) -> HashMap < usize , [ u32 ; 60 ] > {
2815 let scanner = Regex :: new ( r"^\[([^]]+)] (Guard #(\d+)|falls asleep|wakes up)" ) . unwrap ( ) ;
29-
30- let mut events = Vec :: new ( ) ;
31- for line in input. lines ( ) {
16+ let mut events: Vec < Event > = input. lines ( ) . map ( |line| {
3217 let captures = scanner. captures ( line) . unwrap ( ) ;
33- let timestamp = Utc
34- . datetime_from_str ( & captures[ 1 ] , "%Y-%m-%d %H:%M" )
35- . unwrap ( ) ;
36-
18+ let timestamp = NaiveDateTime :: parse_from_str ( & captures[ 1 ] , "%Y-%m-%d %H:%M" ) . unwrap ( ) . and_local_timezone ( Utc ) . unwrap ( ) ;
3719 let event = match & captures[ 2 ] {
38- "falls asleep" => EventType :: Sleep ,
39- "wakes up" => EventType :: Wake ,
20+ "falls asleep" => EventType :: Sleep , "wakes up" => EventType :: Wake ,
4021 _ => EventType :: Shift ( captures[ 3 ] . parse ( ) . unwrap ( ) ) ,
4122 } ;
42-
43- events. push ( Event {
44- time : timestamp,
45- event,
46- } ) ;
47- }
23+ Event { time : timestamp, event }
24+ } ) . collect ( ) ;
4825 events. sort_unstable ( ) ;
49- events
50- }
51- fn format_results ( sleepers : & HashMap < usize , [ u32 ; 60 ] > , scores : & HashMap < usize , u32 > ) -> usize {
52- let ( best_sleeper, _) = scores. iter ( ) . max_by ( |& ( _, a) , & ( _, b) | a. cmp ( b) ) . unwrap ( ) ;
5326
54- let best_minute = sleepers[ best_sleeper]
55- . iter ( )
56- . enumerate ( )
57- . max_by ( |& ( _, a) , & ( _, b) | a. cmp ( b) )
58- . unwrap ( )
59- . 0 ;
60-
61- best_sleeper * best_minute
62- }
63-
64- fn get_sleeps ( events : Vec < Event > ) -> HashMap < usize , [ u32 ; 60 ] > {
6527 let mut sleeps = HashMap :: new ( ) ;
6628 let mut guard: Option < usize > = None ;
6729 let mut sleep_start: Option < DateTime < Utc > > = None ;
68-
6930 for event in events. iter ( ) {
7031 match & event. event {
71- EventType :: Shift ( val) => {
72- guard = Some ( * val) ;
73- sleep_start = None ;
74- }
75- EventType :: Sleep => {
76- sleep_start = Some ( event. time ) ;
77- }
32+ EventType :: Shift ( val) => { guard = Some ( * val) ; sleep_start = None ; }
33+ EventType :: Sleep => { sleep_start = Some ( event. time ) ; }
7834 EventType :: Wake => {
7935 let minutes = sleeps. entry ( guard. unwrap ( ) ) . or_insert ( [ 0u32 ; 60 ] ) ;
8036 for m in sleep_start. unwrap ( ) . minute ( ) ..event. time . minute ( ) {
@@ -85,51 +41,24 @@ fn get_sleeps(events: Vec<Event>) -> HashMap<usize, [u32; 60]> {
8541 }
8642 sleeps
8743}
88- fn part1 ( input : String ) -> ( HashMap < usize , [ u32 ; 60 ] > , HashMap < usize , u32 > ) {
89- let events = read_events ( input) ;
90- let sleepers = get_sleeps ( events) ;
91- let scores: HashMap < usize , u32 > = sleepers. iter ( ) . map ( |( k, v) | ( * k, v. iter ( ) . sum ( ) ) ) . collect ( ) ;
9244
93- ( sleepers, scores)
94- }
95-
96- fn part2 ( input : String ) -> ( HashMap < usize , [ u32 ; 60 ] > , HashMap < usize , u32 > ) {
97- let events = read_events ( input) ;
98- let sleepers = get_sleeps ( events) ;
99- let scores: HashMap < usize , u32 > = sleepers
100- . iter ( )
101- . map ( |( k, v) | ( * k, * v. iter ( ) . max ( ) . unwrap ( ) ) )
102- . collect ( ) ;
103-
104- ( sleepers, scores)
105- }
106-
107- #[ cfg( test) ]
108- mod tests {
109- use super :: * ;
45+ impl Solution for Day04 {
46+ fn year ( & self ) -> u32 { 2018 }
47+ fn day ( & self ) -> u32 { 4 }
11048
111- #[ test]
112- #[ ignore]
113- fn test_first ( ) {
114- let example = include_str ! ( "./example.data" ) ;
115- let ( sleepers, scores) = part1 ( example. to_owned ( ) ) ;
116- let result = format_results ( & sleepers, & scores) ;
117- assert_eq ! ( 240 , result) ;
118- let prod = include_str ! ( "./prod.data" ) ;
119- let ( sleepers, scores) = part1 ( prod. to_owned ( ) ) ;
120- let result = format_results ( & sleepers, & scores) ;
121- assert_eq ! ( 76357 , result) ;
49+ fn part1 ( & self , input : & str ) -> Box < dyn Display > {
50+ let sleepers = get_sleeps ( input) ;
51+ let scores: HashMap < usize , u32 > = sleepers. iter ( ) . map ( |( k, v) | ( * k, v. iter ( ) . sum ( ) ) ) . collect ( ) ;
52+ let ( best_sleeper, _) = scores. iter ( ) . max_by_key ( |& ( _, v) | v) . unwrap ( ) ;
53+ let best_minute = sleepers[ best_sleeper] . iter ( ) . enumerate ( ) . max_by_key ( |& ( _, count) | count) . unwrap ( ) . 0 ;
54+ Box :: new ( best_sleeper * best_minute)
12255 }
123- #[ test]
124- #[ ignore]
125- fn test_second ( ) {
126- let example = include_str ! ( "./example.data" ) ;
127- let ( sleepers, scores) = part2 ( example. to_owned ( ) ) ;
128- let result = format_results ( & sleepers, & scores) ;
129- assert_eq ! ( 4455 , result) ;
130- let prod = include_str ! ( "./prod.data" ) ;
131- let ( sleepers, scores) = part2 ( prod. to_owned ( ) ) ;
132- let result = format_results ( & sleepers, & scores) ;
133- assert_eq ! ( 41668 , result) ;
56+
57+ fn part2 ( & self , input : & str ) -> Box < dyn Display > {
58+ let sleepers = get_sleeps ( input) ;
59+ let ( guard, ( minute, _) ) = sleepers. iter ( ) . map ( |( guard, minutes) | {
60+ ( guard, minutes. iter ( ) . enumerate ( ) . max_by_key ( |& ( _, count) | count) . unwrap ( ) )
61+ } ) . max_by_key ( |& ( _, ( _, count) ) | count) . unwrap ( ) ;
62+ Box :: new ( guard * minute)
13463 }
13564}
0 commit comments