diff --git a/2016/day9/day9.rs b/2016/day9/day9.rs index 741847d..a098cbd 100644 --- a/2016/day9/day9.rs +++ b/2016/day9/day9.rs @@ -9,12 +9,12 @@ fn main() { } /// Do part 1 of the puzzle -fn part1(data: &str) -> usize { - data.split('\n').fold(0, |acc, line| acc + expand_v1(line).len()) +fn part1(data: &str) -> u64 { + data.split('\n').fold(0, |acc, line| acc + expand_v1(line).len() as u64) } /// Do part 2 of the puzzle -fn part2(data: &str) -> usize { +fn part2(data: &str) -> u64 { data.split('\n').fold(0, |acc, line| acc + expand_v2(line)) } @@ -53,12 +53,12 @@ fn expand_v1(s: &str) -> String { } /// ``expand_v2`` returns the length of expanded string according to the format v2. -fn expand_v2(s: &str) -> usize { +fn expand_v2(s: &str) -> u64 { expand(s, 2) } /// ``expand`` returns the length of the expanded string (v1 or v2). -fn expand(s: &str, version: u8) -> usize { +fn expand(s: &str, version: u8) -> u64 { let mut new_len = 0; let mut chars = s.chars(); @@ -76,13 +76,13 @@ fn expand(s: &str, version: u8) -> usize { .by_ref() .take_while(|c| *c != ')') .collect::() - .parse::() + .parse::() .unwrap(); let taken = chars.by_ref().take(take); let count = if version == 1 { - taken.count() + taken.count() as u64 } else { expand(taken.collect::().as_str(), version) }; @@ -101,7 +101,7 @@ fn expand(s: &str, version: u8) -> usize { fn test_expand_v1() { fn test_v1(s: &str, expected: &str) { assert_eq!(expand_v1(s), expected); - assert_eq!(expand(s, 1), expected.len()); + assert_eq!(expand(s, 1), expected.len() as u64); } test_v1("ADVENT", "ADVENT"); test_v1("A(1x5)BC", "ABBBBBC"); diff --git a/2020/day23/day23.rs b/2020/day23/day23.rs index 7a55001..8fd7652 100644 --- a/2020/day23/day23.rs +++ b/2020/day23/day23.rs @@ -20,7 +20,7 @@ impl Puzzle { .collect(); } - fn solve(&self, nb_cups: usize, nb_moves: usize) -> usize { + fn solve(&self, nb_cups: usize, nb_moves: usize) -> u64 { // cups are labeled from 1 to 9 (and from 10 to ncups), cup no. 0 is *unused* let cups = |i: usize| { @@ -68,13 +68,13 @@ impl Puzzle { if nb_cups > self.cups.len() { // answer for part 2 - (pos[pos[1]]) * (pos[1]) + (pos[pos[1]] as u64) * (pos[1] as u64) } else { // answer for part 1 let mut result = 0; let mut cup = pos[1]; while cup != 1 { - result = result * 10 + cup; + result = result * 10 + cup as u64; cup = pos[cup]; } result @@ -82,12 +82,12 @@ impl Puzzle { } /// Solve part one. - fn part1(&self) -> usize { + fn part1(&self) -> u64 { self.solve(self.cups.len(), 100) } /// Solve part two. - fn part2(&self) -> usize { + fn part2(&self) -> u64 { self.solve(1_000_000, 10_000_000) } } diff --git a/2022/day11/day11.cpp b/2022/day11/day11.cpp index 505c620..3eac56b 100644 --- a/2022/day11/day11.cpp +++ b/2022/day11/day11.cpp @@ -91,7 +91,7 @@ void solve(const std::vector &monkeys_orig, int rounds) { return a.inspections > b.inspections; }); - uint64_t monkey_business_level = monkeys[0].inspections * monkeys[1].inspections; + uint64_t monkey_business_level = (uint64_t)monkeys[0].inspections * (uint64_t)monkeys[1].inspections; std::cout << monkey_business_level << std::endl; } diff --git a/2022/day11/day11.rs b/2022/day11/day11.rs index ff8d6d6..266d32e 100644 --- a/2022/day11/day11.rs +++ b/2022/day11/day11.rs @@ -112,17 +112,17 @@ impl Puzzle { } /// Solves part one - fn part1(&self) -> usize { + fn part1(&self) -> u64 { self.solve(20) } /// Solve part two - fn part2(&self) -> usize { + fn part2(&self) -> u64 { self.solve(10000) } /// Solve the puzzle - fn solve(&self, rounds: usize) -> usize { + fn solve(&self, rounds: usize) -> u64 { // we need to clone the monkeys array since we modify the starting item lists let mut monkeys = self.monkeys.clone(); @@ -161,7 +161,7 @@ impl Puzzle { .map(|x| x.inspections) .collect::>(); monkey_business.sort_by(|a, b| b.cmp(a)); - monkey_business[0] * monkey_business[1] + (monkey_business[0] as u64) * (monkey_business[1] as u64) } } diff --git a/2022/day15/day15.rs b/2022/day15/day15.rs index e946998..0170b03 100644 --- a/2022/day15/day15.rs +++ b/2022/day15/day15.rs @@ -57,7 +57,7 @@ impl Puzzle { } // Solves part one - fn part1(&self) -> usize { + fn part1(&self) -> u32 { let bx_min = self.beacons.iter().map(|x| x.0).min().unwrap() - self.max_d; let bx_max = self.beacons.iter().map(|x| x.0).max().unwrap() + self.max_d; @@ -90,7 +90,7 @@ impl Puzzle { } // Solve part two - fn part2(&self) -> usize { + fn part2(&self) -> i64 { for y in 0..=self.field_size { // each sensor defines a zone where there is only one beacon // this zone is all points at a distance less than or equal to the Manhattan distance to its beacon @@ -140,7 +140,7 @@ impl Puzzle { if column.len() > 1 { let x = column.first().unwrap().1; - return (x * 4_000_000 + y) as usize; + return x * 4_000_000 + y; } } diff --git a/2022/day20/day20.rs b/2022/day20/day20.rs index 07448f7..83e7a46 100644 --- a/2022/day20/day20.rs +++ b/2022/day20/day20.rs @@ -38,25 +38,25 @@ impl Puzzle { fn decrypt(&self, key: i64, rounds: usize) -> i64 { let mut q = VecDeque::new(); - q.extend(self.numbers.iter().map(|x| (*x) * key).enumerate()); + q.extend(self.numbers.iter().map(|x| (*x) * key).zip(0..)); - let nb = self.numbers.len(); + let nb = self.numbers.len() as i64; for _ in 0..rounds { for i in 0..nb { - let mut shift = (0usize, 0i64); + let mut shift = (0, 0); while let Some(e) = q.pop_front() { - if e.0 == i { + if e.1 == i { shift = e; break; } q.push_back(e); } - match shift.1 { - o if o > 0 => q.rotate_left((o as usize) % (nb - 1)), - o if o < 0 => q.rotate_right((-o as usize) % (nb - 1)), + match shift.0 { + o if o > 0 => q.rotate_left(((o) % (nb - 1)) as usize), + o if o < 0 => q.rotate_right(((-o) % (nb - 1)) as usize), _ => (), } @@ -64,11 +64,11 @@ impl Puzzle { } } - for (i, v) in q.iter().enumerate() { - if v.1 == 0 { - return q.get((i + 1000) % nb).unwrap().1 - + q.get((i + 2000) % nb).unwrap().1 - + q.get((i + 3000) % nb).unwrap().1; + for (v, i) in q.iter().zip(0..) { + if v.0 == 0 { + return q.get(((i + 1000) % nb) as usize).unwrap().0 + + q.get(((i + 2000) % nb) as usize).unwrap().0 + + q.get(((i + 3000) % nb) as usize).unwrap().0; } } 0 diff --git a/2023/day11/day11.rs b/2023/day11/day11.rs index 735bea0..382dbdb 100644 --- a/2023/day11/day11.rs +++ b/2023/day11/day11.rs @@ -1,9 +1,9 @@ //! [Day 11: Cosmic Expansion](https://adventofcode.com/2023/day/11) struct Puzzle { - galaxies: Vec<(usize, usize)>, - empty_rows: Vec, - empty_cols: Vec, + galaxies: Vec<(u64, u64)>, + empty_rows: Vec, + empty_cols: Vec, } impl Puzzle { @@ -21,9 +21,9 @@ impl Puzzle { let mut grid = vec![]; - for (y, line) in data.lines().enumerate() { + for (line, y) in data.lines().zip(0..) { let row: Vec<_> = line.chars().collect(); - for (x, &c) in row.iter().enumerate() { + for (&c, x) in row.iter().zip(0..) { if c == '#' { self.galaxies.push((x, y)); } @@ -38,12 +38,12 @@ impl Puzzle { for x in 0..grid[0].len() { if (0..grid.len()).all(|y| grid[y][x] == '.') { - self.empty_cols.push(x); + self.empty_cols.push(x as u64); } } } - fn solve(&self, expansion_factor: usize) -> usize { + fn solve(&self, expansion_factor: u64) -> u64 { let expansion_factor = expansion_factor - 1; let mut result = 0; for (i, &(x1, y1)) in self.galaxies.iter().enumerate() { @@ -55,7 +55,7 @@ impl Puzzle { .empty_cols .iter() .filter(|&&col| x1.min(x2) <= col && col <= x1.max(x2)) - .count() + .count() as u64 * expansion_factor; // expand empty spaces vertically @@ -63,7 +63,7 @@ impl Puzzle { .empty_rows .iter() .filter(|&&row| y1.min(y2) <= row && row <= y1.max(y2)) - .count() + .count() as u64 * expansion_factor; result += distance; @@ -74,12 +74,12 @@ impl Puzzle { } /// Solve part one. - fn part1(&self) -> usize { + fn part1(&self) -> u64 { self.solve(2) } /// Solve part two. - fn part2(&self) -> usize { + fn part2(&self) -> u64 { self.solve(1_000_000) } } diff --git a/2023/day21/day21.rs b/2023/day21/day21.rs index 235cffa..696b967 100644 --- a/2023/day21/day21.rs +++ b/2023/day21/day21.rs @@ -63,7 +63,7 @@ impl Puzzle { self.garden[usize::try_from(i).unwrap()] } - fn count(&self, n: i32) -> usize { + fn count(&self, n: i32) -> u64 { // nota: still not really optimized, could probably memoize something let mut p = HashSet::new(); p.insert((self.start_x, self.start_y)); @@ -116,10 +116,10 @@ impl Puzzle { p = np; } - p.len() + p.len() as u64 } - fn big_count(&self, n: i32) -> usize { + fn big_count(&self, n: i32) -> u64 { // the step count curve is parabolic let (t, x0) = n.div_rem(&self.n); @@ -138,18 +138,18 @@ impl Puzzle { let a = y2 - 2 * y1 + y0; let b = y1 - y0; - let t = usize::try_from(t).unwrap(); + let t = u64::try_from(t).unwrap(); a * t * (t - 1) / 2 + b * t + y0 } /// Solve part one. - fn part1(&self) -> usize { + fn part1(&self) -> u64 { self.count(64) } /// Solve part two. - fn part2(&self) -> usize { + fn part2(&self) -> u64 { self.big_count(26_501_365) } } diff --git a/2023/day8/day8.rs b/2023/day8/day8.rs index fb623d3..cdf6e81 100644 --- a/2023/day8/day8.rs +++ b/2023/day8/day8.rs @@ -3,7 +3,7 @@ use num::Integer; use std::collections::HashMap; -fn lcm(values: &Vec) -> usize { +fn lcm(values: &Vec) -> u64 { let mut m = 1; for x in values { m = m.lcm(x); @@ -44,7 +44,7 @@ impl Puzzle { } } - fn solve(&self, part1: bool) -> usize { + fn solve(&self, part1: bool) -> u64 { let start = u32::from_str_radix(if part1 { "AAA" } else { "A" }, 36).unwrap(); let stop = u32::from_str_radix(if part1 { "ZZZ" } else { "Z" }, 36).unwrap(); let mask = if part1 { 36 * 36 * 36 } else { 36 }; @@ -81,10 +81,10 @@ impl Puzzle { *node = new_node; if new_node % mask == stop { - z.insert(i, n); + z.insert(i, n as u64); if z.len() == size { - let z = z.values().copied().collect::>(); + let z: Vec<_> = z.values().copied().collect(); return lcm(&z); } } @@ -93,12 +93,12 @@ impl Puzzle { } /// Solve part one. - fn part1(&self) -> usize { + fn part1(&self) -> u64 { self.solve(true) } /// Solve part two. - fn part2(&self) -> usize { + fn part2(&self) -> u64 { self.solve(false) } } diff --git a/scripts/runall.py b/scripts/runall.py index 0abf53f..8826d0b 100755 --- a/scripts/runall.py +++ b/scripts/runall.py @@ -199,28 +199,33 @@ def make(year: Path, source: Path, dest: Path, cmd: str): subprocess.check_call(cmdline, shell=True) -def build_all(filter_year: int): +def build_all(filter_year: int, filter_lang: t.Iterable[str]): for year in range(2015, 2024): if filter_year != 0 and year != filter_year: continue year = Path(str(year)) if not year.is_dir(): continue - m = year / "Cargo.toml" - if year.is_dir() and m.is_file(): - print(f"{FEINT}{ITALIC}cargo build {m}{RESET}", end=f"{CLEAR_EOL}{CR}") - subprocess.check_call(["cargo", "build", "--manifest-path", m, "--release", "--quiet"]) + + if not filter_lang or "rust" in filter_lang: + m = year / "Cargo.toml" + if year.is_dir() and m.is_file(): + print(f"{FEINT}{ITALIC}cargo build {m}{RESET}", end=f"{CLEAR_EOL}{CR}") + subprocess.check_call(["cargo", "build", "--manifest-path", m, "--release", "--quiet"]) for day in range(1, 26): - src = year / f"day{day}" / f"day{day}.c" - if src.is_file(): - print(f"{FEINT}{ITALIC}compile {src}{RESET}", end=f"{CLEAR_EOL}{CR}") - make(year, src, f"day{day}_c", "cc -std=c11") - src = year / f"day{day}" / f"day{day}.cpp" - if src.is_file(): - print(f"{FEINT}{ITALIC}compile {src}{RESET}", end=f"{CLEAR_EOL}{CR}") - make(year, src, f"day{day}_cpp", "c++ -std=c++17") + if not filter_lang or "c" in filter_lang: + src = year / f"day{day}" / f"day{day}.c" + if src.is_file(): + print(f"{FEINT}{ITALIC}compile {src}{RESET}", end=f"{CLEAR_EOL}{CR}") + make(year, src, f"day{day}_c", "cc -std=c11") + + if not filter_lang or "c++" in filter_lang: + src = year / f"day{day}" / f"day{day}.cpp" + if src.is_file(): + print(f"{FEINT}{ITALIC}compile {src}{RESET}", end=f"{CLEAR_EOL}{CR}") + make(year, src, f"day{day}_cpp", "c++ -std=c++17") def load_data(filter_year, filter_user, filter_yearday): @@ -366,7 +371,6 @@ def run_day( def get_languages(filter_lang: t.Iterable[str]) -> t.Dict[str, t.Tuple[str, t.Union[str, None]]]: - filter_lang = set(map(str.casefold, filter_lang or ())) languages = {} for lang, v in LANGUAGES.items(): @@ -377,6 +381,16 @@ def get_languages(filter_lang: t.Iterable[str]) -> t.Dict[str, t.Tuple[str, t.Un if "/" not in interpreter and "\\" not in interpreter: interpreter = shutil.which(interpreter) + if not interpreter: + continue + + if lang == "Python": + hexversion = int( + subprocess.check_output([interpreter, "-c", "import sys;print(sys.hexversion)"]).decode() + ) + if hexversion < 0x30A0000: # 3.10.x + continue + languages[lang2] = (v, interpreter) else: interpreter = Path(interpreter).expanduser().absolute() @@ -458,7 +472,9 @@ def main(): if args.venv: return install_venv(args.venv) - languages = get_languages(args.language) + filter_lang = set(map(str.casefold, args.language or ())) + + languages = get_languages(filter_lang) args.exclude = args.exclude or [] if args.no_slow: @@ -471,16 +487,12 @@ def main(): " -x 2022:15" " -x 2023:5 -x 2023:10 -x 2023:23".split() ) - if args.no_64: - args.exclude.extend( - " -x 2016:9 -x 2016:15" " -x 2022:11 -x 2022:20" " -x 2020:23" " -x 2023:8 -x 2023:11 -x 2023:21" - ) filter_year = 0 if len(args.n) == 0 else int(args.n.pop(0)) filter_day = set(args.n) if not args.no_build: - build_all(filter_year) + build_all(filter_year, filter_lang) print(end=f"{CR}{CLEAR_EOL}") inputs, sols = load_data(filter_year, args.filter_user, args.exclude) @@ -510,18 +522,22 @@ def main(): save_cache() if elapsed: - print( - f"{CLEAR_EOL}--> ", - " | ".join((f"{lang} : {t:.3f}s" for lang, t in elapsed.items())), - f"{FEINT}({nb_samples} input{'s' if nb_samples>1 else ''}){RESET}", - ) + if nb_samples > 1: + print( + f"{CR}{CLEAR_EOL}--> ", + " | ".join((f"{lang} : {t:.3f}s" for lang, t in elapsed.items())), + f"{FEINT}({nb_samples} input{'s' if nb_samples>1 else ''}){RESET}", + ) + else: + print(end=f"{CR}{CLEAR_EOL}") + for lang, e in elapsed.items(): stats_elapsed[year, day, lang] = e if filter_year == 0: print( "==========================" # prefix - " ===============================" # language, status + " ===========================" # language, status " ========================================" # answers " ==================================" # input path )