aboutsummaryrefslogtreecommitdiff
path: root/2020/25a.hs
diff options
context:
space:
mode:
Diffstat (limited to '2020/25a.hs')
-rw-r--r--2020/25a.hs43
1 files changed, 43 insertions, 0 deletions
diff --git a/2020/25a.hs b/2020/25a.hs
new file mode 100644
index 0000000..7b96ed4
--- /dev/null
+++ b/2020/25a.hs
@@ -0,0 +1,43 @@
+module Day25A where
+
+import System.Environment (getArgs)
+import Text.Printf (printf)
+import Data.Bits
+
+modExp :: Integer -> Integer -> Integer -> Integer
+modExp b 0 m = 1
+modExp b e m = t * modExp ((b * b) `mod` m) (shiftR e 1) m `mod` m
+ where t = if testBit e 0 then b `mod` m else 1
+
+-- subject, loop size
+encrypt :: Integer -> Integer -> Integer
+encrypt s n = modExp s n 20201227
+
+-- Brute force the loop size used for the given number with the given subject
+bruteLoopSize :: Integer -> Integer -> Integer
+bruteLoopSize k s = getNEqual 1 1
+ where getNEqual n x | new == k = n
+ | otherwise = getNEqual (n + 1) new
+ where new = (x * s) `mod` 20201227
+
+parseFile :: String -> IO (Integer, Integer)
+parseFile f = do
+ c <- readFile f;
+ let [a, b] = map read $ lines c;
+ return (a, b);
+
+-- runghc 25a.hs inputs/day25
+main :: IO ()
+main = do
+ args <- getArgs;
+ (a, b) <- parseFile $ head args;
+
+ let aLoop = bruteLoopSize a 7;
+ let bLoop = bruteLoopSize b 7;
+
+ printf "a loop size = %d\nb loop size = %d\n" aLoop bLoop;
+
+ let enc = encrypt a bLoop;
+ printf "key = %d\n" enc;
+
+ return ();