Skip to content

Commit 7e3ef43

Browse files
committed
clippy
1 parent 409e351 commit 7e3ef43

File tree

26 files changed

+511
-537
lines changed

26 files changed

+511
-537
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ Year | Count | Days
6868

6969
## Under the hood 🎄
7070

71-
All solutions are *tested* and *verified* with numerous puzzle inputs (over 15: personal accounts, family accounts, friends' accounts and those found on GitHub). They can be considered totally generic.
71+
All solutions are *tested* and *verified* with a lot of puzzle inputs and answers (personal accounts, family accounts, friends' accounts and those found on GitHub). Thus, they can be considered totally generic.
7272

7373
By choice, I use the most recent versions of the languages, and therefore sometimes new paradigms and functionalities, since AoC is an excellent way to practice, explore and learn (while having fun!).
7474

75-
Rust solutions are mostly just `cargo clippy -- -F clippy::all -F clippy::pedantic -F clippy::nursery`, which is a pretty strong hardening. In the older ones, I allow myself to do unsafe integer casts or sign conversions. It's time-consuming to correct when you haven't necessarily planned for it from the start.
75+
Rust solutions respect `cargo clippy -- -D clippy::all -F clippy::pedantic -F clippy::nursery`, which is a pretty strong hardening (except one `clippy::too_many_lines`).
7676

77-
They also include, for the most part, unit tests taken from example puzzle statements.
77+
They also include, for the most part, unit tests taken from the examples of puzzle statements.
7878

7979
On average, with all the inputs I have, 80% of them run in less than 100ms on my Apple Silicon M1, and 95% in less than half a second.

crates/aoc/src/grid.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,14 @@ impl From<&str> for Grid<char> {
370370
#[inline]
371371
#[must_use]
372372
fn from(value: &str) -> Self {
373-
Self::parse(value)
373+
Self::parse(value, '#')
374374
}
375375
}
376376

377377
impl Grid<char> {
378378
/// # Panics
379379
#[must_use]
380-
pub fn parse(input: &str) -> Self {
380+
pub fn parse(input: &str, exterior: char) -> Self {
381381
let lines: Vec<_> = input.lines().collect();
382382

383383
let width = lines.iter().map(|row| row.len()).max().unwrap();
@@ -393,7 +393,7 @@ impl Grid<char> {
393393
Self {
394394
size: Coord::new(width.try_into().unwrap(), height.try_into().unwrap()),
395395
data: g,
396-
exterior: '#',
396+
exterior,
397397
dummy: '?',
398398
}
399399
}

crates/assembunny/src/lib.rs

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -315,57 +315,62 @@ impl BunnyVM {
315315
}
316316
}
317317

318-
#[test]
319-
fn test_program() {
320-
let demo = "cpy 41 a
318+
#[cfg(test)]
319+
mod test {
320+
use super::*;
321+
322+
#[test]
323+
fn test_program() {
324+
let demo = "cpy 41 a
321325
inc a
322326
inc a
323327
dec a
324328
jnz a 2
325329
dec a";
326330

327-
let mut program = BunnyVM::new(demo);
331+
let mut program = BunnyVM::new(demo);
328332

329-
assert!(program.run(100));
330-
assert_eq!(program.registers[REG_A], 42);
331-
}
333+
assert!(program.run(100));
334+
assert_eq!(program.registers[REG_A], 42);
335+
}
332336

333-
#[test]
334-
fn test_jnz() {
335-
assert_eq!(BunnyVM::new_ip(10, 2), 12);
336-
assert_eq!(BunnyVM::new_ip(10, -2), 8);
337-
}
337+
#[test]
338+
fn test_jnz() {
339+
assert_eq!(BunnyVM::new_ip(10, 2), 12);
340+
assert_eq!(BunnyVM::new_ip(10, -2), 8);
341+
}
338342

339-
#[test]
340-
fn test_inc_a() {
341-
let mut program = BunnyVM::new("inc a");
342-
program.registers[REG_A] = 42;
343-
program.step();
344-
assert_eq!(program.registers[REG_A], 43);
345-
}
343+
#[test]
344+
fn test_inc_a() {
345+
let mut program = BunnyVM::new("inc a");
346+
program.registers[REG_A] = 42;
347+
program.step();
348+
assert_eq!(program.registers[REG_A], 43);
349+
}
346350

347-
#[test]
348-
fn test_dec_b() {
349-
let mut program = BunnyVM::new("dec b");
350-
program.registers[REG_B] = 42;
351-
program.step();
352-
assert_eq!(program.registers[REG_B], 41);
353-
}
351+
#[test]
352+
fn test_dec_b() {
353+
let mut program = BunnyVM::new("dec b");
354+
program.registers[REG_B] = 42;
355+
program.step();
356+
assert_eq!(program.registers[REG_B], 41);
357+
}
354358

355-
#[test]
356-
fn test_toggle() {
357-
let demo = "cpy 2 a
359+
#[test]
360+
fn test_toggle() {
361+
let demo = "cpy 2 a
358362
tgl a
359363
tgl a
360364
tgl a
361365
cpy 1 a
362366
dec a
363367
dec a";
364368

365-
let mut program = BunnyVM::new(demo);
369+
let mut program = BunnyVM::new(demo);
366370

367-
let ok = program.run(100);
368-
assert!(ok);
371+
let ok = program.run(100);
372+
assert!(ok);
369373

370-
assert_eq!(program.registers[REG_A], 3);
374+
assert_eq!(program.registers[REG_A], 3);
375+
}
371376
}

scripts/runall.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def run(
194194
cmdline = " ".join(map(str, cmd))
195195
cmdline = cmdline.replace(Path(__file__).parent.parent.as_posix() + "/", "")
196196
cmdline = cmdline.replace(Path.home().as_posix(), "~")
197-
print(f"{FEINT}{cmdline}{RESET}", end=CR)
197+
print(f"{FEINT}{cmdline}{RESET}", end=TRANSIENT)
198198

199199
start = time.time_ns()
200200
try:

src/main.rs

Lines changed: 111 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ fn main() -> std::io::Result<()> {
99
let args = aoc::parse_args_raw();
1010

1111
// in a YEAR/dayDAY directory, we act as the standalone binary
12-
if !args.has_option("-r") && !args.has_option("-l") && run_day()? {
12+
if args.params.is_empty() && run_day_zzz()? {
1313
return Ok(());
1414
}
1515

@@ -74,7 +74,7 @@ fn main() -> std::io::Result<()> {
7474
Ok(())
7575
}
7676

77-
fn run_day() -> std::io::Result<bool> {
77+
fn run_day_zzz() -> std::io::Result<bool> {
7878
let path = std::env::current_dir()?;
7979

8080
if let Some(day) = path.file_name() {
@@ -97,7 +97,9 @@ fn run_day() -> std::io::Result<bool> {
9797

9898
for sol in &solutions() {
9999
if sol.day == day && sol.year == year && sol.alt == alt {
100-
(sol.main)();
100+
// (sol.main)();
101+
102+
run_day(sol, true);
101103
break;
102104
}
103105
}
@@ -130,11 +132,106 @@ fn print_part_result(part: u8, answer: &str, ok: &str, day: u8) {
130132
}
131133
}
132134

133-
fn find_path(sol: &Solution) -> PathBuf {
134-
let hint = Path::new("input")
135-
.join(sol.year.to_string())
136-
.join(sol.day.to_string())
137-
.with_extension("in");
135+
fn run_all(sols: &[Solution], alt: bool) {
136+
println!("💫 {} 🎄✨ 💫", "Advent of Code".green());
137+
138+
let mut total_elapsed = Duration::ZERO;
139+
let mut puzzles = 0;
140+
let mut success = 0;
141+
let mut failed = 0;
142+
143+
for sol in sols {
144+
if sol.alt.is_some() && !alt {
145+
continue;
146+
}
147+
148+
// if sol.alt.is_none() {
149+
// continue;
150+
// }
151+
152+
if let Some((elapsed, ok, ko)) = run_day(sol, false) {
153+
puzzles += 1;
154+
total_elapsed += elapsed;
155+
success += i32::from(ok);
156+
failed += i32::from(ko);
157+
}
158+
}
159+
160+
if puzzles > 1 {
161+
println!();
162+
println!("Elapsed: {total_elapsed:#?} for {puzzles} puzzle(s) - success: {success}, failed: {failed}");
163+
}
164+
}
165+
166+
fn run_day(sol: &Solution, input_txt: bool) -> Option<(Duration, bool, bool)> {
167+
let (path_input, path_answer) = find_input_path(sol, input_txt);
168+
169+
if let Some(alt) = &sol.alt {
170+
println!(
171+
"{} day {} ({}): {}",
172+
sol.year,
173+
sol.day,
174+
alt.magenta(),
175+
path_input.as_os_str().to_str().unwrap().dimmed()
176+
);
177+
} else {
178+
println!(
179+
"{} day {}: {}",
180+
sol.year,
181+
sol.day,
182+
path_input.as_os_str().to_str().unwrap().dimmed()
183+
);
184+
}
185+
186+
if path_input.is_file() {
187+
if let Ok(data) = std::fs::read_to_string(&path_input) {
188+
// run the solution
189+
let instant = Instant::now();
190+
let (part1, part2) = (sol.solve)(&data);
191+
let elapsed = instant.elapsed();
192+
193+
let mut success = false;
194+
let mut failed = false;
195+
196+
let micros = Duration::new(elapsed.as_secs(), elapsed.subsec_micros() * 1000);
197+
198+
if let Ok(ok) = std::fs::read_to_string(path_answer) {
199+
let (ok1, ok2) = ok.trim_ascii().split_once('\n').unwrap_or((&ok, ""));
200+
201+
print_part_result(1, &part1, ok1, sol.day);
202+
print_part_result(2, &part2, ok2, sol.day);
203+
204+
if ok1.trim_ascii() == part1 && ok2.trim_ascii() == part2 {
205+
success = true;
206+
} else {
207+
failed = true;
208+
}
209+
} else {
210+
print_part_result(1, &part1, "", sol.day);
211+
print_part_result(2, &part2, "", sol.day);
212+
}
213+
214+
println!("{}", format!(" Elapsed : {micros:#?}").italic());
215+
println!();
216+
217+
return Some((elapsed, success, failed));
218+
}
219+
}
220+
221+
println!(" missing file: {}", path_input.to_str().unwrap().red());
222+
223+
None
224+
}
225+
226+
fn find_input_path(sol: &Solution, input_txt: bool) -> (PathBuf, PathBuf) {
227+
let hint = if input_txt {
228+
PathBuf::new().with_file_name("input.txt")
229+
} else {
230+
Path::new("input")
231+
.join(sol.year.to_string())
232+
.join(sol.day.to_string())
233+
.with_extension("in")
234+
};
138235

139236
let mut path = hint.clone();
140237

@@ -170,79 +267,13 @@ fn find_path(sol: &Solution) -> PathBuf {
170267
}
171268
}
172269

173-
if path.is_file() {
174-
path
175-
} else {
176-
hint
177-
}
178-
}
179-
180-
fn run_all(sols: &[Solution], alt: bool) {
181-
println!("💫 {} 🎄✨ 💫", "Advent of Code".green());
182-
183-
let mut total_elapsed = Duration::ZERO;
184-
let mut puzzles = 0;
185-
let mut success = 0;
186-
let mut failed = 0;
187-
188-
for sol in sols {
189-
if sol.alt.is_some() && !alt {
190-
continue;
191-
}
192-
193-
// if sol.alt.is_none() {
194-
// continue;
195-
// }
196-
197-
let path = find_path(sol);
198-
199-
let ok = path.with_extension("ok");
200-
201-
println!();
202-
if let Some(alt) = &sol.alt {
203-
println!("{} day {} ({}):", sol.year, sol.day, alt.magenta());
204-
} else {
205-
println!("{} day {}:", sol.year, sol.day);
206-
}
207-
208-
if path.is_file() {
209-
if let Ok(data) = std::fs::read_to_string(&path) {
210-
// run the solution
211-
let instant = Instant::now();
212-
let (part1, part2) = (sol.solve)(&data);
213-
let elapsed = instant.elapsed();
214-
215-
total_elapsed += elapsed;
216-
puzzles += 1;
217-
218-
#[allow(clippy::cast_possible_truncation)]
219-
let micros = Duration::from_micros(elapsed.as_micros() as u64);
220-
221-
if let Ok(ok) = std::fs::read_to_string(ok) {
222-
let (ok1, ok2) = ok.trim_ascii().split_once('\n').unwrap_or((&ok, ""));
223-
224-
print_part_result(1, &part1, ok1, sol.day);
225-
print_part_result(2, &part2, ok2, sol.day);
226-
227-
if ok1.trim_ascii() == part1 && ok2.trim_ascii() == part2 {
228-
success += 1;
229-
} else {
230-
failed += 1;
231-
}
232-
} else {
233-
print_part_result(1, &part1, "", sol.day);
234-
print_part_result(2, &part2, "", sol.day);
235-
}
236-
237-
println!("{}", format!(" Elapsed : {micros:#?}").italic());
238-
}
239-
} else {
240-
println!(" missing file: {}", path.to_str().unwrap().red());
241-
}
270+
if !path.is_file() {
271+
path = hint;
242272
}
243273

244-
if puzzles > 1 {
245-
println!();
246-
println!("Elapsed: {total_elapsed:#?} for {puzzles} puzzle(s) - success: {success}, failed: {failed}");
274+
if path.file_name() == Path::new("input.txt").file_name() {
275+
(path.clone(), path.with_file_name("answer.txt"))
276+
} else {
277+
(path.clone(), path.with_extension("ok"))
247278
}
248279
}

0 commit comments

Comments
 (0)