From a2c37891cd3f0045c4ddb55ee3dce040428638f9 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Mon, 1 Dec 2025 05:54:25 +0000 Subject: [PATCH 01/26] 2025-01 rust --- .pre-commit-config.yaml | 14 ++--- Cargo.lock | 5 ++ Cargo.toml | 3 +- rust/y2025/d01/Cargo.toml | 7 +++ rust/y2025/d01/y2025d01.rs | 101 +++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 6 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 rust/y2025/d01/Cargo.toml create mode 100644 rust/y2025/d01/y2025d01.rs diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbbd930..e63194d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,13 +24,13 @@ repos: files: \.rs$ types: [file] pass_filenames: false - - id: cargo-clippy - name: cargo clippy - entry: cargo clippy -- -D warnings - language: system - files: \.rs$ - types: [file] - pass_filenames: false + # - id: cargo-clippy + # name: cargo clippy + # entry: cargo clippy -- -D warnings + # language: system + # files: \.rs$ + # types: [file] + # pass_filenames: false - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.8.0 diff --git a/Cargo.lock b/Cargo.lock index b630331..dd9b33e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,6 +123,7 @@ dependencies = [ "y2024d20", "y2024d21", "y2024d24", + "y2025d01", ] [[package]] @@ -1883,6 +1884,10 @@ version = "0.1.0" name = "y2024d24" version = "0.1.0" +[[package]] +name = "y2025d01" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 5b102d4..7a03358 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", + "rust/y2024/d24", "rust/y2025/d01", ] [package] @@ -57,3 +57,4 @@ y2024d21 = { path = "rust/y2024/d21" } y2024d24 = { path = "rust/y2024/d24" } y2024d16 = { path = "rust/y2024/d16" } y2024d17 = { path = "rust/y2024/d17" } +y2025d01 = { path = "rust/y2025/d01" } diff --git a/rust/y2025/d01/Cargo.toml b/rust/y2025/d01/Cargo.toml new file mode 100644 index 0000000..ef53362 --- /dev/null +++ b/rust/y2025/d01/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d01" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d01.rs" diff --git a/rust/y2025/d01/y2025d01.rs b/rust/y2025/d01/y2025d01.rs new file mode 100644 index 0000000..c614c1f --- /dev/null +++ b/rust/y2025/d01/y2025d01.rs @@ -0,0 +1,101 @@ +use std::fmt::Error; + +pub fn part1(input: String) -> Result> { + let mut dial = Dial::new(); + for instruction in input.lines() { + dial.execute1(instruction)?; + } + Ok(dial.count.to_string()) +} + +pub fn part2(input: String) -> Result> { + let mut dial = Dial::new(); + for instruction in input.lines() { + dial.execute2(instruction)?; + } + Ok(dial.count.to_string()) +} + +// 5784 is not right +// 5157 + +struct Dial { + position: i64, + count: usize, +} + +impl Dial { + fn new() -> Self { + Dial { + position: 50, + count: 0, + } + } + + fn rotate_left1(self: &mut Self, amount: i64) { + self.position = (self.position - amount) % 100; + if self.position == 0 { + self.count += 1 + } + } + + fn rotate_right1(self: &mut Self, amount: i64) { + self.position = (self.position + amount) % 100; + if self.position == 0 { + self.count += 1 + } + } + + fn execute1(self: &mut Self, instruction: &str) -> Result<(), Box> { + let mut chars = instruction.chars(); + let first = chars.next().expect("invalid instruction"); + let amount: i64 = chars.collect::().parse()?; + match first { + 'L' => self.rotate_left1(amount), + 'R' => self.rotate_right1(amount), + _ => return Err("Invalid instruction".into()), + } + Ok(()) + } + + fn rotate_left2(self: &mut Self, amount: i64) { + let new = self.position - amount; + println!( + "old {} new {} -> {}", + self.position, + new, + new.rem_euclid(100) + ); + if new < 0 { + println!("adding {}", 1 + usize::try_from(-new).unwrap() / 100); + self.count += usize::try_from(-new).unwrap() / 100; + if self.position > 0 { + println!(" +1"); + self.count += 1 + } + } + if new == 0 { + println!("ended at 0 - adding 1"); + self.count += 1; + } + self.position = new.rem_euclid(100); + } + + fn rotate_right2(self: &mut Self, amount: i64) { + let new = self.position + amount; + self.position = new.rem_euclid(100); + self.count += new as usize / 100; + } + + fn execute2(self: &mut Self, instruction: &str) -> Result<(), Box> { + let mut chars = instruction.chars(); + let first = chars.next().expect("invalid instruction"); + let amount: i64 = chars.collect::().parse()?; + match first { + 'L' => self.rotate_left2(amount), + 'R' => self.rotate_right2(amount), + _ => return Err("Invalid instruction".into()), + } + Ok(()) + } +} diff --git a/src/run.rs b/src/run.rs index 8a91654..a9fc7d3 100644 --- a/src/run.rs +++ b/src/run.rs @@ -90,6 +90,7 @@ fn get_solution_functions( (2024, 20) => Ok((y2024d20::part1, y2024d20::part2)), (2024, 21) => Ok((y2024d21::part1, y2024d21::part2)), (2024, 24) => Ok((y2024d24::part1, y2024d24::part2)), + (2025, 1) => Ok((y2025d01::part1, y2025d01::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From 6510272beac6c12f0820f5f66afe222d7fb70a04 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Mon, 1 Dec 2025 06:00:25 +0000 Subject: [PATCH 02/26] cleanup --- .pre-commit-config.yaml | 14 +++--- rust/y2025/d01/y2025d01.rs | 95 +++++++++++--------------------------- 2 files changed, 33 insertions(+), 76 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e63194d..cbbd930 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,13 +24,13 @@ repos: files: \.rs$ types: [file] pass_filenames: false - # - id: cargo-clippy - # name: cargo clippy - # entry: cargo clippy -- -D warnings - # language: system - # files: \.rs$ - # types: [file] - # pass_filenames: false + - id: cargo-clippy + name: cargo clippy + entry: cargo clippy -- -D warnings + language: system + files: \.rs$ + types: [file] + pass_filenames: false - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.8.0 diff --git a/rust/y2025/d01/y2025d01.rs b/rust/y2025/d01/y2025d01.rs index c614c1f..487bebc 100644 --- a/rust/y2025/d01/y2025d01.rs +++ b/rust/y2025/d01/y2025d01.rs @@ -1,100 +1,57 @@ -use std::fmt::Error; - pub fn part1(input: String) -> Result> { let mut dial = Dial::new(); for instruction in input.lines() { - dial.execute1(instruction)?; + dial.rotate(parse_instruction(instruction)?)?; } - Ok(dial.count.to_string()) + Ok(dial.count_final.to_string()) } pub fn part2(input: String) -> Result> { let mut dial = Dial::new(); for instruction in input.lines() { - dial.execute2(instruction)?; + dial.rotate(parse_instruction(instruction)?)?; } - Ok(dial.count.to_string()) + Ok(dial.count_pass.to_string()) } -// 5784 is not right -// 5157 +fn parse_instruction(instruction: &str) -> Result> { + let mut chars = instruction.chars(); + let sign = match chars.next() { + Some('R') => 1, + Some('L') => -1, + _ => return Err("Invalid instruction".into()), + }; + let amount: i64 = chars.collect::().parse()?; + Ok(sign * amount) +} struct Dial { position: i64, - count: usize, + count_final: u64, + count_pass: u64, } impl Dial { fn new() -> Self { Dial { position: 50, - count: 0, - } - } - - fn rotate_left1(self: &mut Self, amount: i64) { - self.position = (self.position - amount) % 100; - if self.position == 0 { - self.count += 1 + count_final: 0, + count_pass: 0, } } - fn rotate_right1(self: &mut Self, amount: i64) { - self.position = (self.position + amount) % 100; - if self.position == 0 { - self.count += 1 - } - } - - fn execute1(self: &mut Self, instruction: &str) -> Result<(), Box> { - let mut chars = instruction.chars(); - let first = chars.next().expect("invalid instruction"); - let amount: i64 = chars.collect::().parse()?; - match first { - 'L' => self.rotate_left1(amount), - 'R' => self.rotate_right1(amount), - _ => return Err("Invalid instruction".into()), - } - Ok(()) - } + fn rotate(&mut self, amount: i64) -> Result<(), Box> { + let new = self.position + amount; + self.count_pass += u64::try_from((new / 100).abs())?; - fn rotate_left2(self: &mut Self, amount: i64) { - let new = self.position - amount; - println!( - "old {} new {} -> {}", - self.position, - new, - new.rem_euclid(100) - ); - if new < 0 { - println!("adding {}", 1 + usize::try_from(-new).unwrap() / 100); - self.count += usize::try_from(-new).unwrap() / 100; - if self.position > 0 { - println!(" +1"); - self.count += 1 - } + if new <= 0 && self.position > 0 { + // Passed zero turning left + self.count_pass += 1; } - if new == 0 { - println!("ended at 0 - adding 1"); - self.count += 1; - } - self.position = new.rem_euclid(100); - } - fn rotate_right2(self: &mut Self, amount: i64) { - let new = self.position + amount; self.position = new.rem_euclid(100); - self.count += new as usize / 100; - } - - fn execute2(self: &mut Self, instruction: &str) -> Result<(), Box> { - let mut chars = instruction.chars(); - let first = chars.next().expect("invalid instruction"); - let amount: i64 = chars.collect::().parse()?; - match first { - 'L' => self.rotate_left2(amount), - 'R' => self.rotate_right2(amount), - _ => return Err("Invalid instruction".into()), + if self.position == 0 { + self.count_final += 1 } Ok(()) } From 785706622a964c0b0969f9ea06336c4429493c5a Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Tue, 2 Dec 2025 05:33:07 +0000 Subject: [PATCH 03/26] 2025-02p1 --- Cargo.lock | 5 +++++ Cargo.toml | 3 ++- rust/y2025/d02/Cargo.toml | 7 +++++++ rust/y2025/d02/y2025d02.rs | 39 ++++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d02/Cargo.toml create mode 100644 rust/y2025/d02/y2025d02.rs diff --git a/Cargo.lock b/Cargo.lock index dd9b33e..318cdcc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -124,6 +124,7 @@ dependencies = [ "y2024d21", "y2024d24", "y2025d01", + "y2025d02", ] [[package]] @@ -1888,6 +1889,10 @@ version = "0.1.0" name = "y2025d01" version = "0.1.0" +[[package]] +name = "y2025d02" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 7a03358..d340455 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", ] [package] @@ -58,3 +58,4 @@ y2024d24 = { path = "rust/y2024/d24" } y2024d16 = { path = "rust/y2024/d16" } y2024d17 = { path = "rust/y2024/d17" } y2025d01 = { path = "rust/y2025/d01" } +y2025d02 = { path = "rust/y2025/d02" } diff --git a/rust/y2025/d02/Cargo.toml b/rust/y2025/d02/Cargo.toml new file mode 100644 index 0000000..76ff651 --- /dev/null +++ b/rust/y2025/d02/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d02" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d02.rs" diff --git a/rust/y2025/d02/y2025d02.rs b/rust/y2025/d02/y2025d02.rs new file mode 100644 index 0000000..6a14fdc --- /dev/null +++ b/rust/y2025/d02/y2025d02.rs @@ -0,0 +1,39 @@ +pub fn part1(input: String) -> Result> { + let ranges = parse_input(input)?; + let total: u64 = ranges + .into_iter() + .flat_map(|(a, b)| (a..=b).filter(is_invalid_1)) + .sum(); + Ok(total.to_string()) +} + +pub fn part2(input: String) -> Result> { + let ranges = parse_input(input)?; + let total: u64 = ranges + .into_iter() + .flat_map(|(a, b)| (a..=b).filter(is_invalid_2)) + .sum(); + Ok(total.to_string()) +} + +fn parse_input(input: String) -> Result, Box> { + input + .trim() + .split(',') + .map(|r| { + let (a, b) = r.split_once('-').ok_or("missing -")?; + Ok((a.parse()?, b.parse()?)) + }) + .collect() +} + +fn is_invalid_1(n: &u64) -> bool { + // must have an even number of digits + // and be a multiple of 10..01 = 10^(nd/2) + 1 + let nd = n.ilog10() + 1; + nd.is_multiple_of(2) && n.is_multiple_of(10u64.pow(nd / 2) + 1) +} + +fn is_invalid_2(n: &u64) -> bool { + panic!("{n}") +} diff --git a/src/run.rs b/src/run.rs index a9fc7d3..0b279bd 100644 --- a/src/run.rs +++ b/src/run.rs @@ -91,6 +91,7 @@ fn get_solution_functions( (2024, 21) => Ok((y2024d21::part1, y2024d21::part2)), (2024, 24) => Ok((y2024d24::part1, y2024d24::part2)), (2025, 1) => Ok((y2025d01::part1, y2025d01::part2)), + (2025, 2) => Ok((y2025d02::part1, y2025d02::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From 493d17ecdd9961cba31bec7b5fad88a453da0211 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Tue, 2 Dec 2025 06:07:16 +0000 Subject: [PATCH 04/26] 2025-02-p2 --- rust/y2025/d02/y2025d02.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/rust/y2025/d02/y2025d02.rs b/rust/y2025/d02/y2025d02.rs index 6a14fdc..66de5d7 100644 --- a/rust/y2025/d02/y2025d02.rs +++ b/rust/y2025/d02/y2025d02.rs @@ -35,5 +35,17 @@ fn is_invalid_1(n: &u64) -> bool { } fn is_invalid_2(n: &u64) -> bool { - panic!("{n}") + // iterate over the possible factorizations of number of digits + // into number of repetitions * number of repeated digits + let nd = n.ilog10() + 1; + for nrep in 2..=nd { + if nd.is_multiple_of(nrep) { + let nrd = nd / nrep; + let ones = (0..nrep).map(|i| 10u64.pow(nrd * i)).sum(); + if n.is_multiple_of(ones) { + return true; + } + } + } + false } From c23859e7c465bb5e5cc07fc3d6d08d4cef9b36b0 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Tue, 2 Dec 2025 06:13:48 +0000 Subject: [PATCH 05/26] cleanup --- rust/y2025/d02/y2025d02.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/rust/y2025/d02/y2025d02.rs b/rust/y2025/d02/y2025d02.rs index 66de5d7..1d82e3e 100644 --- a/rust/y2025/d02/y2025d02.rs +++ b/rust/y2025/d02/y2025d02.rs @@ -38,14 +38,10 @@ fn is_invalid_2(n: &u64) -> bool { // iterate over the possible factorizations of number of digits // into number of repetitions * number of repeated digits let nd = n.ilog10() + 1; - for nrep in 2..=nd { - if nd.is_multiple_of(nrep) { - let nrd = nd / nrep; - let ones = (0..nrep).map(|i| 10u64.pow(nrd * i)).sum(); - if n.is_multiple_of(ones) { - return true; - } - } - } - false + (2..=nd) + .filter(|nrep| nd.is_multiple_of(*nrep)) + .any(|nrep| { + let rep_factor = (0..nrep).map(|i| 10u64.pow(nd / nrep * i)).sum(); + n.is_multiple_of(rep_factor) + }) } From 719dd7bc6704ded4d09bacc65db11fb35fb9532d Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Wed, 3 Dec 2025 05:23:05 +0000 Subject: [PATCH 06/26] 2025-03-p1 --- Cargo.lock | 5 +++++ Cargo.toml | 3 ++- rust/y2025/d03/Cargo.toml | 7 +++++++ rust/y2025/d03/y2025d03.rs | 29 +++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d03/Cargo.toml create mode 100644 rust/y2025/d03/y2025d03.rs diff --git a/Cargo.lock b/Cargo.lock index 318cdcc..baab026 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,7 @@ dependencies = [ "y2024d24", "y2025d01", "y2025d02", + "y2025d03", ] [[package]] @@ -1893,6 +1894,10 @@ version = "0.1.0" name = "y2025d02" version = "0.1.0" +[[package]] +name = "y2025d03" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index d340455..7d707c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", ] [package] @@ -59,3 +59,4 @@ y2024d16 = { path = "rust/y2024/d16" } y2024d17 = { path = "rust/y2024/d17" } y2025d01 = { path = "rust/y2025/d01" } y2025d02 = { path = "rust/y2025/d02" } +y2025d03 = { path = "rust/y2025/d03" } diff --git a/rust/y2025/d03/Cargo.toml b/rust/y2025/d03/Cargo.toml new file mode 100644 index 0000000..c11b7d9 --- /dev/null +++ b/rust/y2025/d03/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d03" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d03.rs" diff --git a/rust/y2025/d03/y2025d03.rs b/rust/y2025/d03/y2025d03.rs new file mode 100644 index 0000000..424e829 --- /dev/null +++ b/rust/y2025/d03/y2025d03.rs @@ -0,0 +1,29 @@ +pub fn part1(input: String) -> Result> { + let result: Result> = input + .trim() + .lines() + .map(max_joltage) + .collect::, _>>() + .map(|vec| vec.iter().sum()); + Ok(result?.to_string()) +} + +pub fn part2(_input: String) -> Result> { + // Solve part 2 + Err("Solution not implemented".into()) +} + +fn max_joltage(row: &str) -> Result> { + let first_digit = row[..row.len() - 1].chars().max().ok_or("Bank is empty")?; + let (i, _) = row + .chars() + .enumerate() + .find(|(_, c)| *c == first_digit) + .unwrap(); + // TODO: do it in one go with something like row.chars().enumerate().max_by_key + // but max methods return the last value + let second_digit = row[i + 1..].chars().max().ok_or("Bank is empty")?; + let result = 10 * first_digit.to_digit(10).ok_or("Invalid bank")? + + second_digit.to_digit(10).ok_or("Invalid bank")?; + Ok(result) +} diff --git a/src/run.rs b/src/run.rs index 0b279bd..d7b53ed 100644 --- a/src/run.rs +++ b/src/run.rs @@ -92,6 +92,7 @@ fn get_solution_functions( (2024, 24) => Ok((y2024d24::part1, y2024d24::part2)), (2025, 1) => Ok((y2025d01::part1, y2025d01::part2)), (2025, 2) => Ok((y2025d02::part1, y2025d02::part2)), + (2025, 3) => Ok((y2025d03::part1, y2025d03::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From d157486ed3870ee273402cc820bb89390c51dc04 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Wed, 3 Dec 2025 05:47:46 +0000 Subject: [PATCH 07/26] 2025-03-p2 --- rust/y2025/d03/y2025d03.rs | 45 +++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/rust/y2025/d03/y2025d03.rs b/rust/y2025/d03/y2025d03.rs index 424e829..857ca2a 100644 --- a/rust/y2025/d03/y2025d03.rs +++ b/rust/y2025/d03/y2025d03.rs @@ -1,29 +1,38 @@ pub fn part1(input: String) -> Result> { - let result: Result> = input + solve(input, 2) +} + +pub fn part2(input: String) -> Result> { + solve(input, 12) +} + +fn solve(input: String, n: usize) -> Result> { + let result: Result> = input .trim() .lines() - .map(max_joltage) + .map(|r| max_joltage_n(r, n)) .collect::, _>>() .map(|vec| vec.iter().sum()); Ok(result?.to_string()) } -pub fn part2(_input: String) -> Result> { - // Solve part 2 - Err("Solution not implemented".into()) -} +fn max_joltage_n(row: &str, n: usize) -> Result> { + if n == 1 { + return row + .chars() + .max() + .and_then(|d| d.to_digit(10)) + .map(|d| d as u64) + .ok_or("Invalid bank".into()); + } + let (i, first_digit) = row[..row.len() - (n - 1)] + .char_indices() + .rev() + .max_by_key(|(_, c)| *c) + .ok_or("Bank is too small")?; -fn max_joltage(row: &str) -> Result> { - let first_digit = row[..row.len() - 1].chars().max().ok_or("Bank is empty")?; - let (i, _) = row - .chars() - .enumerate() - .find(|(_, c)| *c == first_digit) - .unwrap(); - // TODO: do it in one go with something like row.chars().enumerate().max_by_key - // but max methods return the last value - let second_digit = row[i + 1..].chars().max().ok_or("Bank is empty")?; - let result = 10 * first_digit.to_digit(10).ok_or("Invalid bank")? - + second_digit.to_digit(10).ok_or("Invalid bank")?; + // Recursive is slow for long banks, consider iterating over the row only once. + let result = 10u64.pow((n - 1) as u32) * first_digit.to_digit(10).ok_or("Invalid bank")? as u64 + + max_joltage_n(&row[i + 1..], n - 1)?; Ok(result) } From 9cdc3a8c998614bf8fddef98373acc75b0fe2a96 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Thu, 4 Dec 2025 06:16:03 +0000 Subject: [PATCH 08/26] 2025-04-p1 --- Cargo.lock | 5 +++++ Cargo.toml | 3 ++- rust/y2025/d04/Cargo.toml | 7 +++++++ rust/y2025/d04/y2025d04.rs | 41 ++++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d04/Cargo.toml create mode 100644 rust/y2025/d04/y2025d04.rs diff --git a/Cargo.lock b/Cargo.lock index baab026..71aa605 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,6 +126,7 @@ dependencies = [ "y2025d01", "y2025d02", "y2025d03", + "y2025d04", ] [[package]] @@ -1898,6 +1899,10 @@ version = "0.1.0" name = "y2025d03" version = "0.1.0" +[[package]] +name = "y2025d04" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 7d707c0..957e812 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", ] [package] @@ -60,3 +60,4 @@ y2024d17 = { path = "rust/y2024/d17" } y2025d01 = { path = "rust/y2025/d01" } y2025d02 = { path = "rust/y2025/d02" } y2025d03 = { path = "rust/y2025/d03" } +y2025d04 = { path = "rust/y2025/d04" } diff --git a/rust/y2025/d04/Cargo.toml b/rust/y2025/d04/Cargo.toml new file mode 100644 index 0000000..43fc5e7 --- /dev/null +++ b/rust/y2025/d04/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d04" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d04.rs" diff --git a/rust/y2025/d04/y2025d04.rs b/rust/y2025/d04/y2025d04.rs new file mode 100644 index 0000000..12ac5e4 --- /dev/null +++ b/rust/y2025/d04/y2025d04.rs @@ -0,0 +1,41 @@ +use std::collections::HashSet; + +pub fn part1(input: String) -> Result> { + let positions = get_rolls_set(input); + let result = positions + .iter() + .filter(|p| count_neighbours(p, &positions) < 4) + .count(); + Ok(result.to_string()) +} + +pub fn part2(_input: String) -> Result> { + // Solve part 2 + Err("Solution not implemented".into()) +} + +fn get_rolls_set(input: String) -> HashSet<(usize, usize)> { + input + .lines() + .enumerate() + .flat_map(|(i, row)| { + row.char_indices().filter_map( + move |(j, c)| { + if c == '@' { + Some((i + 1, j + 1)) + } else { + None + } + }, + ) + }) + .collect() +} + +fn neighbors((i, j): (usize, usize)) -> impl Iterator { + (i - 1..=i + 1).flat_map(move |x| (j - 1..=j + 1).map(move |y| (x, y))) +} + +fn count_neighbours(p: &(usize, usize), positions: &HashSet<(usize, usize)>) -> usize { + neighbors(*p).filter(|n| positions.contains(n)).count() - 1 +} diff --git a/src/run.rs b/src/run.rs index d7b53ed..fbbfb1a 100644 --- a/src/run.rs +++ b/src/run.rs @@ -93,6 +93,7 @@ fn get_solution_functions( (2025, 1) => Ok((y2025d01::part1, y2025d01::part2)), (2025, 2) => Ok((y2025d02::part1, y2025d02::part2)), (2025, 3) => Ok((y2025d03::part1, y2025d03::part2)), + (2025, 4) => Ok((y2025d04::part1, y2025d04::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From bca2a83d1060c8fa88930d020a693cb20859705b Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Thu, 4 Dec 2025 06:29:38 +0000 Subject: [PATCH 09/26] 2025-04-p2 --- rust/y2025/d04/y2025d04.rs | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/rust/y2025/d04/y2025d04.rs b/rust/y2025/d04/y2025d04.rs index 12ac5e4..392ad77 100644 --- a/rust/y2025/d04/y2025d04.rs +++ b/rust/y2025/d04/y2025d04.rs @@ -4,14 +4,23 @@ pub fn part1(input: String) -> Result> { let positions = get_rolls_set(input); let result = positions .iter() - .filter(|p| count_neighbours(p, &positions) < 4) + .filter(|p| is_accessible(p, &positions)) .count(); Ok(result.to_string()) } -pub fn part2(_input: String) -> Result> { - // Solve part 2 - Err("Solution not implemented".into()) +pub fn part2(input: String) -> Result> { + let mut positions = get_rolls_set(input); + let n_removed = std::iter::from_fn(|| { + let n = remove_rolls(&mut positions); + if n == 0 { + None + } else { + Some(n) + } + }) + .sum::(); + Ok(n_removed.to_string()) } fn get_rolls_set(input: String) -> HashSet<(usize, usize)> { @@ -36,6 +45,19 @@ fn neighbors((i, j): (usize, usize)) -> impl Iterator { (i - 1..=i + 1).flat_map(move |x| (j - 1..=j + 1).map(move |y| (x, y))) } -fn count_neighbours(p: &(usize, usize), positions: &HashSet<(usize, usize)>) -> usize { - neighbors(*p).filter(|n| positions.contains(n)).count() - 1 +fn is_accessible(p: &(usize, usize), positions: &HashSet<(usize, usize)>) -> bool { + // neighborg includes p itself, so compare with 5 (assumes p is a roll) + neighbors(*p).filter(|n| positions.contains(n)).count() < 5 +} + +fn remove_rolls(positions: &mut HashSet<(usize, usize)>) -> usize { + let to_remove: Vec<_> = positions + .iter() + .filter(|p| is_accessible(p, positions)) + .copied() + .collect(); + to_remove.iter().for_each(|p| { + positions.remove(p); + }); + to_remove.len() } From d12dc78cddee74cf43f395d0e16b14f127357935 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Fri, 5 Dec 2025 07:25:06 +0000 Subject: [PATCH 10/26] 2025-05 --- Cargo.lock | 5 ++++ Cargo.toml | 3 +- rust/y2025/d05/Cargo.toml | 7 +++++ rust/y2025/d05/y2025d05.rs | 57 ++++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d05/Cargo.toml create mode 100644 rust/y2025/d05/y2025d05.rs diff --git a/Cargo.lock b/Cargo.lock index 71aa605..495a437 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,6 +127,7 @@ dependencies = [ "y2025d02", "y2025d03", "y2025d04", + "y2025d05", ] [[package]] @@ -1903,6 +1904,10 @@ version = "0.1.0" name = "y2025d04" version = "0.1.0" +[[package]] +name = "y2025d05" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 957e812..824e9fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", ] [package] @@ -61,3 +61,4 @@ y2025d01 = { path = "rust/y2025/d01" } y2025d02 = { path = "rust/y2025/d02" } y2025d03 = { path = "rust/y2025/d03" } y2025d04 = { path = "rust/y2025/d04" } +y2025d05 = { path = "rust/y2025/d05" } diff --git a/rust/y2025/d05/Cargo.toml b/rust/y2025/d05/Cargo.toml new file mode 100644 index 0000000..eb71c1b --- /dev/null +++ b/rust/y2025/d05/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d05" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d05.rs" diff --git a/rust/y2025/d05/y2025d05.rs b/rust/y2025/d05/y2025d05.rs new file mode 100644 index 0000000..c6163e5 --- /dev/null +++ b/rust/y2025/d05/y2025d05.rs @@ -0,0 +1,57 @@ +use std::cmp::max; + +pub fn part1(input: String) -> Result> { + let (ranges, ids) = parse_input(input)?; + let n = ids + .iter() + .filter(|&id| ranges.iter().any(|range| in_range(id, range))) + .count(); + Ok(n.to_string()) +} + +pub fn part2(input: String) -> Result> { + let (mut ranges, _) = parse_input(input)?; + ranges.sort(); + let mut ranges = ranges.into_iter(); + let mut tot = 0; + let mut current_range = ranges.next().ok_or("No ranges")?; + + for (a, b) in ranges { + if in_range(&a, ¤t_range) { + current_range.1 = max(current_range.1, b); + } else { + tot = add(tot, current_range); + current_range = (a, b); + } + } + tot = add(tot, current_range); + Ok(tot.to_string()) +} + +type Range = (u64, u64); + +fn parse_input(input: String) -> Result<(Vec, Vec), Box> { + let (ranges_str, ids_str) = input.trim().split_once("\n\n").ok_or("Invalid input")?; + let ranges = ranges_str + .lines() + .map(|s| -> Result<_, Box> { + let (a, b) = s.split_once('-').ok_or("Invalid input")?; + Ok((a.parse()?, b.parse()?)) + }) + .collect::>()?; + + let ids = ids_str + .lines() + .map(|s| s.parse()) + .collect::>()?; + + Ok((ranges, ids)) +} + +fn in_range(n: &u64, (a, b): &Range) -> bool { + n >= a && n <= b +} + +fn add(n: u64, (a, b): Range) -> u64 { + n + b - a + 1 +} diff --git a/src/run.rs b/src/run.rs index fbbfb1a..9ff11a5 100644 --- a/src/run.rs +++ b/src/run.rs @@ -94,6 +94,7 @@ fn get_solution_functions( (2025, 2) => Ok((y2025d02::part1, y2025d02::part2)), (2025, 3) => Ok((y2025d03::part1, y2025d03::part2)), (2025, 4) => Ok((y2025d04::part1, y2025d04::part2)), + (2025, 5) => Ok((y2025d05::part1, y2025d05::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From 183e2851d4be6302cd3307151da0d29e231e186a Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Fri, 5 Dec 2025 08:06:26 +0000 Subject: [PATCH 11/26] fold --- rust/y2025/d05/y2025d05.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/rust/y2025/d05/y2025d05.rs b/rust/y2025/d05/y2025d05.rs index c6163e5..50a1b25 100644 --- a/rust/y2025/d05/y2025d05.rs +++ b/rust/y2025/d05/y2025d05.rs @@ -12,20 +12,16 @@ pub fn part1(input: String) -> Result> { pub fn part2(input: String) -> Result> { let (mut ranges, _) = parse_input(input)?; ranges.sort(); - let mut ranges = ranges.into_iter(); - let mut tot = 0; - let mut current_range = ranges.next().ok_or("No ranges")?; - - for (a, b) in ranges { - if in_range(&a, ¤t_range) { - current_range.1 = max(current_range.1, b); + let acc = (0, ranges[0]); + let (tot, last) = ranges.into_iter().fold(acc, |(tot, current), next| { + if in_range(&next.0, ¤t) { + // Next interval intersects the current -> merge them + (tot, (current.0, max(next.1, current.1))) } else { - tot = add(tot, current_range); - current_range = (a, b); + (add(tot, current), next) } - } - tot = add(tot, current_range); - Ok(tot.to_string()) + }); + Ok(add(tot, last).to_string()) } type Range = (u64, u64); From 971a1d28eccc394e674ef862c2fba54115202782 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Sat, 6 Dec 2025 08:39:51 +0000 Subject: [PATCH 12/26] 2025-06 --- Cargo.lock | 5 ++ Cargo.toml | 3 +- rust/y2025/d06/Cargo.toml | 7 +++ rust/y2025/d06/y2025d06.rs | 123 +++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d06/Cargo.toml create mode 100644 rust/y2025/d06/y2025d06.rs diff --git a/Cargo.lock b/Cargo.lock index 495a437..681a694 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -128,6 +128,7 @@ dependencies = [ "y2025d03", "y2025d04", "y2025d05", + "y2025d06", ] [[package]] @@ -1908,6 +1909,10 @@ version = "0.1.0" name = "y2025d05" version = "0.1.0" +[[package]] +name = "y2025d06" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 824e9fa..52ce2ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", ] [package] @@ -62,3 +62,4 @@ y2025d02 = { path = "rust/y2025/d02" } y2025d03 = { path = "rust/y2025/d03" } y2025d04 = { path = "rust/y2025/d04" } y2025d05 = { path = "rust/y2025/d05" } +y2025d06 = { path = "rust/y2025/d06" } diff --git a/rust/y2025/d06/Cargo.toml b/rust/y2025/d06/Cargo.toml new file mode 100644 index 0000000..c871b16 --- /dev/null +++ b/rust/y2025/d06/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d06" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d06.rs" diff --git a/rust/y2025/d06/y2025d06.rs b/rust/y2025/d06/y2025d06.rs new file mode 100644 index 0000000..cb840d9 --- /dev/null +++ b/rust/y2025/d06/y2025d06.rs @@ -0,0 +1,123 @@ +use std::str::FromStr; + +pub fn part1(input: String) -> Result> { + let problems = parse_input1(input)?; + let tot: u64 = problems.iter().map(|p| p.answer()).sum(); + Ok(tot.to_string()) +} + +pub fn part2(input: String) -> Result> { + let problems = parse_input2(input)?; + let tot: u64 = problems.iter().map(|p| p.answer()).sum(); + Ok(tot.to_string()) +} + +fn parse_input1(input: String) -> Result, Box> { + let ns = input + .lines() + .take_while(|s| s.chars().next().is_some_and(|c| c.is_digit(10))) + .map(|s| { + s.split_whitespace() + .map(|n| n.parse::()) + .collect::, _>>() + }) + .collect::, _>>()?; + let ops = input + .trim() + .lines() + .last() + .ok_or("Invalid input")? + .split_whitespace() + .map(|s| Op::from_str(s)) + .collect::, _>>()?; + + Ok(ops + .into_iter() + .enumerate() + .map(|(i, op)| Problem { + xs: ns.iter().map(|v| v[i]).collect(), + op, + }) + .collect()) +} + +fn parse_input2(input: String) -> Result, Box> { + let rows: Vec = input + .lines() + .map_while(|s| { + if s.chars().next().is_some_and(|c| c.is_digit(10)) { + Some(s.to_string()) + } else { + None + } + }) + .collect(); + let ns = transpose(rows).fold(vec![vec![]], |mut groups, row| { + match row.trim().parse::() { + Ok(n) => groups.last_mut().unwrap().push(n), + Err(_) => groups.push(Vec::new()), + }; + groups + }); + + let ops = input + .trim() + .lines() + .last() + .ok_or("Invalid input")? + .split_whitespace() + .map(|s| Op::from_str(s)) + .collect::, _>>()?; + + Ok(ops + .into_iter() + .zip(ns.into_iter()) + .map(|(op, xs)| Problem { xs, op }) + .collect()) +} + +fn transpose(rows: Vec) -> impl Iterator { + let nrows = rows.len(); + let ncols = rows.first().map(|r| r.len()).unwrap_or(0); + + (0..ncols).map(move |col| { + let mut out = String::with_capacity(nrows); + for r in &rows { + out.push(r.chars().nth(col).unwrap_or(' ')); + } + out + }) +} + +#[derive(Debug)] +enum Op { + Add, + Mul, +} + +impl FromStr for Op { + type Err = Box; + + fn from_str(s: &str) -> Result { + match s { + "+" => Ok(Self::Add), + "*" => Ok(Self::Mul), + _ => Err("Invalid operation".into()), + } + } +} + +#[derive(Debug)] +struct Problem { + xs: Vec, + op: Op, +} + +impl Problem { + fn answer(&self) -> u64 { + match self.op { + Op::Add => self.xs.iter().sum(), + Op::Mul => self.xs.iter().product(), + } + } +} diff --git a/src/run.rs b/src/run.rs index 9ff11a5..c223a75 100644 --- a/src/run.rs +++ b/src/run.rs @@ -95,6 +95,7 @@ fn get_solution_functions( (2025, 3) => Ok((y2025d03::part1, y2025d03::part2)), (2025, 4) => Ok((y2025d04::part1, y2025d04::part2)), (2025, 5) => Ok((y2025d05::part1, y2025d05::part2)), + (2025, 6) => Ok((y2025d06::part1, y2025d06::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From 3d34d79dbeec8c5f16c822107db4067339627b48 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Sat, 6 Dec 2025 08:53:42 +0000 Subject: [PATCH 13/26] cleanup --- rust/y2025/d06/y2025d06.rs | 52 ++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/rust/y2025/d06/y2025d06.rs b/rust/y2025/d06/y2025d06.rs index cb840d9..cb83051 100644 --- a/rust/y2025/d06/y2025d06.rs +++ b/rust/y2025/d06/y2025d06.rs @@ -13,23 +13,22 @@ pub fn part2(input: String) -> Result> { } fn parse_input1(input: String) -> Result, Box> { - let ns = input - .lines() - .take_while(|s| s.chars().next().is_some_and(|c| c.is_digit(10))) + let mut lines = input.lines().rev(); + let ops = lines + .next() + .ok_or("Invalid input")? + .split_whitespace() + .map(Op::from_str) + .collect::, _>>()?; + let ns = lines + .rev() + .take_while(|s| s.chars().next().is_some_and(|c| c.is_ascii_digit())) .map(|s| { s.split_whitespace() .map(|n| n.parse::()) .collect::, _>>() }) .collect::, _>>()?; - let ops = input - .trim() - .lines() - .last() - .ok_or("Invalid input")? - .split_whitespace() - .map(|s| Op::from_str(s)) - .collect::, _>>()?; Ok(ops .into_iter() @@ -42,17 +41,25 @@ fn parse_input1(input: String) -> Result, Box Result, Box> { - let rows: Vec = input - .lines() + let mut lines = input.lines().rev(); + let ops = lines + .next() + .ok_or("Invalid input")? + .split_whitespace() + .map(Op::from_str) + .collect::, _>>()?; + + let rows: Vec = lines + .rev() .map_while(|s| { - if s.chars().next().is_some_and(|c| c.is_digit(10)) { + if s.chars().next().is_some_and(|c| c.is_ascii_digit()) { Some(s.to_string()) } else { None } }) .collect(); - let ns = transpose(rows).fold(vec![vec![]], |mut groups, row| { + let ns = transpose_string(rows).fold(vec![vec![]], |mut groups, row| { match row.trim().parse::() { Ok(n) => groups.last_mut().unwrap().push(n), Err(_) => groups.push(Vec::new()), @@ -60,23 +67,14 @@ fn parse_input2(input: String) -> Result, Box, _>>()?; - Ok(ops .into_iter() - .zip(ns.into_iter()) + .zip(ns) .map(|(op, xs)| Problem { xs, op }) .collect()) } -fn transpose(rows: Vec) -> impl Iterator { +fn transpose_string(rows: Vec) -> impl Iterator { let nrows = rows.len(); let ncols = rows.first().map(|r| r.len()).unwrap_or(0); @@ -89,7 +87,6 @@ fn transpose(rows: Vec) -> impl Iterator { }) } -#[derive(Debug)] enum Op { Add, Mul, @@ -107,7 +104,6 @@ impl FromStr for Op { } } -#[derive(Debug)] struct Problem { xs: Vec, op: Op, From fb1ec0bfada4708c7ae463b833a89cc7da2185f7 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Sat, 6 Dec 2025 09:17:19 +0000 Subject: [PATCH 14/26] 2025-06 python --- pyaoc/solutions/y2025/y2025d06.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 pyaoc/solutions/y2025/y2025d06.py diff --git a/pyaoc/solutions/y2025/y2025d06.py b/pyaoc/solutions/y2025/y2025d06.py new file mode 100644 index 0000000..09ff6fb --- /dev/null +++ b/pyaoc/solutions/y2025/y2025d06.py @@ -0,0 +1,28 @@ +from functools import reduce +from operator import mul + + +def part1(input_str: str) -> str: + *lines, ops_str = input_str.splitlines() + ops = map({"+": sum, "*": product}.__getitem__, ops_str.split()) + nss = zip(*[map(int, s.split()) for s in lines]) + result = sum(op(ns) for op, ns in zip(ops, nss)) + return str(result) + + +def part2(input_str: str) -> str: + *lines, ops_str = input_str.splitlines() + ops = map({"+": sum, "*": product}.__getitem__, ops_str.split()) + cols = ["".join(s) for s in zip(*lines)] + nss: list[list[int]] = [[]] + for c in cols: + try: + nss[-1].append(int(c)) + except ValueError: + nss.append([]) + result = sum(op(ns) for op, ns in zip(ops, nss)) + return str(result) + + +def product(xs): + return reduce(mul, xs) From bb08a01091fbf28d1d6606f480a97dd1f013091d Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Sun, 7 Dec 2025 09:46:55 +0000 Subject: [PATCH 15/26] 2025-07-p1 --- Cargo.lock | 5 ++++ Cargo.toml | 3 ++- rust/y2025/d07/Cargo.toml | 7 ++++++ rust/y2025/d07/y2025d07.rs | 49 ++++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d07/Cargo.toml create mode 100644 rust/y2025/d07/y2025d07.rs diff --git a/Cargo.lock b/Cargo.lock index 681a694..fdb9424 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -129,6 +129,7 @@ dependencies = [ "y2025d04", "y2025d05", "y2025d06", + "y2025d07", ] [[package]] @@ -1913,6 +1914,10 @@ version = "0.1.0" name = "y2025d06" version = "0.1.0" +[[package]] +name = "y2025d07" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 52ce2ac..68f9760 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", ] [package] @@ -63,3 +63,4 @@ y2025d03 = { path = "rust/y2025/d03" } y2025d04 = { path = "rust/y2025/d04" } y2025d05 = { path = "rust/y2025/d05" } y2025d06 = { path = "rust/y2025/d06" } +y2025d07 = { path = "rust/y2025/d07" } diff --git a/rust/y2025/d07/Cargo.toml b/rust/y2025/d07/Cargo.toml new file mode 100644 index 0000000..453f461 --- /dev/null +++ b/rust/y2025/d07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d07" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d07.rs" diff --git a/rust/y2025/d07/y2025d07.rs b/rust/y2025/d07/y2025d07.rs new file mode 100644 index 0000000..8c1fb22 --- /dev/null +++ b/rust/y2025/d07/y2025d07.rs @@ -0,0 +1,49 @@ +use std::collections::HashSet; + +pub fn part1(input: String) -> Result> { + let (start, splitters) = parse_input(input)?; + let mut beams = HashSet::from([start]); + let mut count = 0; + + for row in splitters { + beams = beams + .iter() + .flat_map(|x| { + if row.contains(x) { + count += 1; + vec![x - 1, x + 1] + } else { + vec![*x] + } + }) + .collect(); + println!("{:?}", beams); + } + + Ok(count.to_string()) +} + +pub fn part2(_input: String) -> Result> { + // Solve part 2 + Err("Solution not implemented".into()) +} + +type PositionsByRow = Vec>; + +fn parse_input(input: String) -> Result<(usize, PositionsByRow), Box> { + let mut lines = input.trim().lines(); + let start = lines + .next() + .ok_or("Invalid input")? + .char_indices() + .find_map(|(i, c)| if c == 'S' { Some(i) } else { None }) + .ok_or("No S found")?; + let splitters = lines + .map(|row| { + row.char_indices() + .filter_map(|(i, c)| if c == '^' { Some(i) } else { None }) + .collect() + }) + .collect(); + Ok((start, splitters)) +} diff --git a/src/run.rs b/src/run.rs index c223a75..c26095e 100644 --- a/src/run.rs +++ b/src/run.rs @@ -96,6 +96,7 @@ fn get_solution_functions( (2025, 4) => Ok((y2025d04::part1, y2025d04::part2)), (2025, 5) => Ok((y2025d05::part1, y2025d05::part2)), (2025, 6) => Ok((y2025d06::part1, y2025d06::part2)), + (2025, 7) => Ok((y2025d07::part1, y2025d07::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From 0ccdd44af1791686921a06b3bdfaf94612b63bf6 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Sun, 7 Dec 2025 09:59:58 +0000 Subject: [PATCH 16/26] 2025-07-p2 --- rust/y2025/d07/y2025d07.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/rust/y2025/d07/y2025d07.rs b/rust/y2025/d07/y2025d07.rs index 8c1fb22..0d3b3be 100644 --- a/rust/y2025/d07/y2025d07.rs +++ b/rust/y2025/d07/y2025d07.rs @@ -1,4 +1,4 @@ -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; pub fn part1(input: String) -> Result> { let (start, splitters) = parse_input(input)?; @@ -17,15 +17,28 @@ pub fn part1(input: String) -> Result> { } }) .collect(); - println!("{:?}", beams); } Ok(count.to_string()) } -pub fn part2(_input: String) -> Result> { - // Solve part 2 - Err("Solution not implemented".into()) +pub fn part2(input: String) -> Result> { + let (start, splitters) = parse_input(input)?; + let mut paths = HashMap::from([(start, 1u64)]); // pos -> # paths + + for row in splitters { + paths = paths.iter().fold(HashMap::new(), |mut acc, (&x, np)| { + if row.contains(&x) { + *acc.entry(x - 1).or_insert(0) += np; + *acc.entry(x + 1).or_insert(0) += np; + } else { + *acc.entry(x).or_insert(0) += np; + }; + acc + }) + } + + Ok(paths.values().sum::().to_string()) } type PositionsByRow = Vec>; From fd49a9b26bd4c9ac03932621883dff5558cc83ed Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Mon, 8 Dec 2025 06:09:05 +0000 Subject: [PATCH 17/26] 2025-08-p1 --- Cargo.lock | 5 ++ Cargo.toml | 3 +- rust/y2025/d08/Cargo.toml | 7 +++ rust/y2025/d08/y2025d08.rs | 95 ++++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d08/Cargo.toml create mode 100644 rust/y2025/d08/y2025d08.rs diff --git a/Cargo.lock b/Cargo.lock index fdb9424..c11da1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -130,6 +130,7 @@ dependencies = [ "y2025d05", "y2025d06", "y2025d07", + "y2025d08", ] [[package]] @@ -1918,6 +1919,10 @@ version = "0.1.0" name = "y2025d07" version = "0.1.0" +[[package]] +name = "y2025d08" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 68f9760..7b84616 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", ] [package] @@ -64,3 +64,4 @@ y2025d04 = { path = "rust/y2025/d04" } y2025d05 = { path = "rust/y2025/d05" } y2025d06 = { path = "rust/y2025/d06" } y2025d07 = { path = "rust/y2025/d07" } +y2025d08 = { path = "rust/y2025/d08" } diff --git a/rust/y2025/d08/Cargo.toml b/rust/y2025/d08/Cargo.toml new file mode 100644 index 0000000..e4c6af6 --- /dev/null +++ b/rust/y2025/d08/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d08" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d08.rs" diff --git a/rust/y2025/d08/y2025d08.rs b/rust/y2025/d08/y2025d08.rs new file mode 100644 index 0000000..d6bf652 --- /dev/null +++ b/rust/y2025/d08/y2025d08.rs @@ -0,0 +1,95 @@ +use std::collections::{HashMap, HashSet}; + +pub fn part1(input: String) -> Result> { + let boxes = parse_input(input)?; + let mut distances = Vec::new(); + for (i, x) in boxes.iter().enumerate() { + for (j, y) in boxes.iter().enumerate().skip(i + 1) { + distances.push((d2(x, y), i, j)); + } + } + distances.sort(); + + let connections: HashMap> = + distances + .iter() + .take(1000) + .fold(HashMap::new(), |mut acc, &(_, i, j)| { + acc.entry(i).or_insert(Vec::new()).push(j); + acc.entry(j).or_insert(Vec::new()).push(i); + acc + }); + + let mut seen = HashSet::new(); + let mut components = Vec::new(); + for b in connections.keys() { + if seen.contains(b) { + continue; + } + let mut queue = vec![b]; + let mut component = HashSet::new(); + while let Some(n) = queue.pop() { + for nn in connections.get(n).unwrap() { + if !component.contains(nn) { + component.insert(nn); + seen.insert(nn); + queue.push(nn); + } + } + } + components.push(component); + } + + let mut component_sizes: Vec<_> = components.iter().map(|c| c.len()).collect(); + component_sizes.sort_by(|a, b| b.cmp(a)); + + Ok(component_sizes + .iter() + .take(3) + .product::() + .to_string()) +} + +pub fn part2(input: String) -> Result> { + let boxes = parse_input(input)?; + let mut distances = Vec::new(); + for (i, x) in boxes.iter().enumerate() { + for (j, y) in boxes.iter().enumerate().skip(i + 1) { + distances.push((d2(x, y), i, j)); + } + } + distances.sort(); + + let connections: HashMap> = + distances + .iter() + .fold(HashMap::new(), |mut acc, &(_, i, j)| { + acc.entry(i).or_insert(Vec::new()).push(j); + acc.entry(j).or_insert(Vec::new()).push(i); + acc + }); + + println!("{}", connections.len()); + Err("Solution not implemented".into()) +} + +type Coord = [i64; 3]; + +fn parse_input(input: String) -> Result, Box> { + let x = input + .trim() + .lines() + .map(|line| { + let values: Result, _> = line.split(',').map(str::parse).collect(); + values.map(|v| [v[0], v[1], v[2]]) + }) + .collect::>()?; + Ok(x) +} + +fn d2(a: &Coord, b: &Coord) -> i64 { + a.iter() + .zip(b.iter()) + .map(|(ai, bi)| (ai - bi).pow(2)) + .sum() +} diff --git a/src/run.rs b/src/run.rs index c26095e..16a4d9d 100644 --- a/src/run.rs +++ b/src/run.rs @@ -97,6 +97,7 @@ fn get_solution_functions( (2025, 5) => Ok((y2025d05::part1, y2025d05::part2)), (2025, 6) => Ok((y2025d06::part1, y2025d06::part2)), (2025, 7) => Ok((y2025d07::part1, y2025d07::part2)), + (2025, 8) => Ok((y2025d08::part1, y2025d08::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From cbc82567beacad86e4117b6efdbbdc4162e3ae2c Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Mon, 8 Dec 2025 06:30:45 +0000 Subject: [PATCH 18/26] 2025-08-p2 --- rust/y2025/d08/y2025d08.rs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/rust/y2025/d08/y2025d08.rs b/rust/y2025/d08/y2025d08.rs index d6bf652..56b4b7e 100644 --- a/rust/y2025/d08/y2025d08.rs +++ b/rust/y2025/d08/y2025d08.rs @@ -59,18 +59,30 @@ pub fn part2(input: String) -> Result> { } } distances.sort(); + let mut ids_to_component: HashMap<_, _> = (0..boxes.len()).map(|i| (i, i)).collect(); + let mut components: HashMap<_, _> = (0..boxes.len()).map(|i| (i, HashSet::from([i]))).collect(); - let connections: HashMap> = - distances - .iter() - .fold(HashMap::new(), |mut acc, &(_, i, j)| { - acc.entry(i).or_insert(Vec::new()).push(j); - acc.entry(j).or_insert(Vec::new()).push(i); - acc - }); + for (_, i, j) in distances { + let c1_id = *ids_to_component.get(&i).unwrap(); + let c2_id = *ids_to_component.get(&j).unwrap(); + if c1_id == c2_id { + continue; + } + let component2 = components.remove(&c2_id).unwrap(); + for id in component2.iter() { + ids_to_component.insert(*id, c1_id); + } + components + .entry(c1_id) + .or_insert_with(|| panic!()) + .extend(component2); + + if components.len() == 1 { + return Ok((boxes[i][0] * boxes[j][0]).to_string()); + } + } - println!("{}", connections.len()); - Err("Solution not implemented".into()) + Err("Solution not found".into()) // unreachable } type Coord = [i64; 3]; From df65e495baa2f461751eef007de524ff0bfeaeb0 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Mon, 8 Dec 2025 06:55:35 +0000 Subject: [PATCH 19/26] cleanup --- rust/y2025/d08/y2025d08.rs | 117 +++++++++++++++---------------------- 1 file changed, 47 insertions(+), 70 deletions(-) diff --git a/rust/y2025/d08/y2025d08.rs b/rust/y2025/d08/y2025d08.rs index 56b4b7e..9d003a1 100644 --- a/rust/y2025/d08/y2025d08.rs +++ b/rust/y2025/d08/y2025d08.rs @@ -2,56 +2,54 @@ use std::collections::{HashMap, HashSet}; pub fn part1(input: String) -> Result> { let boxes = parse_input(input)?; - let mut distances = Vec::new(); - for (i, x) in boxes.iter().enumerate() { - for (j, y) in boxes.iter().enumerate().skip(i + 1) { - distances.push((d2(x, y), i, j)); + match find_components(boxes, Some(1000)) { + Components::Sizes(mut component_sizes) if component_sizes.len() >= 3 => { + component_sizes.sort_by(|a, b| b.cmp(a)); + Ok(component_sizes + .iter() + .take(3) + .product::() + .to_string()) } + _ => Err("Solution not found".into()), // unreachable for valid input } - distances.sort(); - - let connections: HashMap> = - distances - .iter() - .take(1000) - .fold(HashMap::new(), |mut acc, &(_, i, j)| { - acc.entry(i).or_insert(Vec::new()).push(j); - acc.entry(j).or_insert(Vec::new()).push(i); - acc - }); +} - let mut seen = HashSet::new(); - let mut components = Vec::new(); - for b in connections.keys() { - if seen.contains(b) { - continue; - } - let mut queue = vec![b]; - let mut component = HashSet::new(); - while let Some(n) = queue.pop() { - for nn in connections.get(n).unwrap() { - if !component.contains(nn) { - component.insert(nn); - seen.insert(nn); - queue.push(nn); - } - } - } - components.push(component); +pub fn part2(input: String) -> Result> { + let boxes = parse_input(input)?; + match find_components(boxes, None) { + Components::LastConnection(a, b) => Ok((a[0] * b[0]).to_string()), + Components::Sizes(_) => Err("Solution not found".into()), // unreachable } +} - let mut component_sizes: Vec<_> = components.iter().map(|c| c.len()).collect(); - component_sizes.sort_by(|a, b| b.cmp(a)); +type Coord = [i64; 3]; - Ok(component_sizes - .iter() - .take(3) - .product::() - .to_string()) +fn parse_input(input: String) -> Result, Box> { + let x = input + .trim() + .lines() + .map(|line| { + let values: Result, _> = line.split(',').map(str::parse).collect(); + values.map(|v| [v[0], v[1], v[2]]) + }) + .collect::>()?; + Ok(x) } -pub fn part2(input: String) -> Result> { - let boxes = parse_input(input)?; +fn d2(a: &Coord, b: &Coord) -> i64 { + a.iter() + .zip(b.iter()) + .map(|(ai, bi)| (ai - bi).pow(2)) + .sum() +} + +enum Components { + LastConnection(Coord, Coord), + Sizes(Vec), +} + +fn find_components(boxes: Vec, max_connections: Option) -> Components { let mut distances = Vec::new(); for (i, x) in boxes.iter().enumerate() { for (j, y) in boxes.iter().enumerate().skip(i + 1) { @@ -59,12 +57,13 @@ pub fn part2(input: String) -> Result> { } } distances.sort(); + let max_connections = max_connections.unwrap_or(distances.len()); + let mut ids_to_component: HashMap<_, _> = (0..boxes.len()).map(|i| (i, i)).collect(); let mut components: HashMap<_, _> = (0..boxes.len()).map(|i| (i, HashSet::from([i]))).collect(); - - for (_, i, j) in distances { - let c1_id = *ids_to_component.get(&i).unwrap(); - let c2_id = *ids_to_component.get(&j).unwrap(); + for (_, i, j) in distances.iter().take(max_connections) { + let c1_id = *ids_to_component.get(i).unwrap(); + let c2_id = *ids_to_component.get(j).unwrap(); if c1_id == c2_id { continue; } @@ -78,30 +77,8 @@ pub fn part2(input: String) -> Result> { .extend(component2); if components.len() == 1 { - return Ok((boxes[i][0] * boxes[j][0]).to_string()); + return Components::LastConnection(boxes[*i], boxes[*j]); } } - - Err("Solution not found".into()) // unreachable -} - -type Coord = [i64; 3]; - -fn parse_input(input: String) -> Result, Box> { - let x = input - .trim() - .lines() - .map(|line| { - let values: Result, _> = line.split(',').map(str::parse).collect(); - values.map(|v| [v[0], v[1], v[2]]) - }) - .collect::>()?; - Ok(x) -} - -fn d2(a: &Coord, b: &Coord) -> i64 { - a.iter() - .zip(b.iter()) - .map(|(ai, bi)| (ai - bi).pow(2)) - .sum() + Components::Sizes(components.values().map(|c| c.len()).collect()) } From ee7902173993d2748331f263fa5e4819574836be Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Tue, 9 Dec 2025 09:07:24 +0000 Subject: [PATCH 20/26] 2025-09 --- Cargo.lock | 5 + Cargo.toml | 3 +- rust/y2025/d09/Cargo.toml | 7 ++ rust/y2025/d09/y2025d09.rs | 182 +++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d09/Cargo.toml create mode 100644 rust/y2025/d09/y2025d09.rs diff --git a/Cargo.lock b/Cargo.lock index c11da1b..aeb93b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,6 +131,7 @@ dependencies = [ "y2025d06", "y2025d07", "y2025d08", + "y2025d09", ] [[package]] @@ -1923,6 +1924,10 @@ version = "0.1.0" name = "y2025d08" version = "0.1.0" +[[package]] +name = "y2025d09" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 7b84616..0c7cf67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", "rust/y2025/d09", ] [package] @@ -65,3 +65,4 @@ y2025d05 = { path = "rust/y2025/d05" } y2025d06 = { path = "rust/y2025/d06" } y2025d07 = { path = "rust/y2025/d07" } y2025d08 = { path = "rust/y2025/d08" } +y2025d09 = { path = "rust/y2025/d09" } diff --git a/rust/y2025/d09/Cargo.toml b/rust/y2025/d09/Cargo.toml new file mode 100644 index 0000000..94a7e9c --- /dev/null +++ b/rust/y2025/d09/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d09" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d09.rs" diff --git a/rust/y2025/d09/y2025d09.rs b/rust/y2025/d09/y2025d09.rs new file mode 100644 index 0000000..cf02085 --- /dev/null +++ b/rust/y2025/d09/y2025d09.rs @@ -0,0 +1,182 @@ +use std::collections::{HashMap, HashSet}; + +pub fn part1(input: String) -> Result> { + let tiles = parse_input(input)?; + let max_area = tiles + .iter() + .flat_map(|a| tiles.iter().map(|b| Rectangle::from_corners(a, b).area())) + .max() + .ok_or("Input is empty")?; + Ok(max_area.to_string()) +} + +pub fn part2(input: String) -> Result> { + let tiles = parse_input(input)?; + let floor = Floor::from_red_tiles(&tiles)?; + + let max_area = tiles + .iter() + .flat_map(|a| { + tiles.iter().filter_map(|b| { + let r = Rectangle::from_corners(a, b); + if floor.contains_rectangle(&r).unwrap() { + Some(r.area()) + } else { + None + } + }) + }) + .max() + .ok_or("Input is empty")?; + + Ok(max_area.to_string()) +} + +type Coords = (u64, u64); + +fn parse_input(input: String) -> Result, Box> { + input + .trim() + .lines() + .map(|line| -> Result<_, _> { + let (a, b) = line.split_once(',').ok_or("Invalid input")?; + Ok((a.parse()?, b.parse()?)) + }) + .collect() +} + +struct ContractMap { + xmap: HashMap, + ymap: HashMap, +} + +impl ContractMap { + fn mapx(&self, x: &u64) -> Result> { + self.xmap.get(x).ok_or("Not found".into()).copied() + } + fn mapy(&self, y: &u64) -> Result> { + self.ymap.get(y).ok_or("Not found".into()).copied() + } + fn map(&self, (x, y): &Coords) -> Result<(usize, usize), Box> { + Ok((self.mapx(x)?, self.mapy(y)?)) + } + fn map_rectangle(&self, r: &Rectangle) -> Result> { + Ok(CRectangle { + bottom: self.mapy(&r.bottom)?, + top: self.mapy(&r.top)?, + left: self.mapx(&r.left)?, + right: self.mapx(&r.right)?, + }) + } + + fn from_tiles(tiles: &[Coords]) -> Self { + ContractMap { + xmap: contract_map(tiles.iter().map(|(x, _)| *x)), + ymap: contract_map(tiles.iter().map(|(_, y)| *y)), + } + } +} + +struct Rectangle { + bottom: u64, + top: u64, + left: u64, + right: u64, +} +struct CRectangle { + bottom: usize, + top: usize, + left: usize, + right: usize, +} + +impl Rectangle { + fn from_corners((x1, y1): &Coords, (x2, y2): &Coords) -> Self { + Rectangle { + left: *x1.min(x2), + right: *x1.max(x2), + bottom: *y1.min(y2), + top: *y1.max(y2), + } + } + fn area(&self) -> u64 { + (self.top - self.bottom + 1) * (self.right - self.left + 1) + } +} + +struct Floor { + contract_map: ContractMap, + inside: HashSet<(usize, usize)>, +} + +impl Floor { + fn from_red_tiles(tiles: &[Coords]) -> Result> { + let contract_map = ContractMap::from_tiles(tiles); + let mapped_tiles = tiles + .iter() + .map(|p| contract_map.map(p)) + .collect::, _>>()?; + // start with the perimeter + let mut inside: HashSet<_> = windows(&mapped_tiles) + .flat_map(|((x1, y1), (x2, y2))| { + range(x1, x2).flat_map(|x| range(y1, y2).map(move |y| (x, y))) + }) + .collect(); + // Get the first tile on the left boundary + let (i, v) = mapped_tiles + .iter() + .enumerate() + .find(|(_, (x, _))| *x == 1) + .ok_or("No tiles")?; + let next = mapped_tiles[i + 1]; + // TODO: If assertion fails, the two tiles we are looking for + // are the first and last one + assert!(next.0 == v.0); + // Get the first inner tile, depending on travel direction + let s = if next.1 > v.1 { + // CW -> upper right + (v.0 + 1, v.1 + 1) + } else { + // CCW -> lower right + (v.0 + 1, v.1 - 1) + }; + // flood the inside + let mut q = vec![s]; + inside.insert(s); + while let Some((x, y)) = q.pop() { + for neighbor in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)] { + if inside.insert(neighbor) { + q.push(neighbor); + } + } + } + + Ok(Floor { + contract_map, + inside, + }) + } + + fn contains_rectangle(&self, r: &Rectangle) -> Result> { + let r = self.contract_map.map_rectangle(r)?; + let mut boundary = (r.bottom..=r.top) + .flat_map(|y| [(r.left, y), (r.right, y)]) + .chain((r.left..=r.right).flat_map(|x| [(x, r.bottom), (x, r.top)])); + Ok(!boundary.any(|p| !self.inside.contains(&p))) + } +} + +fn contract_map(xs: impl Iterator) -> HashMap { + let set: HashSet<_> = xs.flat_map(|x| [x - 1, x, x + 1]).collect(); + let mut xs: Vec<_> = set.into_iter().collect(); + xs.sort(); + xs.into_iter().enumerate().map(|(i, x)| (x, i)).collect() +} + +fn windows(xs: &[T]) -> impl Iterator { + xs.iter().skip(1).chain(xs.iter().take(1)).zip(xs.iter()) +} + +fn range(a: &T, b: &T) -> std::ops::RangeInclusive { + *a.min(b)..=*a.max(b) +} diff --git a/src/run.rs b/src/run.rs index 16a4d9d..7c08a46 100644 --- a/src/run.rs +++ b/src/run.rs @@ -98,6 +98,7 @@ fn get_solution_functions( (2025, 6) => Ok((y2025d06::part1, y2025d06::part2)), (2025, 7) => Ok((y2025d07::part1, y2025d07::part2)), (2025, 8) => Ok((y2025d08::part1, y2025d08::part2)), + (2025, 9) => Ok((y2025d09::part1, y2025d09::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From 1fdb39eb711b159af2184da3fa95be738e5e73bf Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Wed, 10 Dec 2025 06:50:42 +0000 Subject: [PATCH 21/26] 2025-10-p1 --- Cargo.lock | 23 +++++++++++ Cargo.toml | 3 +- rust/y2025/d10/Cargo.toml | 10 +++++ rust/y2025/d10/y2025d10.rs | 78 ++++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d10/Cargo.toml create mode 100644 rust/y2025/d10/y2025d10.rs diff --git a/Cargo.lock b/Cargo.lock index aeb93b7..ddc99ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -132,6 +132,7 @@ dependencies = [ "y2025d07", "y2025d08", "y2025d09", + "y2025d10", ] [[package]] @@ -308,6 +309,12 @@ dependencies = [ "syn", ] +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -763,6 +770,15 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.14" @@ -1928,6 +1944,13 @@ version = "0.1.0" name = "y2025d09" version = "0.1.0" +[[package]] +name = "y2025d10" +version = "0.1.0" +dependencies = [ + "itertools", +] + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 0c7cf67..c3b5f13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", "rust/y2025/d09", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", "rust/y2025/d09", "rust/y2025/d10", ] [package] @@ -66,3 +66,4 @@ y2025d06 = { path = "rust/y2025/d06" } y2025d07 = { path = "rust/y2025/d07" } y2025d08 = { path = "rust/y2025/d08" } y2025d09 = { path = "rust/y2025/d09" } +y2025d10 = { path = "rust/y2025/d10" } diff --git a/rust/y2025/d10/Cargo.toml b/rust/y2025/d10/Cargo.toml new file mode 100644 index 0000000..10f5381 --- /dev/null +++ b/rust/y2025/d10/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "y2025d10" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d10.rs" + +[dependencies] +itertools = "0.14.0" diff --git a/rust/y2025/d10/y2025d10.rs b/rust/y2025/d10/y2025d10.rs new file mode 100644 index 0000000..78855bb --- /dev/null +++ b/rust/y2025/d10/y2025d10.rs @@ -0,0 +1,78 @@ +use std::str::FromStr; + +use itertools::Itertools; + +pub fn part1(input: String) -> Result> { + let machines = parse_input(input)?; + let tot: usize = machines + .iter() + .map(|m| m.find_presses()) + .collect::, _>>()? + .iter() + .sum(); + Ok(tot.to_string()) +} + +pub fn part2(input: String) -> Result> { + // Solve part 2 + Err("Solution not implemented".into()) +} + +fn parse_input(input: String) -> Result, Box> { + input.trim().lines().map(Machine::from_str).collect() +} + +struct Machine { + target: Vec, + buttons: Vec>, +} + +impl FromStr for Machine { + type Err = Box; + + fn from_str(s: &str) -> Result { + let (target_str, button_str) = s.split_once(' ').ok_or("Invalid input")?; + let target = target_str + .trim_start_matches('[') + .trim_end_matches(']') + .chars() + .map(|c| c == '#') + .collect(); + let buttons = button_str + .split(' ') + .take_while(|s| s.starts_with('(')) + .map(|s| { + s.trim_start_matches('(') + .trim_end_matches(')') + .split(',') + .map(str::parse) + .collect::, _>>() + }) + .collect::, _>>()?; + + Ok(Self { target, buttons }) + } +} + +impl Machine { + fn find_presses(&self) -> Result> { + for n in 1..=self.buttons.len() { + for bs in self.buttons.iter().combinations(n) { + let s = bs + .iter() + .fold(vec![false; self.target.len()], |mut acc, b| { + for p in b.iter() { + acc[*p] = !acc[*p]; + } + acc + }); + if s == self.target { + println!("{:?}", bs); + return Ok(n); + } + } + } + + Err("Solution not found".into()) + } +} diff --git a/src/run.rs b/src/run.rs index 7c08a46..d59eff4 100644 --- a/src/run.rs +++ b/src/run.rs @@ -99,6 +99,7 @@ fn get_solution_functions( (2025, 7) => Ok((y2025d07::part1, y2025d07::part2)), (2025, 8) => Ok((y2025d08::part1, y2025d08::part2)), (2025, 9) => Ok((y2025d09::part1, y2025d09::part2)), + (2025, 10) => Ok((y2025d10::part1, y2025d10::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From 1e8666940de6cc75c1f8c19ebbc48af6d59a63aa Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Wed, 10 Dec 2025 07:05:35 +0000 Subject: [PATCH 22/26] wip p2 --- rust/y2025/d10/y2025d10.rs | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/rust/y2025/d10/y2025d10.rs b/rust/y2025/d10/y2025d10.rs index 78855bb..bfabc59 100644 --- a/rust/y2025/d10/y2025d10.rs +++ b/rust/y2025/d10/y2025d10.rs @@ -6,7 +6,7 @@ pub fn part1(input: String) -> Result> { let machines = parse_input(input)?; let tot: usize = machines .iter() - .map(|m| m.find_presses()) + .map(|m| m.find_light_presses()) .collect::, _>>()? .iter() .sum(); @@ -14,24 +14,33 @@ pub fn part1(input: String) -> Result> { } pub fn part2(input: String) -> Result> { - // Solve part 2 - Err("Solution not implemented".into()) + let machines = parse_input(input)?; + let tot: usize = machines + .iter() + .map(|m| m.find_joltage_presses()) + .collect::, _>>()? + .iter() + .sum(); + Ok(tot.to_string()) } fn parse_input(input: String) -> Result, Box> { input.trim().lines().map(Machine::from_str).collect() } +#[derive(Debug)] struct Machine { target: Vec, buttons: Vec>, + joltage: Vec, } impl FromStr for Machine { type Err = Box; fn from_str(s: &str) -> Result { - let (target_str, button_str) = s.split_once(' ').ok_or("Invalid input")?; + let (target_str, rest) = s.split_once(" (").ok_or("Invalid input")?; + let (button_str, joltage_str) = rest.split_once(" {").ok_or("Invalid input")?; let target = target_str .trim_start_matches('[') .trim_end_matches(']') @@ -40,7 +49,6 @@ impl FromStr for Machine { .collect(); let buttons = button_str .split(' ') - .take_while(|s| s.starts_with('(')) .map(|s| { s.trim_start_matches('(') .trim_end_matches(')') @@ -49,13 +57,23 @@ impl FromStr for Machine { .collect::, _>>() }) .collect::, _>>()?; + let joltage = joltage_str + .trim_start_matches('{') + .trim_end_matches('}') + .split(',') + .map(str::parse) + .collect::, _>>()?; - Ok(Self { target, buttons }) + Ok(Self { + target, + buttons, + joltage, + }) } } impl Machine { - fn find_presses(&self) -> Result> { + fn find_light_presses(&self) -> Result> { for n in 1..=self.buttons.len() { for bs in self.buttons.iter().combinations(n) { let s = bs @@ -67,7 +85,6 @@ impl Machine { acc }); if s == self.target { - println!("{:?}", bs); return Ok(n); } } @@ -75,4 +92,8 @@ impl Machine { Err("Solution not found".into()) } + + fn find_joltage_presses(&self) -> Result> { + Err("Solution not found".into()) + } } From a5fdc816438f34af4b47530f582f1139594fb499 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Wed, 10 Dec 2025 07:35:05 +0000 Subject: [PATCH 23/26] 2025-10 part 2 in python + scipy (milp) --- pyaoc/solutions/y2025/y2025d10.py | 44 ++++++ pyproject.toml | 1 + uv.lock | 234 ++++++++++++++++++++++-------- 3 files changed, 215 insertions(+), 64 deletions(-) create mode 100644 pyaoc/solutions/y2025/y2025d10.py diff --git a/pyaoc/solutions/y2025/y2025d10.py b/pyaoc/solutions/y2025/y2025d10.py new file mode 100644 index 0000000..189721a --- /dev/null +++ b/pyaoc/solutions/y2025/y2025d10.py @@ -0,0 +1,44 @@ +import numpy as np # type: ignore[import-not-found] +from scipy import optimize # type: ignore[import-not-found] + + +def part1(input_str: str) -> str: + raise NotImplementedError + + +def part2(input_str: str) -> str: + machines = parse_input(input_str) + tot = sum(m.find_joltage_presses() for m in machines) + return str(tot) + + +class Machine: + def __init__(self, buttons: list[list[int]], joltage: list[int]): + self.buttons = buttons + self.joltage = joltage + + @classmethod + def from_str(cls, s: str) -> "Machine": + (_, *buttons_str, joltage_str) = s.split(" ") + buttons = [list(map(int, s.strip("()").split(","))) for s in buttons_str] + joltage = list( + map(int, joltage_str.removeprefix("{").removesuffix("}").split(",")) + ) + return Machine(buttons, joltage) + + def find_joltage_presses(self) -> int: + n_vars = len(self.buttons) + b = np.array( + [[i in b for i in range(len(self.joltage))] for b in self.buttons] + ).T + j = np.array(self.joltage) + res = optimize.milp( + c=np.ones(n_vars), + constraints=optimize.LinearConstraint(b, lb=j, ub=j), + integrality=1, + ) + return int(res.fun) + + +def parse_input(input_str: str) -> list[Machine]: + return list(map(Machine.from_str, input_str.splitlines())) diff --git a/pyproject.toml b/pyproject.toml index 864a1a6..999d4e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ dependencies = [ "networkx>=3.4.2", "pre-commit>=4.0.1", "ruff>=0.7.4", + "scipy>=1.16.3", "tqdm>=4.67.0", ] diff --git a/uv.lock b/uv.lock index 6e7d74b..e940e9e 100644 --- a/uv.lock +++ b/uv.lock @@ -1,4 +1,5 @@ version = 1 +revision = 3 requires-python = ">=3.13" [[package]] @@ -10,6 +11,7 @@ dependencies = [ { name = "networkx" }, { name = "pre-commit" }, { name = "ruff" }, + { name = "scipy" }, { name = "tqdm" }, ] @@ -19,6 +21,7 @@ requires-dist = [ { name = "networkx", specifier = ">=3.4.2" }, { name = "pre-commit", specifier = ">=4.0.1" }, { name = "ruff", specifier = ">=0.7.4" }, + { name = "scipy", specifier = ">=1.16.3" }, { name = "tqdm", specifier = ">=4.67.0" }, ] @@ -26,45 +29,45 @@ requires-dist = [ name = "cfgv" version = "3.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "distlib" version = "0.3.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923, upload-time = "2024-10-09T18:35:47.551Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973, upload-time = "2024-10-09T18:35:44.272Z" }, ] [[package]] name = "filelock" version = "3.16.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037, upload-time = "2024-09-17T19:02:01.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, + { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163, upload-time = "2024-09-17T19:02:00.268Z" }, ] [[package]] name = "identify" version = "2.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/02/79/7a520fc5011e02ca3f3285b5f6820eaf80443eb73e3733f73c02fb42ba0b/identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd", size = 99113 } +sdist = { url = "https://files.pythonhosted.org/packages/02/79/7a520fc5011e02ca3f3285b5f6820eaf80443eb73e3733f73c02fb42ba0b/identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd", size = 99113, upload-time = "2024-11-09T18:11:37.697Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/86/c4395700f3c5475424fb5c41e20c16be28d10c904aee4d005ba3217fc8e7/identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3", size = 98982 }, + { url = "https://files.pythonhosted.org/packages/e0/86/c4395700f3c5475424fb5c41e20c16be28d10c904aee4d005ba3217fc8e7/identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3", size = 98982, upload-time = "2024-11-09T18:11:35.861Z" }, ] [[package]] @@ -75,14 +78,14 @@ dependencies = [ { name = "mypy-extensions" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532, upload-time = "2024-10-22T21:55:47.458Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 }, - { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 }, - { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 }, - { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 }, - { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 }, - { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, + { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721, upload-time = "2024-10-22T21:54:22.321Z" }, + { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996, upload-time = "2024-10-22T21:54:46.023Z" }, + { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043, upload-time = "2024-10-22T21:55:06.231Z" }, + { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996, upload-time = "2024-10-22T21:55:25.811Z" }, + { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709, upload-time = "2024-10-22T21:55:21.246Z" }, + { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043, upload-time = "2024-10-22T21:55:16.617Z" }, ] [package.optional-dependencies] @@ -94,45 +97,97 @@ install-types = [ name = "mypy-extensions" version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433, upload-time = "2023-02-04T12:11:27.157Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695, upload-time = "2023-02-04T12:11:25.002Z" }, ] [[package]] name = "networkx" version = "3.4.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368 } +sdist = { url = "https://files.pythonhosted.org/packages/fd/1d/06475e1cd5264c0b870ea2cc6fdb3e37177c1e565c43f56ff17a10e3937f/networkx-3.4.2.tar.gz", hash = "sha256:307c3669428c5362aab27c8a1260aa8f47c4e91d3891f48be0141738d8d053e1", size = 2151368, upload-time = "2024-10-21T12:39:38.695Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263 }, + { url = "https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl", hash = "sha256:df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f", size = 1723263, upload-time = "2024-10-21T12:39:36.247Z" }, ] [[package]] name = "nodeenv" version = "1.9.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, +] + +[[package]] +name = "numpy" +version = "2.3.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/65/21b3bc86aac7b8f2862db1e808f1ea22b028e30a225a34a5ede9bf8678f2/numpy-2.3.5.tar.gz", hash = "sha256:784db1dcdab56bf0517743e746dfb0f885fc68d948aba86eeec2cba234bdf1c0", size = 20584950, upload-time = "2025-11-16T22:52:42.067Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/69/9cde09f36da4b5a505341180a3f2e6fadc352fd4d2b7096ce9778db83f1a/numpy-2.3.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d0f23b44f57077c1ede8c5f26b30f706498b4862d3ff0a7298b8411dd2f043ff", size = 16728251, upload-time = "2025-11-16T22:50:19.013Z" }, + { url = "https://files.pythonhosted.org/packages/79/fb/f505c95ceddd7027347b067689db71ca80bd5ecc926f913f1a23e65cf09b/numpy-2.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa5bc7c5d59d831d9773d1170acac7893ce3a5e130540605770ade83280e7188", size = 12254652, upload-time = "2025-11-16T22:50:21.487Z" }, + { url = "https://files.pythonhosted.org/packages/78/da/8c7738060ca9c31b30e9301ee0cf6c5ffdbf889d9593285a1cead337f9a5/numpy-2.3.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:ccc933afd4d20aad3c00bcef049cb40049f7f196e0397f1109dba6fed63267b0", size = 5083172, upload-time = "2025-11-16T22:50:24.562Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b4/ee5bb2537fb9430fd2ef30a616c3672b991a4129bb1c7dcc42aa0abbe5d7/numpy-2.3.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:afaffc4393205524af9dfa400fa250143a6c3bc646c08c9f5e25a9f4b4d6a903", size = 6622990, upload-time = "2025-11-16T22:50:26.47Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/dc0723a013c7d7c19de5ef29e932c3081df1c14ba582b8b86b5de9db7f0f/numpy-2.3.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c75442b2209b8470d6d5d8b1c25714270686f14c749028d2199c54e29f20b4d", size = 14248902, upload-time = "2025-11-16T22:50:28.861Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017", size = 16597430, upload-time = "2025-11-16T22:50:31.56Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/c1e29be863588db58175175f057286900b4b3327a1351e706d5e0f8dd679/numpy-2.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed89927b86296067b4f81f108a2271d8926467a8868e554eaf370fc27fa3ccaf", size = 16024551, upload-time = "2025-11-16T22:50:34.242Z" }, + { url = "https://files.pythonhosted.org/packages/83/68/8236589d4dbb87253d28259d04d9b814ec0ecce7cb1c7fed29729f4c3a78/numpy-2.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51c55fe3451421f3a6ef9a9c1439e82101c57a2c9eab9feb196a62b1a10b58ce", size = 18533275, upload-time = "2025-11-16T22:50:37.651Z" }, + { url = "https://files.pythonhosted.org/packages/40/56/2932d75b6f13465239e3b7b7e511be27f1b8161ca2510854f0b6e521c395/numpy-2.3.5-cp313-cp313-win32.whl", hash = "sha256:1978155dd49972084bd6ef388d66ab70f0c323ddee6f693d539376498720fb7e", size = 6277637, upload-time = "2025-11-16T22:50:40.11Z" }, + { url = "https://files.pythonhosted.org/packages/0c/88/e2eaa6cffb115b85ed7c7c87775cb8bcf0816816bc98ca8dbfa2ee33fe6e/numpy-2.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:00dc4e846108a382c5869e77c6ed514394bdeb3403461d25a829711041217d5b", size = 12779090, upload-time = "2025-11-16T22:50:42.503Z" }, + { url = "https://files.pythonhosted.org/packages/8f/88/3f41e13a44ebd4034ee17baa384acac29ba6a4fcc2aca95f6f08ca0447d1/numpy-2.3.5-cp313-cp313-win_arm64.whl", hash = "sha256:0472f11f6ec23a74a906a00b48a4dcf3849209696dff7c189714511268d103ae", size = 10194710, upload-time = "2025-11-16T22:50:44.971Z" }, + { url = "https://files.pythonhosted.org/packages/13/cb/71744144e13389d577f867f745b7df2d8489463654a918eea2eeb166dfc9/numpy-2.3.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:414802f3b97f3c1eef41e530aaba3b3c1620649871d8cb38c6eaff034c2e16bd", size = 16827292, upload-time = "2025-11-16T22:50:47.715Z" }, + { url = "https://files.pythonhosted.org/packages/71/80/ba9dc6f2a4398e7f42b708a7fdc841bb638d353be255655498edbf9a15a8/numpy-2.3.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5ee6609ac3604fa7780e30a03e5e241a7956f8e2fcfe547d51e3afa5247ac47f", size = 12378897, upload-time = "2025-11-16T22:50:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/2e/6d/db2151b9f64264bcceccd51741aa39b50150de9b602d98ecfe7e0c4bff39/numpy-2.3.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:86d835afea1eaa143012a2d7a3f45a3adce2d7adc8b4961f0b362214d800846a", size = 5207391, upload-time = "2025-11-16T22:50:54.542Z" }, + { url = "https://files.pythonhosted.org/packages/80/ae/429bacace5ccad48a14c4ae5332f6aa8ab9f69524193511d60ccdfdc65fa/numpy-2.3.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:30bc11310e8153ca664b14c5f1b73e94bd0503681fcf136a163de856f3a50139", size = 6721275, upload-time = "2025-11-16T22:50:56.794Z" }, + { url = "https://files.pythonhosted.org/packages/74/5b/1919abf32d8722646a38cd527bc3771eb229a32724ee6ba340ead9b92249/numpy-2.3.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1062fde1dcf469571705945b0f221b73928f34a20c904ffb45db101907c3454e", size = 14306855, upload-time = "2025-11-16T22:50:59.208Z" }, + { url = "https://files.pythonhosted.org/packages/a5/87/6831980559434973bebc30cd9c1f21e541a0f2b0c280d43d3afd909b66d0/numpy-2.3.5-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce581db493ea1a96c0556360ede6607496e8bf9b3a8efa66e06477267bc831e9", size = 16657359, upload-time = "2025-11-16T22:51:01.991Z" }, + { url = "https://files.pythonhosted.org/packages/dd/91/c797f544491ee99fd00495f12ebb7802c440c1915811d72ac5b4479a3356/numpy-2.3.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:cc8920d2ec5fa99875b670bb86ddeb21e295cb07aa331810d9e486e0b969d946", size = 16093374, upload-time = "2025-11-16T22:51:05.291Z" }, + { url = "https://files.pythonhosted.org/packages/74/a6/54da03253afcbe7a72785ec4da9c69fb7a17710141ff9ac5fcb2e32dbe64/numpy-2.3.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9ee2197ef8c4f0dfe405d835f3b6a14f5fee7782b5de51ba06fb65fc9b36e9f1", size = 18594587, upload-time = "2025-11-16T22:51:08.585Z" }, + { url = "https://files.pythonhosted.org/packages/80/e9/aff53abbdd41b0ecca94285f325aff42357c6b5abc482a3fcb4994290b18/numpy-2.3.5-cp313-cp313t-win32.whl", hash = "sha256:70b37199913c1bd300ff6e2693316c6f869c7ee16378faf10e4f5e3275b299c3", size = 6405940, upload-time = "2025-11-16T22:51:11.541Z" }, + { url = "https://files.pythonhosted.org/packages/d5/81/50613fec9d4de5480de18d4f8ef59ad7e344d497edbef3cfd80f24f98461/numpy-2.3.5-cp313-cp313t-win_amd64.whl", hash = "sha256:b501b5fa195cc9e24fe102f21ec0a44dffc231d2af79950b451e0d99cea02234", size = 12920341, upload-time = "2025-11-16T22:51:14.312Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ab/08fd63b9a74303947f34f0bd7c5903b9c5532c2d287bead5bdf4c556c486/numpy-2.3.5-cp313-cp313t-win_arm64.whl", hash = "sha256:a80afd79f45f3c4a7d341f13acbe058d1ca8ac017c165d3fa0d3de6bc1a079d7", size = 10262507, upload-time = "2025-11-16T22:51:16.846Z" }, + { url = "https://files.pythonhosted.org/packages/ba/97/1a914559c19e32d6b2e233cf9a6a114e67c856d35b1d6babca571a3e880f/numpy-2.3.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:bf06bc2af43fa8d32d30fae16ad965663e966b1a3202ed407b84c989c3221e82", size = 16735706, upload-time = "2025-11-16T22:51:19.558Z" }, + { url = "https://files.pythonhosted.org/packages/57/d4/51233b1c1b13ecd796311216ae417796b88b0616cfd8a33ae4536330748a/numpy-2.3.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:052e8c42e0c49d2575621c158934920524f6c5da05a1d3b9bab5d8e259e045f0", size = 12264507, upload-time = "2025-11-16T22:51:22.492Z" }, + { url = "https://files.pythonhosted.org/packages/45/98/2fe46c5c2675b8306d0b4a3ec3494273e93e1226a490f766e84298576956/numpy-2.3.5-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:1ed1ec893cff7040a02c8aa1c8611b94d395590d553f6b53629a4461dc7f7b63", size = 5093049, upload-time = "2025-11-16T22:51:25.171Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0e/0698378989bb0ac5f1660c81c78ab1fe5476c1a521ca9ee9d0710ce54099/numpy-2.3.5-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:2dcd0808a421a482a080f89859a18beb0b3d1e905b81e617a188bd80422d62e9", size = 6626603, upload-time = "2025-11-16T22:51:27Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a6/9ca0eecc489640615642a6cbc0ca9e10df70df38c4d43f5a928ff18d8827/numpy-2.3.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727fd05b57df37dc0bcf1a27767a3d9a78cbbc92822445f32cc3436ba797337b", size = 14262696, upload-time = "2025-11-16T22:51:29.402Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f6/07ec185b90ec9d7217a00eeeed7383b73d7e709dae2a9a021b051542a708/numpy-2.3.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fffe29a1ef00883599d1dc2c51aa2e5d80afe49523c261a74933df395c15c520", size = 16597350, upload-time = "2025-11-16T22:51:32.167Z" }, + { url = "https://files.pythonhosted.org/packages/75/37/164071d1dde6a1a84c9b8e5b414fa127981bad47adf3a6b7e23917e52190/numpy-2.3.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8f7f0e05112916223d3f438f293abf0727e1181b5983f413dfa2fefc4098245c", size = 16040190, upload-time = "2025-11-16T22:51:35.403Z" }, + { url = "https://files.pythonhosted.org/packages/08/3c/f18b82a406b04859eb026d204e4e1773eb41c5be58410f41ffa511d114ae/numpy-2.3.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2e2eb32ddb9ccb817d620ac1d8dae7c3f641c1e5f55f531a33e8ab97960a75b8", size = 18536749, upload-time = "2025-11-16T22:51:39.698Z" }, + { url = "https://files.pythonhosted.org/packages/40/79/f82f572bf44cf0023a2fe8588768e23e1592585020d638999f15158609e1/numpy-2.3.5-cp314-cp314-win32.whl", hash = "sha256:66f85ce62c70b843bab1fb14a05d5737741e74e28c7b8b5a064de10142fad248", size = 6335432, upload-time = "2025-11-16T22:51:42.476Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2e/235b4d96619931192c91660805e5e49242389742a7a82c27665021db690c/numpy-2.3.5-cp314-cp314-win_amd64.whl", hash = "sha256:e6a0bc88393d65807d751a614207b7129a310ca4fe76a74e5c7da5fa5671417e", size = 12919388, upload-time = "2025-11-16T22:51:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/07/2b/29fd75ce45d22a39c61aad74f3d718e7ab67ccf839ca8b60866054eb15f8/numpy-2.3.5-cp314-cp314-win_arm64.whl", hash = "sha256:aeffcab3d4b43712bb7a60b65f6044d444e75e563ff6180af8f98dd4b905dfd2", size = 10476651, upload-time = "2025-11-16T22:51:47.749Z" }, + { url = "https://files.pythonhosted.org/packages/17/e1/f6a721234ebd4d87084cfa68d081bcba2f5cfe1974f7de4e0e8b9b2a2ba1/numpy-2.3.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:17531366a2e3a9e30762c000f2c43a9aaa05728712e25c11ce1dbe700c53ad41", size = 16834503, upload-time = "2025-11-16T22:51:50.443Z" }, + { url = "https://files.pythonhosted.org/packages/5c/1c/baf7ffdc3af9c356e1c135e57ab7cf8d247931b9554f55c467efe2c69eff/numpy-2.3.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d21644de1b609825ede2f48be98dfde4656aefc713654eeee280e37cadc4e0ad", size = 12381612, upload-time = "2025-11-16T22:51:53.609Z" }, + { url = "https://files.pythonhosted.org/packages/74/91/f7f0295151407ddc9ba34e699013c32c3c91944f9b35fcf9281163dc1468/numpy-2.3.5-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c804e3a5aba5460c73955c955bdbd5c08c354954e9270a2c1565f62e866bdc39", size = 5210042, upload-time = "2025-11-16T22:51:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/2e/3b/78aebf345104ec50dd50a4d06ddeb46a9ff5261c33bcc58b1c4f12f85ec2/numpy-2.3.5-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:cc0a57f895b96ec78969c34f682c602bf8da1a0270b09bc65673df2e7638ec20", size = 6724502, upload-time = "2025-11-16T22:51:58.584Z" }, + { url = "https://files.pythonhosted.org/packages/02/c6/7c34b528740512e57ef1b7c8337ab0b4f0bddf34c723b8996c675bc2bc91/numpy-2.3.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:900218e456384ea676e24ea6a0417f030a3b07306d29d7ad843957b40a9d8d52", size = 14308962, upload-time = "2025-11-16T22:52:01.698Z" }, + { url = "https://files.pythonhosted.org/packages/80/35/09d433c5262bc32d725bafc619e095b6a6651caf94027a03da624146f655/numpy-2.3.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09a1bea522b25109bf8e6f3027bd810f7c1085c64a0c7ce050c1676ad0ba010b", size = 16655054, upload-time = "2025-11-16T22:52:04.267Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ab/6a7b259703c09a88804fa2430b43d6457b692378f6b74b356155283566ac/numpy-2.3.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:04822c00b5fd0323c8166d66c701dc31b7fbd252c100acd708c48f763968d6a3", size = 16091613, upload-time = "2025-11-16T22:52:08.651Z" }, + { url = "https://files.pythonhosted.org/packages/c2/88/330da2071e8771e60d1038166ff9d73f29da37b01ec3eb43cb1427464e10/numpy-2.3.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d6889ec4ec662a1a37eb4b4fb26b6100841804dac55bd9df579e326cdc146227", size = 18591147, upload-time = "2025-11-16T22:52:11.453Z" }, + { url = "https://files.pythonhosted.org/packages/51/41/851c4b4082402d9ea860c3626db5d5df47164a712cb23b54be028b184c1c/numpy-2.3.5-cp314-cp314t-win32.whl", hash = "sha256:93eebbcf1aafdf7e2ddd44c2923e2672e1010bddc014138b229e49725b4d6be5", size = 6479806, upload-time = "2025-11-16T22:52:14.641Z" }, + { url = "https://files.pythonhosted.org/packages/90/30/d48bde1dfd93332fa557cff1972fbc039e055a52021fbef4c2c4b1eefd17/numpy-2.3.5-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a9958e88b65c3b27e22ca2a076311636850b612d6bbfb76e8d156aacde2aaf", size = 13105760, upload-time = "2025-11-16T22:52:17.975Z" }, + { url = "https://files.pythonhosted.org/packages/2d/fd/4b5eb0b3e888d86aee4d198c23acec7d214baaf17ea93c1adec94c9518b9/numpy-2.3.5-cp314-cp314t-win_arm64.whl", hash = "sha256:6203fdf9f3dc5bdaed7319ad8698e685c7a3be10819f41d32a0723e611733b42", size = 10545459, upload-time = "2025-11-16T22:52:20.55Z" }, ] [[package]] name = "pip" version = "24.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f4/b1/b422acd212ad7eedddaf7981eee6e5de085154ff726459cf2da7c5a184c1/pip-24.3.1.tar.gz", hash = "sha256:ebcb60557f2aefabc2e0f918751cd24ea0d56d8ec5445fe1807f1d2109660b99", size = 1931073 } +sdist = { url = "https://files.pythonhosted.org/packages/f4/b1/b422acd212ad7eedddaf7981eee6e5de085154ff726459cf2da7c5a184c1/pip-24.3.1.tar.gz", hash = "sha256:ebcb60557f2aefabc2e0f918751cd24ea0d56d8ec5445fe1807f1d2109660b99", size = 1931073, upload-time = "2024-10-27T18:35:56.354Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/7d/500c9ad20238fcfcb4cb9243eede163594d7020ce87bd9610c9e02771876/pip-24.3.1-py3-none-any.whl", hash = "sha256:3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed", size = 1822182 }, + { url = "https://files.pythonhosted.org/packages/ef/7d/500c9ad20238fcfcb4cb9243eede163594d7020ce87bd9610c9e02771876/pip-24.3.1-py3-none-any.whl", hash = "sha256:3790624780082365f47549d032f3770eeb2b1e8bd1f7b2e02dace1afa361b4ed", size = 1822182, upload-time = "2024-10-27T18:35:53.067Z" }, ] [[package]] name = "platformdirs" version = "4.3.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302, upload-time = "2024-09-17T19:06:50.688Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439, upload-time = "2024-09-17T19:06:49.212Z" }, ] [[package]] @@ -146,51 +201,102 @@ dependencies = [ { name = "pyyaml" }, { name = "virtualenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/c8/e22c292035f1bac8b9f5237a2622305bc0304e776080b246f3df57c4ff9f/pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2", size = 191678 } +sdist = { url = "https://files.pythonhosted.org/packages/2e/c8/e22c292035f1bac8b9f5237a2622305bc0304e776080b246f3df57c4ff9f/pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2", size = 191678, upload-time = "2024-10-08T16:09:37.641Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/8f/496e10d51edd6671ebe0432e33ff800aa86775d2d147ce7d43389324a525/pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878", size = 218713 }, + { url = "https://files.pythonhosted.org/packages/16/8f/496e10d51edd6671ebe0432e33ff800aa86775d2d147ce7d43389324a525/pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878", size = 218713, upload-time = "2024-10-08T16:09:35.726Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[package]] name = "ruff" version = "0.7.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/8b/bc4e0dfa1245b07cf14300e10319b98e958a53ff074c1dd86b35253a8c2a/ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2", size = 3275547 } +sdist = { url = "https://files.pythonhosted.org/packages/0b/8b/bc4e0dfa1245b07cf14300e10319b98e958a53ff074c1dd86b35253a8c2a/ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2", size = 3275547, upload-time = "2024-11-15T11:33:11.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/4b/f5094719e254829766b807dadb766841124daba75a37da83e292ae5ad12f/ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478", size = 10447512, upload-time = "2024-11-15T11:32:27.812Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1d/3d2d2c9f601cf6044799c5349ff5267467224cefed9b35edf5f1f36486e9/ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63", size = 10235436, upload-time = "2024-11-15T11:32:30.6Z" }, + { url = "https://files.pythonhosted.org/packages/62/83/42a6ec6216ded30b354b13e0e9327ef75a3c147751aaf10443756cb690e9/ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20", size = 9888936, upload-time = "2024-11-15T11:32:33.287Z" }, + { url = "https://files.pythonhosted.org/packages/4d/26/e1e54893b13046a6ad05ee9b89ee6f71542ba250f72b4c7a7d17c3dbf73d/ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109", size = 10697353, upload-time = "2024-11-15T11:32:35.895Z" }, + { url = "https://files.pythonhosted.org/packages/21/24/98d2e109c4efc02bfef144ec6ea2c3e1217e7ce0cfddda8361d268dfd499/ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452", size = 10228078, upload-time = "2024-11-15T11:32:40.929Z" }, + { url = "https://files.pythonhosted.org/packages/ad/b7/964c75be9bc2945fc3172241b371197bb6d948cc69e28bc4518448c368f3/ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea", size = 11264823, upload-time = "2024-11-15T11:32:43.31Z" }, + { url = "https://files.pythonhosted.org/packages/12/8d/20abdbf705969914ce40988fe71a554a918deaab62c38ec07483e77866f6/ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7", size = 11951855, upload-time = "2024-11-15T11:32:46.038Z" }, + { url = "https://files.pythonhosted.org/packages/b8/fc/6519ce58c57b4edafcdf40920b7273dfbba64fc6ebcaae7b88e4dc1bf0a8/ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05", size = 11516580, upload-time = "2024-11-15T11:32:48.17Z" }, + { url = "https://files.pythonhosted.org/packages/37/1a/5ec1844e993e376a86eb2456496831ed91b4398c434d8244f89094758940/ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06", size = 12692057, upload-time = "2024-11-15T11:32:50.623Z" }, + { url = "https://files.pythonhosted.org/packages/50/90/76867152b0d3c05df29a74bb028413e90f704f0f6701c4801174ba47f959/ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc", size = 11085137, upload-time = "2024-11-15T11:32:52.819Z" }, + { url = "https://files.pythonhosted.org/packages/c8/eb/0a7cb6059ac3555243bd026bb21785bbc812f7bbfa95a36c101bd72b47ae/ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172", size = 10681243, upload-time = "2024-11-15T11:32:55.902Z" }, + { url = "https://files.pythonhosted.org/packages/5e/76/2270719dbee0fd35780b05c08a07b7a726c3da9f67d9ae89ef21fc18e2e5/ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a", size = 10319187, upload-time = "2024-11-15T11:32:58.255Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e5/39100f72f8ba70bec1bd329efc880dea8b6c1765ea1cb9d0c1c5f18b8d7f/ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd", size = 10803715, upload-time = "2024-11-15T11:33:00.88Z" }, + { url = "https://files.pythonhosted.org/packages/a5/89/40e904784f305fb56850063f70a998a64ebba68796d823dde67e89a24691/ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a", size = 11162912, upload-time = "2024-11-15T11:33:03.097Z" }, + { url = "https://files.pythonhosted.org/packages/8d/1b/dd77503b3875c51e3dbc053fd8367b845ab8b01c9ca6d0c237082732856c/ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac", size = 8702767, upload-time = "2024-11-15T11:33:05.15Z" }, + { url = "https://files.pythonhosted.org/packages/63/76/253ddc3e89e70165bba952ecca424b980b8d3c2598ceb4fc47904f424953/ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6", size = 9497534, upload-time = "2024-11-15T11:33:07.359Z" }, + { url = "https://files.pythonhosted.org/packages/aa/70/f8724f31abc0b329ca98b33d73c14020168babcf71b0cba3cded5d9d0e66/ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f", size = 8851590, upload-time = "2024-11-15T11:33:09.664Z" }, +] + +[[package]] +name = "scipy" +version = "1.16.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/ca/d8ace4f98322d01abcd52d381134344bf7b431eba7ed8b42bdea5a3c2ac9/scipy-1.16.3.tar.gz", hash = "sha256:01e87659402762f43bd2fee13370553a17ada367d42e7487800bf2916535aecb", size = 30597883, upload-time = "2025-10-28T17:38:54.068Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/4b/f5094719e254829766b807dadb766841124daba75a37da83e292ae5ad12f/ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478", size = 10447512 }, - { url = "https://files.pythonhosted.org/packages/9e/1d/3d2d2c9f601cf6044799c5349ff5267467224cefed9b35edf5f1f36486e9/ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63", size = 10235436 }, - { url = "https://files.pythonhosted.org/packages/62/83/42a6ec6216ded30b354b13e0e9327ef75a3c147751aaf10443756cb690e9/ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20", size = 9888936 }, - { url = "https://files.pythonhosted.org/packages/4d/26/e1e54893b13046a6ad05ee9b89ee6f71542ba250f72b4c7a7d17c3dbf73d/ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109", size = 10697353 }, - { url = "https://files.pythonhosted.org/packages/21/24/98d2e109c4efc02bfef144ec6ea2c3e1217e7ce0cfddda8361d268dfd499/ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452", size = 10228078 }, - { url = "https://files.pythonhosted.org/packages/ad/b7/964c75be9bc2945fc3172241b371197bb6d948cc69e28bc4518448c368f3/ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea", size = 11264823 }, - { url = "https://files.pythonhosted.org/packages/12/8d/20abdbf705969914ce40988fe71a554a918deaab62c38ec07483e77866f6/ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7", size = 11951855 }, - { url = "https://files.pythonhosted.org/packages/b8/fc/6519ce58c57b4edafcdf40920b7273dfbba64fc6ebcaae7b88e4dc1bf0a8/ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05", size = 11516580 }, - { url = "https://files.pythonhosted.org/packages/37/1a/5ec1844e993e376a86eb2456496831ed91b4398c434d8244f89094758940/ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06", size = 12692057 }, - { url = "https://files.pythonhosted.org/packages/50/90/76867152b0d3c05df29a74bb028413e90f704f0f6701c4801174ba47f959/ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc", size = 11085137 }, - { url = "https://files.pythonhosted.org/packages/c8/eb/0a7cb6059ac3555243bd026bb21785bbc812f7bbfa95a36c101bd72b47ae/ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172", size = 10681243 }, - { url = "https://files.pythonhosted.org/packages/5e/76/2270719dbee0fd35780b05c08a07b7a726c3da9f67d9ae89ef21fc18e2e5/ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a", size = 10319187 }, - { url = "https://files.pythonhosted.org/packages/9f/e5/39100f72f8ba70bec1bd329efc880dea8b6c1765ea1cb9d0c1c5f18b8d7f/ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd", size = 10803715 }, - { url = "https://files.pythonhosted.org/packages/a5/89/40e904784f305fb56850063f70a998a64ebba68796d823dde67e89a24691/ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a", size = 11162912 }, - { url = "https://files.pythonhosted.org/packages/8d/1b/dd77503b3875c51e3dbc053fd8367b845ab8b01c9ca6d0c237082732856c/ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac", size = 8702767 }, - { url = "https://files.pythonhosted.org/packages/63/76/253ddc3e89e70165bba952ecca424b980b8d3c2598ceb4fc47904f424953/ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6", size = 9497534 }, - { url = "https://files.pythonhosted.org/packages/aa/70/f8724f31abc0b329ca98b33d73c14020168babcf71b0cba3cded5d9d0e66/ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f", size = 8851590 }, + { url = "https://files.pythonhosted.org/packages/72/f1/57e8327ab1508272029e27eeef34f2302ffc156b69e7e233e906c2a5c379/scipy-1.16.3-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:d2ec56337675e61b312179a1ad124f5f570c00f920cc75e1000025451b88241c", size = 36617856, upload-time = "2025-10-28T17:33:31.375Z" }, + { url = "https://files.pythonhosted.org/packages/44/13/7e63cfba8a7452eb756306aa2fd9b37a29a323b672b964b4fdeded9a3f21/scipy-1.16.3-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:16b8bc35a4cc24db80a0ec836a9286d0e31b2503cb2fd7ff7fb0e0374a97081d", size = 28874306, upload-time = "2025-10-28T17:33:36.516Z" }, + { url = "https://files.pythonhosted.org/packages/15/65/3a9400efd0228a176e6ec3454b1fa998fbbb5a8defa1672c3f65706987db/scipy-1.16.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:5803c5fadd29de0cf27fa08ccbfe7a9e5d741bf63e4ab1085437266f12460ff9", size = 20865371, upload-time = "2025-10-28T17:33:42.094Z" }, + { url = "https://files.pythonhosted.org/packages/33/d7/eda09adf009a9fb81827194d4dd02d2e4bc752cef16737cc4ef065234031/scipy-1.16.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:b81c27fc41954319a943d43b20e07c40bdcd3ff7cf013f4fb86286faefe546c4", size = 23524877, upload-time = "2025-10-28T17:33:48.483Z" }, + { url = "https://files.pythonhosted.org/packages/7d/6b/3f911e1ebc364cb81320223a3422aab7d26c9c7973109a9cd0f27c64c6c0/scipy-1.16.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0c3b4dd3d9b08dbce0f3440032c52e9e2ab9f96ade2d3943313dfe51a7056959", size = 33342103, upload-time = "2025-10-28T17:33:56.495Z" }, + { url = "https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88", size = 35697297, upload-time = "2025-10-28T17:34:04.722Z" }, + { url = "https://files.pythonhosted.org/packages/04/e1/6496dadbc80d8d896ff72511ecfe2316b50313bfc3ebf07a3f580f08bd8c/scipy-1.16.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:663b8d66a8748051c3ee9c96465fb417509315b99c71550fda2591d7dd634234", size = 36021756, upload-time = "2025-10-28T17:34:13.482Z" }, + { url = "https://files.pythonhosted.org/packages/fe/bd/a8c7799e0136b987bda3e1b23d155bcb31aec68a4a472554df5f0937eef7/scipy-1.16.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eab43fae33a0c39006a88096cd7b4f4ef545ea0447d250d5ac18202d40b6611d", size = 38696566, upload-time = "2025-10-28T17:34:22.384Z" }, + { url = "https://files.pythonhosted.org/packages/cd/01/1204382461fcbfeb05b6161b594f4007e78b6eba9b375382f79153172b4d/scipy-1.16.3-cp313-cp313-win_amd64.whl", hash = "sha256:062246acacbe9f8210de8e751b16fc37458213f124bef161a5a02c7a39284304", size = 38529877, upload-time = "2025-10-28T17:35:51.076Z" }, + { url = "https://files.pythonhosted.org/packages/7f/14/9d9fbcaa1260a94f4bb5b64ba9213ceb5d03cd88841fe9fd1ffd47a45b73/scipy-1.16.3-cp313-cp313-win_arm64.whl", hash = "sha256:50a3dbf286dbc7d84f176f9a1574c705f277cb6565069f88f60db9eafdbe3ee2", size = 25455366, upload-time = "2025-10-28T17:35:59.014Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a3/9ec205bd49f42d45d77f1730dbad9ccf146244c1647605cf834b3a8c4f36/scipy-1.16.3-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:fb4b29f4cf8cc5a8d628bc8d8e26d12d7278cd1f219f22698a378c3d67db5e4b", size = 37027931, upload-time = "2025-10-28T17:34:31.451Z" }, + { url = "https://files.pythonhosted.org/packages/25/06/ca9fd1f3a4589cbd825b1447e5db3a8ebb969c1eaf22c8579bd286f51b6d/scipy-1.16.3-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:8d09d72dc92742988b0e7750bddb8060b0c7079606c0d24a8cc8e9c9c11f9079", size = 29400081, upload-time = "2025-10-28T17:34:39.087Z" }, + { url = "https://files.pythonhosted.org/packages/6a/56/933e68210d92657d93fb0e381683bc0e53a965048d7358ff5fbf9e6a1b17/scipy-1.16.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:03192a35e661470197556de24e7cb1330d84b35b94ead65c46ad6f16f6b28f2a", size = 21391244, upload-time = "2025-10-28T17:34:45.234Z" }, + { url = "https://files.pythonhosted.org/packages/a8/7e/779845db03dc1418e215726329674b40576879b91814568757ff0014ad65/scipy-1.16.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:57d01cb6f85e34f0946b33caa66e892aae072b64b034183f3d87c4025802a119", size = 23929753, upload-time = "2025-10-28T17:34:51.793Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4b/f756cf8161d5365dcdef9e5f460ab226c068211030a175d2fc7f3f41ca64/scipy-1.16.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:96491a6a54e995f00a28a3c3badfff58fd093bf26cd5fb34a2188c8c756a3a2c", size = 33496912, upload-time = "2025-10-28T17:34:59.8Z" }, + { url = "https://files.pythonhosted.org/packages/09/b5/222b1e49a58668f23839ca1542a6322bb095ab8d6590d4f71723869a6c2c/scipy-1.16.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cd13e354df9938598af2be05822c323e97132d5e6306b83a3b4ee6724c6e522e", size = 35802371, upload-time = "2025-10-28T17:35:08.173Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8d/5964ef68bb31829bde27611f8c9deeac13764589fe74a75390242b64ca44/scipy-1.16.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63d3cdacb8a824a295191a723ee5e4ea7768ca5ca5f2838532d9f2e2b3ce2135", size = 36190477, upload-time = "2025-10-28T17:35:16.7Z" }, + { url = "https://files.pythonhosted.org/packages/ab/f2/b31d75cb9b5fa4dd39a0a931ee9b33e7f6f36f23be5ef560bf72e0f92f32/scipy-1.16.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e7efa2681ea410b10dde31a52b18b0154d66f2485328830e45fdf183af5aefc6", size = 38796678, upload-time = "2025-10-28T17:35:26.354Z" }, + { url = "https://files.pythonhosted.org/packages/b4/1e/b3723d8ff64ab548c38d87055483714fefe6ee20e0189b62352b5e015bb1/scipy-1.16.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2d1ae2cf0c350e7705168ff2429962a89ad90c2d49d1dd300686d8b2a5af22fc", size = 38640178, upload-time = "2025-10-28T17:35:35.304Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f3/d854ff38789aca9b0cc23008d607ced9de4f7ab14fa1ca4329f86b3758ca/scipy-1.16.3-cp313-cp313t-win_arm64.whl", hash = "sha256:0c623a54f7b79dd88ef56da19bc2873afec9673a48f3b85b18e4d402bdd29a5a", size = 25803246, upload-time = "2025-10-28T17:35:42.155Z" }, + { url = "https://files.pythonhosted.org/packages/99/f6/99b10fd70f2d864c1e29a28bbcaa0c6340f9d8518396542d9ea3b4aaae15/scipy-1.16.3-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:875555ce62743e1d54f06cdf22c1e0bc47b91130ac40fe5d783b6dfa114beeb6", size = 36606469, upload-time = "2025-10-28T17:36:08.741Z" }, + { url = "https://files.pythonhosted.org/packages/4d/74/043b54f2319f48ea940dd025779fa28ee360e6b95acb7cd188fad4391c6b/scipy-1.16.3-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:bb61878c18a470021fb515a843dc7a76961a8daceaaaa8bad1332f1bf4b54657", size = 28872043, upload-time = "2025-10-28T17:36:16.599Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e1/24b7e50cc1c4ee6ffbcb1f27fe9f4c8b40e7911675f6d2d20955f41c6348/scipy-1.16.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2622206f5559784fa5c4b53a950c3c7c1cf3e84ca1b9c4b6c03f062f289ca26", size = 20862952, upload-time = "2025-10-28T17:36:22.966Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3a/3e8c01a4d742b730df368e063787c6808597ccb38636ed821d10b39ca51b/scipy-1.16.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7f68154688c515cdb541a31ef8eb66d8cd1050605be9dcd74199cbd22ac739bc", size = 23508512, upload-time = "2025-10-28T17:36:29.731Z" }, + { url = "https://files.pythonhosted.org/packages/1f/60/c45a12b98ad591536bfe5330cb3cfe1850d7570259303563b1721564d458/scipy-1.16.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b3c820ddb80029fe9f43d61b81d8b488d3ef8ca010d15122b152db77dc94c22", size = 33413639, upload-time = "2025-10-28T17:36:37.982Z" }, + { url = "https://files.pythonhosted.org/packages/71/bc/35957d88645476307e4839712642896689df442f3e53b0fa016ecf8a3357/scipy-1.16.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d3837938ae715fc0fe3c39c0202de3a8853aff22ca66781ddc2ade7554b7e2cc", size = 35704729, upload-time = "2025-10-28T17:36:46.547Z" }, + { url = "https://files.pythonhosted.org/packages/3b/15/89105e659041b1ca11c386e9995aefacd513a78493656e57789f9d9eab61/scipy-1.16.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:aadd23f98f9cb069b3bd64ddc900c4d277778242e961751f77a8cb5c4b946fb0", size = 36086251, upload-time = "2025-10-28T17:36:55.161Z" }, + { url = "https://files.pythonhosted.org/packages/1a/87/c0ea673ac9c6cc50b3da2196d860273bc7389aa69b64efa8493bdd25b093/scipy-1.16.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b7c5f1bda1354d6a19bc6af73a649f8285ca63ac6b52e64e658a5a11d4d69800", size = 38716681, upload-time = "2025-10-28T17:37:04.1Z" }, + { url = "https://files.pythonhosted.org/packages/91/06/837893227b043fb9b0d13e4bd7586982d8136cb249ffb3492930dab905b8/scipy-1.16.3-cp314-cp314-win_amd64.whl", hash = "sha256:e5d42a9472e7579e473879a1990327830493a7047506d58d73fc429b84c1d49d", size = 39358423, upload-time = "2025-10-28T17:38:20.005Z" }, + { url = "https://files.pythonhosted.org/packages/95/03/28bce0355e4d34a7c034727505a02d19548549e190bedd13a721e35380b7/scipy-1.16.3-cp314-cp314-win_arm64.whl", hash = "sha256:6020470b9d00245926f2d5bb93b119ca0340f0d564eb6fbaad843eaebf9d690f", size = 26135027, upload-time = "2025-10-28T17:38:24.966Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6f/69f1e2b682efe9de8fe9f91040f0cd32f13cfccba690512ba4c582b0bc29/scipy-1.16.3-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:e1d27cbcb4602680a49d787d90664fa4974063ac9d4134813332a8c53dbe667c", size = 37028379, upload-time = "2025-10-28T17:37:14.061Z" }, + { url = "https://files.pythonhosted.org/packages/7c/2d/e826f31624a5ebbab1cd93d30fd74349914753076ed0593e1d56a98c4fb4/scipy-1.16.3-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:9b9c9c07b6d56a35777a1b4cc8966118fb16cfd8daf6743867d17d36cfad2d40", size = 29400052, upload-time = "2025-10-28T17:37:21.709Z" }, + { url = "https://files.pythonhosted.org/packages/69/27/d24feb80155f41fd1f156bf144e7e049b4e2b9dd06261a242905e3bc7a03/scipy-1.16.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:3a4c460301fb2cffb7f88528f30b3127742cff583603aa7dc964a52c463b385d", size = 21391183, upload-time = "2025-10-28T17:37:29.559Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d3/1b229e433074c5738a24277eca520a2319aac7465eea7310ea6ae0e98ae2/scipy-1.16.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:f667a4542cc8917af1db06366d3f78a5c8e83badd56409f94d1eac8d8d9133fa", size = 23930174, upload-time = "2025-10-28T17:37:36.306Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/d9e148b0ec680c0f042581a2be79a28a7ab66c0c4946697f9e7553ead337/scipy-1.16.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f379b54b77a597aa7ee5e697df0d66903e41b9c85a6dd7946159e356319158e8", size = 33497852, upload-time = "2025-10-28T17:37:42.228Z" }, + { url = "https://files.pythonhosted.org/packages/2f/22/4e5f7561e4f98b7bea63cf3fd7934bff1e3182e9f1626b089a679914d5c8/scipy-1.16.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4aff59800a3b7f786b70bfd6ab551001cb553244988d7d6b8299cb1ea653b353", size = 35798595, upload-time = "2025-10-28T17:37:48.102Z" }, + { url = "https://files.pythonhosted.org/packages/83/42/6644d714c179429fc7196857866f219fef25238319b650bb32dde7bf7a48/scipy-1.16.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:da7763f55885045036fabcebd80144b757d3db06ab0861415d1c3b7c69042146", size = 36186269, upload-time = "2025-10-28T17:37:53.72Z" }, + { url = "https://files.pythonhosted.org/packages/ac/70/64b4d7ca92f9cf2e6fc6aaa2eecf80bb9b6b985043a9583f32f8177ea122/scipy-1.16.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ffa6eea95283b2b8079b821dc11f50a17d0571c92b43e2b5b12764dc5f9b285d", size = 38802779, upload-time = "2025-10-28T17:37:59.393Z" }, + { url = "https://files.pythonhosted.org/packages/61/82/8d0e39f62764cce5ffd5284131e109f07cf8955aef9ab8ed4e3aa5e30539/scipy-1.16.3-cp314-cp314t-win_amd64.whl", hash = "sha256:d9f48cafc7ce94cf9b15c6bffdc443a81a27bf7075cf2dcd5c8b40f85d10c4e7", size = 39471128, upload-time = "2025-10-28T17:38:05.259Z" }, + { url = "https://files.pythonhosted.org/packages/64/47/a494741db7280eae6dc033510c319e34d42dd41b7ac0c7ead39354d1a2b5/scipy-1.16.3-cp314-cp314t-win_arm64.whl", hash = "sha256:21d9d6b197227a12dcbf9633320a4e34c6b0e51c57268df255a0942983bac562", size = 26464127, upload-time = "2025-10-28T17:38:11.34Z" }, ] [[package]] @@ -198,20 +304,20 @@ name = "tqdm" version = "4.67.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e8/4f/0153c21dc5779a49a0598c445b1978126b1344bab9ee71e53e44877e14e0/tqdm-4.67.0.tar.gz", hash = "sha256:fe5a6f95e6fe0b9755e9469b77b9c3cf850048224ecaa8293d7d2d31f97d869a", size = 169739 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/4f/0153c21dc5779a49a0598c445b1978126b1344bab9ee71e53e44877e14e0/tqdm-4.67.0.tar.gz", hash = "sha256:fe5a6f95e6fe0b9755e9469b77b9c3cf850048224ecaa8293d7d2d31f97d869a", size = 169739, upload-time = "2024-11-06T16:35:37.677Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/78/57043611a16c655c8350b4c01b8d6abfb38cc2acb475238b62c2146186d7/tqdm-4.67.0-py3-none-any.whl", hash = "sha256:0cd8af9d56911acab92182e88d763100d4788bdf421d251616040cc4d44863be", size = 78590 }, + { url = "https://files.pythonhosted.org/packages/2b/78/57043611a16c655c8350b4c01b8d6abfb38cc2acb475238b62c2146186d7/tqdm-4.67.0-py3-none-any.whl", hash = "sha256:0cd8af9d56911acab92182e88d763100d4788bdf421d251616040cc4d44863be", size = 78590, upload-time = "2024-11-06T16:35:35.023Z" }, ] [[package]] name = "typing-extensions" version = "4.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, ] [[package]] @@ -223,7 +329,7 @@ dependencies = [ { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/b3/7b6a79c5c8cf6d90ea681310e169cf2db2884f4d583d16c6e1d5a75a4e04/virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba", size = 6491145 } +sdist = { url = "https://files.pythonhosted.org/packages/8c/b3/7b6a79c5c8cf6d90ea681310e169cf2db2884f4d583d16c6e1d5a75a4e04/virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba", size = 6491145, upload-time = "2024-10-28T18:00:22.706Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ae/92/78324ff89391e00c8f4cf6b8526c41c6ef36b4ea2d2c132250b1a6fc2b8d/virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4", size = 3117838 }, + { url = "https://files.pythonhosted.org/packages/ae/92/78324ff89391e00c8f4cf6b8526c41c6ef36b4ea2d2c132250b1a6fc2b8d/virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4", size = 3117838, upload-time = "2024-10-28T18:00:19.994Z" }, ] From 8417cb758f758596b7af9893b6bc62e8e1ef1772 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Thu, 11 Dec 2025 07:06:06 +0000 Subject: [PATCH 24/26] 2025-11 --- Cargo.lock | 5 ++++ Cargo.toml | 3 +- rust/y2025/d10/y2025d10.rs | 4 +-- rust/y2025/d11/Cargo.toml | 7 +++++ rust/y2025/d11/y2025d11.rs | 59 ++++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 6 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 rust/y2025/d11/Cargo.toml create mode 100644 rust/y2025/d11/y2025d11.rs diff --git a/Cargo.lock b/Cargo.lock index ddc99ce..7fa64d0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,6 +133,7 @@ dependencies = [ "y2025d08", "y2025d09", "y2025d10", + "y2025d11", ] [[package]] @@ -1951,6 +1952,10 @@ dependencies = [ "itertools", ] +[[package]] +name = "y2025d11" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index c3b5f13..6bfbf92 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", "rust/y2025/d09", "rust/y2025/d10", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", "rust/y2025/d09", "rust/y2025/d10", "rust/y2025/d11", ] [package] @@ -67,3 +67,4 @@ y2025d07 = { path = "rust/y2025/d07" } y2025d08 = { path = "rust/y2025/d08" } y2025d09 = { path = "rust/y2025/d09" } y2025d10 = { path = "rust/y2025/d10" } +y2025d11 = { path = "rust/y2025/d11" } diff --git a/rust/y2025/d10/y2025d10.rs b/rust/y2025/d10/y2025d10.rs index bfabc59..83a9d4c 100644 --- a/rust/y2025/d10/y2025d10.rs +++ b/rust/y2025/d10/y2025d10.rs @@ -32,7 +32,7 @@ fn parse_input(input: String) -> Result, Box struct Machine { target: Vec, buttons: Vec>, - joltage: Vec, + _joltage: Vec, } impl FromStr for Machine { @@ -67,7 +67,7 @@ impl FromStr for Machine { Ok(Self { target, buttons, - joltage, + _joltage: joltage, }) } } diff --git a/rust/y2025/d11/Cargo.toml b/rust/y2025/d11/Cargo.toml new file mode 100644 index 0000000..93e0ed6 --- /dev/null +++ b/rust/y2025/d11/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d11" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d11.rs" diff --git a/rust/y2025/d11/y2025d11.rs b/rust/y2025/d11/y2025d11.rs new file mode 100644 index 0000000..7b262fb --- /dev/null +++ b/rust/y2025/d11/y2025d11.rs @@ -0,0 +1,59 @@ +use std::collections::HashMap; + +pub fn part1(input: String) -> Result> { + let outputs = parse_input(input)?; + Ok(n_paths(&outputs, "you", "out").to_string()) +} + +pub fn part2(input: String) -> Result> { + let outputs = parse_input(input)?; + let count = match ( + n_paths(&outputs, "fft", "dac"), + n_paths(&outputs, "dac", "fft"), + ) { + (0, 0) => 0, + (0, n) => n_paths(&outputs, "svr", "dac") * n * n_paths(&outputs, "fft", "out"), + (n, 0) => n_paths(&outputs, "svr", "fft") * n * n_paths(&outputs, "dac", "out"), + _ => return Err("loop".into()), + }; + Ok(count.to_string()) +} + +fn parse_input(input: String) -> Result>, Box> { + input + .trim() + .lines() + .map(|s| { + let (k, r) = s.split_once(": ").ok_or("Invalid input")?; + let v = r.split(' ').map(|s| s.to_string()).collect(); + Ok((k.to_string(), v)) + }) + .collect() +} + +fn n_paths(outputs: &HashMap>, from: &str, to: &str) -> u64 { + let mut counts = HashMap::from([(to.to_string(), 1)]); + n_paths_rec(outputs, from, to, &mut counts) +} + +fn n_paths_rec( + outputs: &HashMap>, + from: &str, + _to: &str, + counts: &mut HashMap, +) -> u64 { + match counts.get(from) { + Some(d) => *d, + None => { + let count = match outputs.get(from) { + Some(ns) => ns + .iter() + .map(|n| n_paths_rec(outputs, n, _to, counts)) + .sum(), + None => 0, + }; + counts.insert(from.to_string(), count); + count + } + } +} diff --git a/src/run.rs b/src/run.rs index d59eff4..95c786c 100644 --- a/src/run.rs +++ b/src/run.rs @@ -100,6 +100,7 @@ fn get_solution_functions( (2025, 8) => Ok((y2025d08::part1, y2025d08::part2)), (2025, 9) => Ok((y2025d09::part1, y2025d09::part2)), (2025, 10) => Ok((y2025d10::part1, y2025d10::part2)), + (2025, 11) => Ok((y2025d11::part1, y2025d11::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From 7b11f12984133fd3164f8be9221caa710907f506 Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Fri, 12 Dec 2025 08:28:06 +0000 Subject: [PATCH 25/26] 2025-12 parse --- Cargo.lock | 5 +++ Cargo.toml | 3 +- rust/y2025/d12/Cargo.toml | 7 ++++ rust/y2025/d12/y2025d12.rs | 83 ++++++++++++++++++++++++++++++++++++++ src/run.rs | 1 + 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 rust/y2025/d12/Cargo.toml create mode 100644 rust/y2025/d12/y2025d12.rs diff --git a/Cargo.lock b/Cargo.lock index 7fa64d0..d65d008 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,6 +134,7 @@ dependencies = [ "y2025d09", "y2025d10", "y2025d11", + "y2025d12", ] [[package]] @@ -1956,6 +1957,10 @@ dependencies = [ name = "y2025d11" version = "0.1.0" +[[package]] +name = "y2025d12" +version = "0.1.0" + [[package]] name = "yoke" version = "0.7.5" diff --git a/Cargo.toml b/Cargo.toml index 6bfbf92..ee644ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ "rust/y2024/d19", "rust/y2024/d20", "rust/y2024/d21", - "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", "rust/y2025/d09", "rust/y2025/d10", "rust/y2025/d11", + "rust/y2024/d24", "rust/y2025/d01", "rust/y2025/d02", "rust/y2025/d03", "rust/y2025/d04", "rust/y2025/d05", "rust/y2025/d06", "rust/y2025/d07", "rust/y2025/d08", "rust/y2025/d09", "rust/y2025/d10", "rust/y2025/d11", "rust/y2025/d12", ] [package] @@ -68,3 +68,4 @@ y2025d08 = { path = "rust/y2025/d08" } y2025d09 = { path = "rust/y2025/d09" } y2025d10 = { path = "rust/y2025/d10" } y2025d11 = { path = "rust/y2025/d11" } +y2025d12 = { path = "rust/y2025/d12" } diff --git a/rust/y2025/d12/Cargo.toml b/rust/y2025/d12/Cargo.toml new file mode 100644 index 0000000..374a817 --- /dev/null +++ b/rust/y2025/d12/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "y2025d12" +version = "0.1.0" +edition = "2021" + +[lib] +path = "y2025d12.rs" diff --git a/rust/y2025/d12/y2025d12.rs b/rust/y2025/d12/y2025d12.rs new file mode 100644 index 0000000..cc92e3a --- /dev/null +++ b/rust/y2025/d12/y2025d12.rs @@ -0,0 +1,83 @@ +use std::str::FromStr; + +pub fn part1(input: String) -> Result> { + let (shapes, spaces) = parse_input(input)?; + println!("{} {}", shapes.len(), spaces.len()); + println!("{:?}", shapes[0]); + println!("{:?}", spaces[0]); + Err("Solution not implemented".into()) +} + +pub fn part2(input: String) -> Result> { + // Solve part 2 + Err("Solution not implemented".into()) +} + +#[derive(Debug)] +struct Shape { + grid: [[bool; 3]; 3], +} + +impl Shape { + fn from_strs(block: &&[&str]) -> Self { + let mut grid = [[false; 3]; 3]; + for (row_idx, line) in block.iter().skip(1).enumerate() { + for (col_idx, ch) in line.chars().enumerate() { + if row_idx < 3 && col_idx < 3 { + grid[row_idx][col_idx] = ch == '#'; + } + } + } + + Shape { grid } + } +} + +#[derive(Debug)] +struct Space { + shape: (usize, usize), + counts: [usize; 6], +} + +impl FromStr for Space { + type Err = Box; + + fn from_str(s: &str) -> Result { + let (shape_str, counts_str) = s.split_once(": ").ok_or("Invalid line")?; + let (w, h) = shape_str.split_once('x').ok_or("Invalid line")?; + let count_parts: Vec<&str> = counts_str.split_whitespace().collect(); + if count_parts.len() != 6 { + return Err("Expected exactly 6 counts".into()); + } + let mut counts = [0; 6]; + for (i, part) in count_parts.iter().enumerate() { + counts[i] = part.parse()?; + } + + Ok(Space { + shape: (w.parse()?, h.parse()?), + counts, + }) + } +} + +fn parse_input(input: String) -> Result<(Vec, Vec), Box> { + let lines = input.trim().lines().collect::>(); + let blocks = lines.split(|s| *s == "").collect::>(); + let shapes = blocks + .iter() + .take_while(|b| { + b[0].chars().nth(0).map_or(false, |c| c.is_ascii_digit()) + && b[0].chars().nth(1) == Some(':') + }) + .map(Shape::from_strs) + .collect(); + + let spaces = blocks + .last() + .ok_or("Invalid input")? + .into_iter() + .map(|s| Space::from_str(*s)) + .collect::, _>>()?; + Ok((shapes, spaces)) +} diff --git a/src/run.rs b/src/run.rs index 95c786c..5a5380a 100644 --- a/src/run.rs +++ b/src/run.rs @@ -101,6 +101,7 @@ fn get_solution_functions( (2025, 9) => Ok((y2025d09::part1, y2025d09::part2)), (2025, 10) => Ok((y2025d10::part1, y2025d10::part2)), (2025, 11) => Ok((y2025d11::part1, y2025d11::part2)), + (2025, 12) => Ok((y2025d12::part1, y2025d12::part2)), _ => Err(format!("Solution code not found for {year}/{day}").into()), } } From b07489a88f0ed5bcc88b3bc64202ea3b2d11c3dd Mon Sep 17 00:00:00 2001 From: dfacoet <11651258+dfacoet@users.noreply.github.com> Date: Fri, 12 Dec 2025 08:48:12 +0000 Subject: [PATCH 26/26] 2025-12 --- rust/y2025/d12/y2025d12.rs | 75 ++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/rust/y2025/d12/y2025d12.rs b/rust/y2025/d12/y2025d12.rs index cc92e3a..13d0234 100644 --- a/rust/y2025/d12/y2025d12.rs +++ b/rust/y2025/d12/y2025d12.rs @@ -1,36 +1,12 @@ use std::str::FromStr; pub fn part1(input: String) -> Result> { - let (shapes, spaces) = parse_input(input)?; - println!("{} {}", shapes.len(), spaces.len()); - println!("{:?}", shapes[0]); - println!("{:?}", spaces[0]); - Err("Solution not implemented".into()) + let (areas, spaces) = parse_input(input)?; + Ok(spaces.iter().filter(|s| s.fits(&areas)).count().to_string()) } -pub fn part2(input: String) -> Result> { - // Solve part 2 - Err("Solution not implemented".into()) -} - -#[derive(Debug)] -struct Shape { - grid: [[bool; 3]; 3], -} - -impl Shape { - fn from_strs(block: &&[&str]) -> Self { - let mut grid = [[false; 3]; 3]; - for (row_idx, line) in block.iter().skip(1).enumerate() { - for (col_idx, ch) in line.chars().enumerate() { - if row_idx < 3 && col_idx < 3 { - grid[row_idx][col_idx] = ch == '#'; - } - } - } - - Shape { grid } - } +pub fn part2(_input: String) -> Result> { + Ok("Merry Christmas".into()) } #[derive(Debug)] @@ -61,23 +37,44 @@ impl FromStr for Space { } } -fn parse_input(input: String) -> Result<(Vec, Vec), Box> { +impl Space { + fn area(&self) -> usize { + self.shape.0 * self.shape.1 + } + + fn fits(&self, shapes: &[usize; 6]) -> bool { + let required_area: usize = shapes + .iter() + .zip(self.counts.iter()) + .map(|(s, n)| n * s) + .sum(); + required_area <= self.area() + } +} + +fn parse_input(input: String) -> Result<([usize; 6], Vec), Box> { let lines = input.trim().lines().collect::>(); - let blocks = lines.split(|s| *s == "").collect::>(); - let shapes = blocks + let blocks = lines.split(|s| s.is_empty()).collect::>(); + if blocks.len() != 7 { + return Err("Invalid input".into()); + } + let shape_areas = blocks .iter() - .take_while(|b| { - b[0].chars().nth(0).map_or(false, |c| c.is_ascii_digit()) - && b[0].chars().nth(1) == Some(':') + .take(6) + .map(|b| { + b.iter() + .map(|r| r.chars().filter(|c| *c == '#').count()) + .sum() }) - .map(Shape::from_strs) - .collect(); + .collect::>() + .try_into() + .unwrap(); let spaces = blocks .last() .ok_or("Invalid input")? - .into_iter() - .map(|s| Space::from_str(*s)) + .iter() + .map(|s| Space::from_str(s)) .collect::, _>>()?; - Ok((shapes, spaces)) + Ok((shape_areas, spaces)) }