Add Elm day 2
parent
2cf9264509
commit
edcc3caf91
|
@ -11,6 +11,7 @@
|
||||||
"elm/browser": "1.0.2",
|
"elm/browser": "1.0.2",
|
||||||
"elm/core": "1.0.5",
|
"elm/core": "1.0.5",
|
||||||
"elm/html": "1.0.0",
|
"elm/html": "1.0.0",
|
||||||
|
"elm/parser": "1.1.0",
|
||||||
"elm/svg": "1.0.1",
|
"elm/svg": "1.0.1",
|
||||||
"mdgriffith/elm-ui": "1.1.8",
|
"mdgriffith/elm-ui": "1.1.8",
|
||||||
"miniBill/elm-fast-dict": "1.1.0"
|
"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
115
elm/src/Main.elm
115
elm/src/Main.elm
|
@ -2,16 +2,16 @@ module Main exposing (main)
|
||||||
|
|
||||||
import Browser
|
import Browser
|
||||||
import Element
|
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.Background
|
||||||
import Element.Input
|
import Element.Input
|
||||||
import Task
|
|
||||||
|
|
||||||
import Puzzles.Day1 as Day1
|
import Puzzles.Day1 as Day1
|
||||||
|
import Puzzles.Day2 as Day2
|
||||||
|
import Task
|
||||||
|
import Tools.Colors as C
|
||||||
|
import Widget
|
||||||
import Widget.Customize
|
import Widget.Customize
|
||||||
|
import Widget.Material as Material
|
||||||
|
import Widget.Material.Typography as Typography
|
||||||
|
|
||||||
|
|
||||||
main : Program () Model Msg
|
main : Program () Model Msg
|
||||||
|
@ -31,17 +31,22 @@ type alias Model =
|
||||||
, output2 : Calculating
|
, output2 : Calculating
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Calculating
|
type Calculating
|
||||||
= Outcome String
|
= Outcome String
|
||||||
| Calculating
|
| Calculating
|
||||||
| InvalidInput String
|
| InvalidInput String
|
||||||
| NoInput
|
| NoInput
|
||||||
|
|
||||||
|
|
||||||
type Window
|
type Window
|
||||||
= Home
|
= Home
|
||||||
| Day Int
|
| Day Int
|
||||||
|
|
||||||
type alias Puzzle = String -> Result String String
|
|
||||||
|
type alias Puzzle =
|
||||||
|
String -> Result String String
|
||||||
|
|
||||||
|
|
||||||
getFunctions : Window -> ( Puzzle, Puzzle )
|
getFunctions : Window -> ( Puzzle, Puzzle )
|
||||||
getFunctions window =
|
getFunctions window =
|
||||||
|
@ -50,15 +55,19 @@ getFunctions window =
|
||||||
( always <| Err "There is no puzzle for this page!"
|
( always <| Err "There is no puzzle for this page!"
|
||||||
, always <| Err "There is no puzzle for this page!"
|
, always <| Err "There is no puzzle for this page!"
|
||||||
)
|
)
|
||||||
|
|
||||||
Day 1 ->
|
Day 1 ->
|
||||||
( Day1.puzzle1, Day1.puzzle2 )
|
( 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!"
|
||||||
, always <| Err "This puzzle has no implementation yet!"
|
, always <| Err "This puzzle has no implementation yet!"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
init : () -> ( Model, Cmd Msg )
|
init : () -> ( Model, Cmd Msg )
|
||||||
init () =
|
init () =
|
||||||
( { view = Home
|
( { view = Home
|
||||||
|
@ -89,16 +98,17 @@ update msg model =
|
||||||
}
|
}
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|
|
||||||
OnInput input ->
|
OnInput input ->
|
||||||
( { model
|
( { model
|
||||||
| input = input
|
| input = input
|
||||||
, output1 = Calculating
|
, output1 = Calculating
|
||||||
, output2 = Calculating
|
, output2 = Calculating
|
||||||
}
|
}
|
||||||
, if input == model.input then
|
, if input == model.input then
|
||||||
Cmd.none
|
Cmd.none
|
||||||
else
|
|
||||||
|
else
|
||||||
Cmd.batch
|
Cmd.batch
|
||||||
[ Task.succeed input
|
[ Task.succeed input
|
||||||
|> Task.map (getFunctions model.view |> Tuple.first)
|
|> Task.map (getFunctions model.view |> Tuple.first)
|
||||||
|
@ -108,48 +118,47 @@ update msg model =
|
||||||
|> Task.perform (Calculate2 model.view)
|
|> Task.perform (Calculate2 model.view)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
DoNothing ->
|
DoNothing ->
|
||||||
( model, Cmd.none )
|
( model, Cmd.none )
|
||||||
|
|
||||||
Calculate1 w (Ok s) ->
|
Calculate1 w (Ok s) ->
|
||||||
if w /= model.view then
|
if w /= model.view then
|
||||||
( model, Cmd.none )
|
( model, Cmd.none )
|
||||||
|
|
||||||
else
|
else
|
||||||
( { model | output1 = Outcome s }
|
( { model | output1 = Outcome s }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|
|
||||||
Calculate1 w (Err s) ->
|
Calculate1 w (Err s) ->
|
||||||
if w /= model.view then
|
if w /= model.view then
|
||||||
( model, Cmd.none )
|
( model, Cmd.none )
|
||||||
|
|
||||||
else
|
else
|
||||||
( { model | output1 = InvalidInput s }
|
( { model | output1 = InvalidInput s }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|
|
||||||
Calculate2 w (Ok s) ->
|
Calculate2 w (Ok s) ->
|
||||||
if w /= model.view then
|
if w /= model.view then
|
||||||
( model, Cmd.none )
|
( model, Cmd.none )
|
||||||
|
|
||||||
else
|
else
|
||||||
( { model | output2 = Outcome s }
|
( { model | output2 = Outcome s }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|
|
||||||
Calculate2 w (Err s) ->
|
Calculate2 w (Err s) ->
|
||||||
if w /= model.view then
|
if w /= model.view then
|
||||||
( model, Cmd.none )
|
( model, Cmd.none )
|
||||||
|
|
||||||
else
|
else
|
||||||
( { model | output2 = InvalidInput s }
|
( { model | output2 = InvalidInput s }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
subscriptions model =
|
subscriptions model =
|
||||||
Sub.none
|
Sub.none
|
||||||
|
@ -160,7 +169,7 @@ view model =
|
||||||
{ title = "Document Title"
|
{ title = "Document Title"
|
||||||
, body =
|
, body =
|
||||||
[ Widget.menuBar
|
[ Widget.menuBar
|
||||||
( Material.menuBar palette )
|
(Material.menuBar palette)
|
||||||
{ title =
|
{ title =
|
||||||
"aoc2023"
|
"aoc2023"
|
||||||
|> Element.text
|
|> Element.text
|
||||||
|
@ -180,10 +189,10 @@ view model =
|
||||||
|> Element.width
|
|> Element.width
|
||||||
, Element.alignTop
|
, Element.alignTop
|
||||||
]
|
]
|
||||||
( List.map
|
(List.map
|
||||||
(\(window, text) ->
|
(\( window, text ) ->
|
||||||
Widget.fullBleedItem
|
Widget.fullBleedItem
|
||||||
( Material.fullBleedItem palette )
|
(Material.fullBleedItem palette)
|
||||||
{ text = text
|
{ text = text
|
||||||
, onPress = Just (ChangeWindow window)
|
, onPress = Just (ChangeWindow window)
|
||||||
, icon = always Element.none
|
, icon = always Element.none
|
||||||
|
@ -203,32 +212,34 @@ view model =
|
||||||
, Element.padding 20
|
, Element.padding 20
|
||||||
, Element.spacing 20
|
, Element.spacing 20
|
||||||
]
|
]
|
||||||
( case model.view of
|
(case model.view of
|
||||||
Home ->
|
Home ->
|
||||||
[ "Advent of Code 2023"
|
[ "Advent of Code 2023"
|
||||||
|> Element.text
|
|> Element.text
|
||||||
|> Element.el Typography.h3
|
|> Element.el Typography.h3
|
||||||
]
|
]
|
||||||
|
|
||||||
Day i ->
|
Day i ->
|
||||||
[ [ "Using the following input for day " ++ String.fromInt i ++ ": "
|
[ [ "Using the following input for day "
|
||||||
|> Element.text
|
++ String.fromInt i
|
||||||
|
++ ": "
|
||||||
|
|> Element.text
|
||||||
, Element.Input.multiline
|
, Element.Input.multiline
|
||||||
[ Element.fill
|
[ Element.fill
|
||||||
|> Element.maximum 500
|
|> Element.maximum 500
|
||||||
|> Element.height
|
|> Element.height
|
||||||
, Element.scrollbarX
|
, Element.scrollbarX
|
||||||
]
|
]
|
||||||
{ onChange = OnInput
|
{ onChange = OnInput
|
||||||
, text = model.input
|
, text = model.input
|
||||||
, placeholder =
|
, placeholder =
|
||||||
"Insert puzzle input here..."
|
"Insert puzzle input here..."
|
||||||
|> Element.text
|
|> Element.text
|
||||||
|> Element.Input.placeholder []
|
|> Element.Input.placeholder []
|
||||||
|> Just
|
|> Just
|
||||||
, label = Element.Input.labelHidden "input"
|
, label = Element.Input.labelHidden "input"
|
||||||
, spellcheck = False
|
, spellcheck = False
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
, case model.output1 of
|
, case model.output1 of
|
||||||
Outcome s ->
|
Outcome s ->
|
||||||
|
@ -243,12 +254,12 @@ view model =
|
||||||
, spellcheck = False
|
, spellcheck = False
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
Calculating ->
|
Calculating ->
|
||||||
[ "Calculating part 1..."
|
[ "Calculating part 1..."
|
||||||
|> Element.text
|
|> Element.text
|
||||||
]
|
]
|
||||||
|
|
||||||
InvalidInput s ->
|
InvalidInput s ->
|
||||||
[ "INVALID INPUT FOR PART 1"
|
[ "INVALID INPUT FOR PART 1"
|
||||||
|> Element.text
|
|> Element.text
|
||||||
|
@ -261,7 +272,7 @@ view model =
|
||||||
, spellcheck = False
|
, spellcheck = False
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
NoInput ->
|
NoInput ->
|
||||||
List.singleton Element.none
|
List.singleton Element.none
|
||||||
, case model.output2 of
|
, case model.output2 of
|
||||||
|
@ -277,12 +288,12 @@ view model =
|
||||||
, spellcheck = False
|
, spellcheck = False
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
Calculating ->
|
Calculating ->
|
||||||
[ "Calculating part 2..."
|
[ "Calculating part 2..."
|
||||||
|> Element.text
|
|> Element.text
|
||||||
]
|
]
|
||||||
|
|
||||||
InvalidInput s ->
|
InvalidInput s ->
|
||||||
[ "INVALID INPUT FOR PART 2"
|
[ "INVALID INPUT FOR PART 2"
|
||||||
|> Element.text
|
|> Element.text
|
||||||
|
@ -295,7 +306,7 @@ view model =
|
||||||
, spellcheck = False
|
, spellcheck = False
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
NoInput ->
|
NoInput ->
|
||||||
List.singleton Element.none
|
List.singleton Element.none
|
||||||
]
|
]
|
||||||
|
@ -308,10 +319,12 @@ view model =
|
||||||
|> List.singleton
|
|> List.singleton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
picker : C.Picker
|
picker : C.Picker
|
||||||
picker =
|
picker =
|
||||||
C.get C.Trichromatic C.LightMode
|
C.get C.Trichromatic C.LightMode
|
||||||
|
|
||||||
|
|
||||||
palette : Material.Palette
|
palette : Material.Palette
|
||||||
palette =
|
palette =
|
||||||
C.defaultPalette picker
|
C.defaultPalette picker
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
module Puzzles.Day1 exposing (puzzle1, puzzle2)
|
module Puzzles.Day1 exposing (puzzle1, puzzle2)
|
||||||
|
|
||||||
|
|
||||||
puzzle1 : String -> Result String String
|
puzzle1 : String -> Result String String
|
||||||
puzzle1 input =
|
puzzle1 input =
|
||||||
input
|
input
|
||||||
|
@ -10,25 +11,25 @@ puzzle1 input =
|
||||||
case items of
|
case items of
|
||||||
head :: tail ->
|
head :: tail ->
|
||||||
Ok (calibrationValue head tail)
|
Ok (calibrationValue head tail)
|
||||||
|
|
||||||
[] ->
|
[] ->
|
||||||
Err i
|
Err i
|
||||||
)
|
)
|
||||||
|> List.foldl
|
|> List.foldl
|
||||||
(\value sum ->
|
(\value sum ->
|
||||||
case (value, sum) of
|
case ( value, sum ) of
|
||||||
(_, Err _) ->
|
( _, Err _ ) ->
|
||||||
sum
|
sum
|
||||||
|
|
||||||
(Err i, Ok _) ->
|
( Err i, Ok _ ) ->
|
||||||
Err ("Line" ++ (String.fromInt <| i + 1) ++ "does not contain any numbers")
|
Err ("Line" ++ (String.fromInt <| i + 1) ++ "does not contain any numbers")
|
||||||
|
|
||||||
(Ok a, Ok b) ->
|
( Ok a, Ok b ) ->
|
||||||
Ok (a + b)
|
Ok (a + b)
|
||||||
)
|
)
|
||||||
(Ok 0)
|
(Ok 0)
|
||||||
|> Result.map String.fromInt
|
|> Result.map String.fromInt
|
||||||
|
|
||||||
|
|
||||||
puzzle1Nums : String -> List Int
|
puzzle1Nums : String -> List Int
|
||||||
puzzle1Nums s =
|
puzzle1Nums s =
|
||||||
|
@ -37,13 +38,15 @@ puzzle1Nums s =
|
||||||
|> List.map String.fromChar
|
|> List.map String.fromChar
|
||||||
|> List.filterMap String.toInt
|
|> List.filterMap String.toInt
|
||||||
|
|
||||||
|
|
||||||
calibrationValue : Int -> List Int -> Int
|
calibrationValue : Int -> List Int -> Int
|
||||||
calibrationValue head tail =
|
calibrationValue head tail =
|
||||||
tail
|
tail
|
||||||
|> List.reverse
|
|> List.reverse
|
||||||
|> List.head
|
|> List.head
|
||||||
|> Maybe.withDefault head
|
|> Maybe.withDefault head
|
||||||
|> (+) ( head * 10 )
|
|> (+) (head * 10)
|
||||||
|
|
||||||
|
|
||||||
puzzle2 : String -> Result String String
|
puzzle2 : String -> Result String String
|
||||||
puzzle2 input =
|
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
|
Color.rgba 0 0 0 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- PRIMARY COLOR
|
-- PRIMARY COLOR
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue