Add Elm day 2
parent
2cf9264509
commit
edcc3caf91
|
@ -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"
|
||||
|
|
1036
elm/index.html
1036
elm/index.html
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
@ -92,13 +101,14 @@ update msg model =
|
|||
|
||||
OnInput input ->
|
||||
( { model
|
||||
| input = input
|
||||
, output1 = Calculating
|
||||
, output2 = Calculating
|
||||
| input = input
|
||||
, output1 = Calculating
|
||||
, output2 = Calculating
|
||||
}
|
||||
, if input == model.input then
|
||||
Cmd.none
|
||||
else
|
||||
|
||||
else
|
||||
Cmd.batch
|
||||
[ Task.succeed input
|
||||
|> Task.map (getFunctions model.view |> Tuple.first)
|
||||
|
@ -149,7 +159,6 @@ update msg model =
|
|||
)
|
||||
|
||||
|
||||
|
||||
subscriptions : Model -> Sub Msg
|
||||
subscriptions model =
|
||||
Sub.none
|
||||
|
@ -160,7 +169,7 @@ view model =
|
|||
{ title = "Document Title"
|
||||
, body =
|
||||
[ Widget.menuBar
|
||||
( Material.menuBar palette )
|
||||
(Material.menuBar palette)
|
||||
{ title =
|
||||
"aoc2023"
|
||||
|> Element.text
|
||||
|
@ -180,10 +189,10 @@ view model =
|
|||
|> Element.width
|
||||
, Element.alignTop
|
||||
]
|
||||
( List.map
|
||||
(\(window, text) ->
|
||||
(List.map
|
||||
(\( window, text ) ->
|
||||
Widget.fullBleedItem
|
||||
( Material.fullBleedItem palette )
|
||||
(Material.fullBleedItem palette)
|
||||
{ text = text
|
||||
, onPress = Just (ChangeWindow window)
|
||||
, icon = always Element.none
|
||||
|
@ -203,7 +212,7 @@ view model =
|
|||
, Element.padding 20
|
||||
, Element.spacing 20
|
||||
]
|
||||
( case model.view of
|
||||
(case model.view of
|
||||
Home ->
|
||||
[ "Advent of Code 2023"
|
||||
|> Element.text
|
||||
|
@ -211,24 +220,26 @@ view model =
|
|||
]
|
||||
|
||||
Day i ->
|
||||
[ [ "Using the following input for day " ++ String.fromInt i ++ ": "
|
||||
|> Element.text
|
||||
[ [ "Using the following input for day "
|
||||
++ String.fromInt i
|
||||
++ ": "
|
||||
|> Element.text
|
||||
, Element.Input.multiline
|
||||
[ Element.fill
|
||||
[ Element.fill
|
||||
|> Element.maximum 500
|
||||
|> Element.height
|
||||
, Element.scrollbarX
|
||||
]
|
||||
{ onChange = OnInput
|
||||
, text = model.input
|
||||
, placeholder =
|
||||
"Insert puzzle input here..."
|
||||
|> Element.text
|
||||
|> Element.Input.placeholder []
|
||||
|> Just
|
||||
, label = Element.Input.labelHidden "input"
|
||||
, spellcheck = False
|
||||
}
|
||||
, Element.scrollbarX
|
||||
]
|
||||
{ onChange = OnInput
|
||||
, text = model.input
|
||||
, placeholder =
|
||||
"Insert puzzle input here..."
|
||||
|> Element.text
|
||||
|> Element.Input.placeholder []
|
||||
|> Just
|
||||
, label = Element.Input.labelHidden "input"
|
||||
, spellcheck = False
|
||||
}
|
||||
]
|
||||
, case model.output1 of
|
||||
Outcome s ->
|
||||
|
@ -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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
module Puzzles.Day1 exposing (puzzle1, puzzle2)
|
||||
|
||||
|
||||
puzzle1 : String -> Result String String
|
||||
puzzle1 input =
|
||||
input
|
||||
|
@ -16,14 +17,14 @@ puzzle1 input =
|
|||
)
|
||||
|> List.foldl
|
||||
(\value sum ->
|
||||
case (value, sum) of
|
||||
(_, Err _) ->
|
||||
case ( value, sum ) of
|
||||
( _, Err _ ) ->
|
||||
sum
|
||||
|
||||
(Err i, Ok _) ->
|
||||
( Err i, Ok _ ) ->
|
||||
Err ("Line" ++ (String.fromInt <| i + 1) ++ "does not contain any numbers")
|
||||
|
||||
(Ok a, Ok b) ->
|
||||
( Ok a, Ok b ) ->
|
||||
Ok (a + b)
|
||||
)
|
||||
(Ok 0)
|
||||
|
@ -37,13 +38,15 @@ puzzle1Nums s =
|
|||
|> List.map String.fromChar
|
||||
|> List.filterMap String.toInt
|
||||
|
||||
|
||||
calibrationValue : Int -> List Int -> Int
|
||||
calibrationValue head tail =
|
||||
tail
|
||||
|> List.reverse
|
||||
|> List.head
|
||||
|> Maybe.withDefault head
|
||||
|> (+) ( head * 10 )
|
||||
|> (+) (head * 10)
|
||||
|
||||
|
||||
puzzle2 : String -> Result String String
|
||||
puzzle2 input =
|
||||
|
|
|
@ -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 == ' ')
|
|
@ -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!"
|
|
@ -409,6 +409,7 @@ transparent =
|
|||
Color.rgba 0 0 0 0
|
||||
|
||||
|
||||
|
||||
-- PRIMARY COLOR
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue