Add Elm day 2

main
Bram 2023-12-28 12:05:45 +01:00
parent 2cf9264509
commit edcc3caf91
7 changed files with 1227 additions and 108 deletions

View File

@ -11,6 +11,7 @@
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/parser": "1.1.0",
"elm/svg": "1.0.1",
"mdgriffith/elm-ui": "1.1.8",
"miniBill/elm-fast-dict": "1.1.0"

File diff suppressed because it is too large Load Diff

View File

@ -2,16 +2,16 @@ module Main exposing (main)
import Browser
import Element
import Tools.Colors as C
import Widget
import Widget.Material as Material
import Widget.Material.Typography as Typography
import Element.Background
import Element.Input
import Task
import Puzzles.Day1 as Day1
import Puzzles.Day2 as Day2
import Task
import Tools.Colors as C
import Widget
import Widget.Customize
import Widget.Material as Material
import Widget.Material.Typography as Typography
main : Program () Model Msg
@ -31,17 +31,22 @@ type alias Model =
, output2 : Calculating
}
type Calculating
= Outcome String
| Calculating
| InvalidInput String
| NoInput
type Window
= Home
| Day Int
type alias Puzzle = String -> Result String String
type alias Puzzle =
String -> Result String String
getFunctions : Window -> ( Puzzle, Puzzle )
getFunctions window =
@ -54,11 +59,15 @@ getFunctions window =
Day 1 ->
( Day1.puzzle1, Day1.puzzle2 )
Day 2 ->
( Day2.puzzle1, Day2.puzzle2 )
_ ->
( always <| Err "This puzzle has no implementation yet!"
, always <| Err "This puzzle has no implementation yet!"
)
init : () -> ( Model, Cmd Msg )
init () =
( { view = Home
@ -98,6 +107,7 @@ update msg model =
}
, if input == model.input then
Cmd.none
else
Cmd.batch
[ Task.succeed input
@ -149,7 +159,6 @@ update msg model =
)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
@ -211,7 +220,9 @@ view model =
]
Day i ->
[ [ "Using the following input for day " ++ String.fromInt i ++ ": "
[ [ "Using the following input for day "
++ String.fromInt i
++ ": "
|> Element.text
, Element.Input.multiline
[ Element.fill
@ -308,10 +319,12 @@ view model =
|> List.singleton
}
picker : C.Picker
picker =
C.get C.Trichromatic C.LightMode
palette : Material.Palette
palette =
C.defaultPalette picker

View File

@ -1,5 +1,6 @@
module Puzzles.Day1 exposing (puzzle1, puzzle2)
puzzle1 : String -> Result String String
puzzle1 input =
input
@ -37,6 +38,7 @@ puzzle1Nums s =
|> List.map String.fromChar
|> List.filterMap String.toInt
calibrationValue : Int -> List Int -> Int
calibrationValue head tail =
tail
@ -45,6 +47,7 @@ calibrationValue head tail =
|> Maybe.withDefault head
|> (+) (head * 10)
puzzle2 : String -> Result String String
puzzle2 input =
input

150
elm/src/Puzzles/Day2.elm Normal file
View File

@ -0,0 +1,150 @@
module Puzzles.Day2 exposing (puzzle1, puzzle2)
import Parser as P exposing ((|.), (|=), Parser)
type alias Game =
{ number : Int, games : List RGB }
type alias RGB =
{ red : Int, green : Int, blue : Int }
maxAllowed : RGB
maxAllowed =
{ red = 12, green = 13, blue = 14 }
puzzle1 : String -> Result String String
puzzle1 input =
case P.run parser input of
Err a ->
Debug.log "Output" a
|> always (Err "Invalid input")
Ok g ->
g
|> List.map
(\{ number, games } ->
let
isLegal : Bool
isLegal =
List.all
(\rgb ->
List.all
(\f -> f rgb <= f maxAllowed)
[ .red, .green, .blue ]
)
games
in
if isLegal then
number
else
0
)
|> List.sum
|> String.fromInt
|> Ok
puzzle2 : String -> Result String String
puzzle2 input =
case P.run parser input of
Err a ->
Debug.log "Output" a
|> always (Err "Invalid input")
-- 179502 too high
Ok g ->
g
|> List.map
(\{ games } ->
let
getMaximumFor : (RGB -> Int) -> Int
getMaximumFor f =
games
|> List.map f
|> List.maximum
|> Maybe.withDefault 0
in
[ .red, .green, .blue ]
|> List.map getMaximumFor
|> List.product
)
|> List.sum
|> String.fromInt
|> Ok
parser : Parser (List Game)
parser =
andOneMore
{ separator = "\n"
, item = gameParser
}
gameParser : Parser Game
gameParser =
P.succeed Game
|. P.keyword "Game"
|. P.spaces
|= P.int
|. P.symbol ":"
|. P.spaces
|= rgbLines
rgbLines : Parser (List RGB)
rgbLines =
andOneMore
{ separator = ";"
, item = rgbParser
}
rgbParser : Parser RGB
rgbParser =
P.succeed (List.foldl (<|) (RGB 0 0 0))
|= andOneMore
{ separator = ","
, item = rgbStmt
}
rgbStmt : Parser (RGB -> RGB)
rgbStmt =
P.succeed (|>)
|= P.int
|. P.spaces
|= P.oneOf
[ P.succeed (\i rgb -> { rgb | red = i })
|. P.keyword "red"
, P.succeed (\i rgb -> { rgb | blue = i })
|. P.keyword "blue"
, P.succeed (\i rgb -> { rgb | green = i })
|. P.keyword "green"
]
andOneMore : { separator : String, item : Parser a } -> Parser (List a)
andOneMore { separator, item } =
P.loop []
(\xs ->
P.succeed (\x state -> state (x :: xs))
|= item
|. onlySpaces
|= P.oneOf
[ P.succeed P.Loop
|. P.token separator
, P.succeed P.Done
]
|. onlySpaces
)
onlySpaces : Parser ()
onlySpaces =
P.chompWhile (\c -> c == ' ')

11
elm/src/Puzzles/DayX.elm Normal file
View File

@ -0,0 +1,11 @@
module Puzzles.DayX exposing (puzzle1, puzzle2)
puzzle1 : String -> Result String String
puzzle1 _ =
Err "Not implemented yet!"
puzzle2 : String -> Result String String
puzzle2 _ =
Err "Not implemented yet!"

View File

@ -409,6 +409,7 @@ transparent =
Color.rgba 0 0 0 0
-- PRIMARY COLOR