commit d4ee2ebf23f77f5ffb76cc3464adc3b128f7161e parent ccc30ec73637c8ad5f1b62e0983763075f6cbf6f Author: Robert Russell <robert@rr3.xyz> Date: Sun, 7 Dec 2025 10:21:31 -0800 Solve 02 again Diffstat:
| M | 02/Main.hs | | | 24 | ++++++++++++++++++------ |
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/02/Main.hs b/02/Main.hs @@ -32,24 +32,36 @@ hasConsensus (x : xs) = all (== x) xs -- of k identical sequences of digits (this is effectively what we get from the -- problem statement). Equivalently, a number n is k-silly iff k divides the -- number d of base-10 digits in n and the digits in n's base-10^k --- representation are identical. We use the latter characterization. +-- representation are identical (this is isSillyA). Equivalently, a number n is +-- k-silly iff k divides d and (11...11)_{10^(d/k)} divides n (this is +-- isSillyB). -- -- Part 1 asks us to sum all 2-silly numbers in the input ranges. -- Part 2 asks us to sum all numbers that are k-silly for some k >= 2. data Range = Range Natural Natural deriving (Show) -elems :: Range -> [Natural] -elems (Range l u) = [l .. u] - -isSilly :: Natural -> Natural -> Bool -isSilly k n = +isSillyA :: Natural -> Natural -> Bool +isSillyA k n = let d = numDigits 10 n in k `divides` d && hasConsensus (digits (10 ^ (d `div` k)) n) +isSillyB :: Natural -> Natural -> Bool +isSillyB k n = + let d = numDigits 10 n + mask 1 = 1 + mask i = mask (i - 1) * 10 ^ (d `div` k) + 1 + in k `divides` d && mask k `divides` n + +isSilly :: Natural -> Natural -> Bool +isSilly = isSillyB + isAnySilly :: Natural -> Bool isAnySilly n = any (`isSilly` n) [2 .. numDigits 10 n] +elems :: Range -> [Natural] +elems (Range l u) = [l .. u] + part1 :: [Range] -> Natural part1 = sum . filter (isSilly 2) . (>>= elems)