Day6 and let identifiers contain ?

This commit is contained in:
2024-11-30 17:07:49 -08:00
parent 71cf4f39f5
commit 53a0f96207
9 changed files with 412 additions and 40 deletions

19
aoc2023/Aoc.newt Normal file
View File

@@ -0,0 +1,19 @@
module Aoc
import Prelude
nums : String List Int
nums s = map stringToInt $ filter (_/=_ "") $ split (trim s) " "
isDigit : Char -> Bool
isDigit '0' = True
isDigit '1' = True
isDigit '2' = True
isDigit '3' = True
isDigit '4' = True
isDigit '5' = True
isDigit '6' = True
isDigit '7' = True
isDigit '8' = True
isDigit '9' = True
isDigit _ = False

View File

@@ -2,6 +2,7 @@ module Day3
import Prelude
import Node
import Aoc
pfunc repr : {a : U} -> a -> String := `(a,o) => ''+o`
pfunc jrepr : {a : U} -> a -> String := `(a,o) => JSON.stringify(o, null, ' ')`
@@ -15,18 +16,6 @@ maybe def f (Just a) = f a
data Number : U where
MkNumber : (start : Nat) -> (stop : Nat) (value : Int) Number
isDigit : Char -> Bool
isDigit '0' = True
isDigit '1' = True
isDigit '2' = True
isDigit '3' = True
isDigit '4' = True
isDigit '5' = True
isDigit '6' = True
isDigit '7' = True
isDigit '8' = True
isDigit '9' = True
isDigit _ = False
numbers : List Char -> List Number
numbers arr = go arr Z

74
aoc2023/Day6.newt Normal file
View File

@@ -0,0 +1,74 @@
module Day6
import Prelude
import Node
import Aoc
Problem : U
Problem = List (Int × Int)
pNums : String Either String (List Int)
pNums line =
let (_ :: line :: Nil) = split line ": "
| _ => Left "expected two parts" in
Right $ nums line
parse : String Either String Problem
parse content = do
let (a :: b :: Nil) = split (trim content) "\n"
| _ => Left "expected two lines"
times <- pNums a
dists <- pNums b
Right (zip times dists)
part1 : Problem Int
part1 prob = go 1 prob
where
run : Int -> Int -> Int Int Int
run time dist t count =
let count = if dist < t * (time - t) then count + 1 else count in
if time == t then count
else run time dist (t + 1) count
go : Int Problem Int
go acc Nil = acc
go acc ((time,dist) :: prob) = go (acc * run time dist 0 0) prob
part2 : Int × Int IO Unit
part2 (time,dist) = do
let t = intToDouble time
let d = intToDouble dist
let x = sqrtDouble (t * t - intToDouble 4 * d)
let start = (t - x) / intToDouble 2
let stop = (t + x) / intToDouble 2
let s = doubleToInt $ ceilDouble start
let e = doubleToInt $ ceilDouble stop
putStrLn $ "part2 " ++ show (e - s)
parse2 : String Either String (Int × Int)
parse2 content =
let (a :: b :: Nil) = split (trim content) "\n"
| _ => Left "too many parts" in
let time = stringToInt $ pack $ filter isDigit $ unpack a
dist = stringToInt $ pack $ filter isDigit $ unpack b
in Right (time, dist)
run : String -> IO Unit
run fn = do
putStrLn fn
text <- readFile fn
let (Right prob) = parse text | Left err => putStrLn err
putStrLn $ debugStr prob
putStrLn $ "part1 " ++ show (part1 prob)
let (Right prob) = parse2 text | Left err => putStrLn err
part2 prob
-- debugLog prob
-- part2 prob
-- 288 / 71503
-- 1413720 / 30565288
main : IO Unit
main = do
run "aoc2023/day6/eg.txt"
run "aoc2023/day6/input.txt"

View File

@@ -187,10 +187,13 @@ infixl 7 _+_
class Add a where
_+_ : a a a
infixl 8 _*_
infixl 8 _*_ _/_
class Mul a where
_*_ : a a a
class Div a where
_/_ : a a a
instance Add Nat where
Z + m = m
S n + m = S (n + m)
@@ -535,3 +538,29 @@ elem v (x :: xs) = if v == x then True else elem v xs
-- sum : ∀ a. {{Add a}} → List a → a
-- sum xs = foldl _+_
pfunc trace uses (debugStr) : a. String -> a -> a := `(_, msg, a) => { console.log(msg,debugStr(_,a)); return a }`
mapMaybe : a b. (a Maybe b) List a List b
mapMaybe f Nil = Nil
mapMaybe f (x :: xs) = case f x of
Just y => y :: mapMaybe f xs
Nothing => mapMaybe f xs
zip : a b. List a List b List (a × b)
zip (x :: xs) (y :: ys) = (x,y) :: zip xs ys
zip _ _ = Nil
-- TODO add double literals
ptype Double
pfunc intToDouble : Int Double := `(x) => x`
pfunc doubleToInt : Double Int := `(x) => x`
pfunc addDouble : Double Double Double := `(x,y) => x + y`
pfunc subDouble : Double Double Double := `(x,y) => x - y`
pfunc mulDouble : Double Double Double := `(x,y) => x * y`
pfunc divDouble : Double Double Double := `(x,y) => x / y`
pfunc sqrtDouble : Double Double := `(x) => Math.sqrt(x)`
pfunc ceilDouble : Double Double := `(x) => Math.ceil(x)`
instance Add Double where x + y = addDouble x y
instance Sub Double where x - y = subDouble x y
instance Mul Double where x * y = mulDouble x y
instance Div Double where x / y = divDouble x y

2
aoc2023/day6/eg.txt Normal file
View File

@@ -0,0 +1,2 @@
Time: 7 15 30
Distance: 9 40 200