Advent of Code solutions
1use std::path::Path;
2
3use regex::Regex;
4
5use crate::MAX_DAY;
6
7const DAY_TEMPLATE: &str = "
8use advent_core::{Day, day_stuff, ex_for_day};
9
10pub struct Day{day};
11
12impl Day for Day{day} {
13
14 day_stuff!({day}, \"\", \"\");
15
16 fn part_1(_input: Self::Input) -> Option<String> {
17 None
18 }
19
20 fn part_2(_input: Self::Input) -> Option<String> {
21 None
22 }
23}
24";
25
26const YEAR_TEMPLATE: &str = "
27use macros::year;
28
29year!({year});
30";
31
32const RUNNER_TEMPLATE: &str = "
33use macros::year_runner;
34
35year_runner!({year});
36";
37
38const CARGO_TEMPLATE: &str = "
39[package]
40name = \"y_{year}\"
41version = \"0.1.0\"
42edition = \"2024\"
43
44[dependencies]
45advent_core = { path = \"../../advent_core\" }
46macros = { path = \"../../macros\" }
47utils = { path = \"../../utils\" }
48";
49
50fn make_day(folder: &Path, day: usize) {
51 let day = day.to_string();
52
53 let day_path = folder.join(format!("day_{}.rs", day));
54
55 let contents = DAY_TEMPLATE.replace("{day}", &day);
56
57 std::fs::write(day_path, contents).unwrap();
58}
59
60fn make_example(folder: &Path, day: usize) {
61 let day = day.to_string();
62
63 let example_path = folder.join(format!("day_{}", day));
64
65 let part_1_path = example_path.join("1.txt");
66 let part_2_path = example_path.join("2.txt");
67
68 std::fs::create_dir_all(&example_path).unwrap();
69 std::fs::write(part_1_path, "").unwrap();
70 std::fs::write(part_2_path, "").unwrap();
71}
72
73fn make_days(folder: &Path) {
74 for day in 1..=MAX_DAY {
75 make_day(folder, day);
76 }
77}
78
79fn make_examples(folder: &Path) {
80 let examples_path = folder.join("examples");
81 for day in 1..=MAX_DAY {
82 make_example(&examples_path, day);
83 }
84}
85
86fn make_lib(folder: &Path, year: &str) {
87 let lib_path = folder.join("lib.rs");
88
89 let contents = YEAR_TEMPLATE.replace("{year}", year);
90
91 std::fs::write(lib_path, contents).unwrap();
92}
93
94fn make_main(folder: &Path, year: &str) {
95 let main_path = folder.join("main.rs");
96
97 let contents = RUNNER_TEMPLATE.replace("{year}", year);
98
99 std::fs::write(main_path, contents).unwrap();
100}
101
102fn make_src(folder: &Path, year: &str) {
103 let src_path = folder.join("src");
104
105 std::fs::create_dir_all(&src_path).unwrap();
106
107 make_days(&src_path);
108 make_examples(&src_path);
109 make_lib(&src_path, year);
110 make_main(&src_path, year);
111}
112
113fn make_cargo(folder: &Path, year: &str) {
114 let cargo_path = folder.join("Cargo.toml");
115
116 let contents = CARGO_TEMPLATE.replace("{year}", year);
117
118 std::fs::write(cargo_path, contents).unwrap();
119}
120
121fn replace_year_list(new_year: &str) {
122 let main = include_str!("../../src/main.rs");
123
124 let global_runner_pattern = Regex::new(r"global_runner!\(([\d,]+)\)").unwrap();
125
126 let matches = global_runner_pattern.captures(main).unwrap();
127
128 let full = matches.get(0).unwrap().as_str();
129
130 let mut years = matches
131 .get(1)
132 .unwrap()
133 .as_str()
134 .split(',')
135 .map(|s| s.parse::<usize>().unwrap())
136 .collect::<Vec<_>>();
137
138 years.push(new_year.parse::<usize>().unwrap());
139
140 years.sort();
141
142 let new_years = years
143 .iter()
144 .map(|y| y.to_string())
145 .collect::<Vec<_>>()
146 .join(",");
147
148 let new_main = main.replace(full, &format!("global_runner!({})", new_years));
149
150 std::fs::write("src/main.rs", new_main).unwrap();
151}
152
153fn replace_cargo_dependencies(new_year: &str) {
154 let cargo = include_str!("../../Cargo.toml");
155
156 let new_dep = format!("y_{year} = {{ path = \"years/{year}\" }}", year = new_year);
157
158 let cargo = cargo.replace("[dependencies]", &format!("[dependencies]\n{}", new_dep));
159
160 std::fs::write("Cargo.toml", cargo).unwrap();
161}
162
163pub fn make_year(year: &str) {
164 let cwd = std::env::current_dir().unwrap();
165
166 let year_path = cwd.join(format!("years/{}", year));
167
168 std::fs::create_dir_all(&year_path).unwrap();
169
170 make_src(&year_path, year);
171 make_cargo(&year_path, year);
172
173 replace_cargo_dependencies(year);
174 replace_year_list(year);
175}