@@ -4,22 +4,22 @@ use aoc::*;
4
4
use std:: env:: args;
5
5
use std:: fs:: read_to_string;
6
6
use std:: iter:: empty;
7
- use std:: path:: { Path , PathBuf } ;
7
+ use std:: path:: Path ;
8
8
use std:: time:: { Duration , Instant } ;
9
9
10
10
fn main ( ) {
11
11
// Parse command line options
12
12
let ( year, day) = match args ( ) . nth ( 1 ) {
13
13
Some ( arg) => {
14
14
let str = arg. as_str ( ) ;
15
- let mut iter = str. iter_unsigned ( ) ;
15
+ let mut iter = str. iter_unsigned :: < u32 > ( ) ;
16
16
( iter. next ( ) , iter. next ( ) )
17
17
}
18
18
None => ( None , None ) ,
19
19
} ;
20
20
21
- // Filter solutions
22
- let solutions : Vec < _ > = empty ( )
21
+ // Filter solutions then pretty print output.
22
+ let ( stars , duration ) = empty ( )
23
23
. chain ( year2015 ( ) )
24
24
. chain ( year2016 ( ) )
25
25
. chain ( year2017 ( ) )
@@ -30,40 +30,40 @@ fn main() {
30
30
. chain ( year2022 ( ) )
31
31
. chain ( year2023 ( ) )
32
32
. chain ( year2024 ( ) )
33
- . filter ( |solution| year. is_none_or ( |y : u32 | y == solution. year ) )
34
- . filter ( |solution| day. is_none_or ( |d : u32 | d == solution. day ) )
35
- . collect ( ) ;
36
-
37
- // Pretty print output for each solution.
38
- let mut duration = Duration :: ZERO ;
39
-
40
- for Solution { year, day, path, wrapper } in & solutions {
41
- if let Ok ( data) = read_to_string ( path) {
42
- let instant = Instant :: now ( ) ;
43
- let ( part1, part2) = wrapper ( data) ;
44
- duration += instant. elapsed ( ) ;
45
-
46
- println ! ( "{BOLD}{YELLOW}{year} Day {day:02}{RESET}" ) ;
47
- println ! ( " Part 1: {part1}" ) ;
48
- println ! ( " Part 2: {part2}" ) ;
49
- } else {
50
- eprintln ! ( "{BOLD}{RED}{year} Day {day:02}{RESET}" ) ;
51
- eprintln ! ( " Missing input!" ) ;
52
- eprintln ! ( " Place input file in {BOLD}{WHITE}{}{RESET}" , path. display( ) ) ;
53
- }
54
- }
33
+ . filter ( |solution| year. is_none_or ( |y| y == solution. year . unsigned ( ) ) )
34
+ . filter ( |solution| day. is_none_or ( |d| d == solution. day . unsigned ( ) ) )
35
+ . fold ( ( 0 , Duration :: ZERO ) , |( stars, duration) , Solution { year, day, wrapper } | {
36
+ let path = Path :: new ( "input" ) . join ( year) . join ( day) . with_extension ( "txt" ) ;
37
+
38
+ if let Ok ( data) = read_to_string ( & path) {
39
+ let instant = Instant :: now ( ) ;
40
+ let ( part1, part2) = wrapper ( data) ;
41
+ let elapsed = instant. elapsed ( ) ;
42
+
43
+ println ! ( "{BOLD}{YELLOW}{} Day {}{RESET}" , & year[ 4 ..] , & day[ 3 ..] ) ;
44
+ println ! ( " Part 1: {part1}" ) ;
45
+ println ! ( " Part 2: {part2}" ) ;
46
+
47
+ ( stars + 2 , duration + elapsed)
48
+ } else {
49
+ eprintln ! ( "{BOLD}{RED}{} Day {}{RESET}" , & year[ 4 ..] , & day[ 3 ..] ) ;
50
+ eprintln ! ( " Missing input!" ) ;
51
+ eprintln ! ( " Place input file in {BOLD}{WHITE}{}{RESET}" , path. display( ) ) ;
52
+
53
+ ( stars, duration)
54
+ }
55
+ } ) ;
55
56
56
57
// Optionally print totals.
57
58
if args ( ) . any ( |a| a == "--totals" ) {
58
- println ! ( "{BOLD}{YELLOW}⭐ {}{RESET}" , 2 * solutions . len ( ) ) ;
59
+ println ! ( "{BOLD}{YELLOW}⭐ {}{RESET}" , stars ) ;
59
60
println ! ( "{BOLD}{WHITE}🕓 {} ms{RESET}" , duration. as_millis( ) ) ;
60
61
}
61
62
}
62
63
63
64
struct Solution {
64
- year : u32 ,
65
- day : u32 ,
66
- path : PathBuf ,
65
+ year : & ' static str ,
66
+ day : & ' static str ,
67
67
wrapper : fn ( String ) -> ( String , String ) ,
68
68
}
69
69
@@ -73,8 +73,6 @@ macro_rules! run {
73
73
vec![ $( {
74
74
let year = stringify!( $year) ;
75
75
let day = stringify!( $day) ;
76
- let path = Path :: new( "input" ) . join( year) . join( day) . with_extension( "txt" ) ;
77
-
78
76
let wrapper = |data: String | {
79
77
use $year:: $day:: * ;
80
78
@@ -85,7 +83,7 @@ macro_rules! run {
85
83
( part1. to_string( ) , part2. to_string( ) )
86
84
} ;
87
85
88
- Solution { year: year . unsigned ( ) , day: day . unsigned ( ) , path , wrapper }
86
+ Solution { year, day, wrapper }
89
87
} , ) * ]
90
88
}
91
89
}
0 commit comments