Day6 and let identifiers contain ?
This commit is contained in:
19
aoc2023/Aoc.newt
Normal file
19
aoc2023/Aoc.newt
Normal 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
|
||||
@@ -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
74
aoc2023/Day6.newt
Normal 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"
|
||||
@@ -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
2
aoc2023/day6/eg.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Time: 7 15 30
|
||||
Distance: 9 40 200
|
||||
Reference in New Issue
Block a user