-
Notifications
You must be signed in to change notification settings - Fork 0
/
Solution.elm
116 lines (95 loc) · 2.71 KB
/
Solution.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
module Five.Solution exposing (..)
import Html exposing (..)
import Html.Events exposing (onInput)
import Html.Attributes exposing (style)
import Browser
import AssocList as Dict exposing (Dict)
import List.Extra as List
import Maybe.Extra as Maybe
import Regex
main : Program () Model Msg
main =
Browser.sandbox
{ init = init
, view = view
, update = update
}
type Msg = OnInputChange String
type alias Model =
{ result : (String, String)
, input : String
}
init : Model
init =
{ result = ("", "")
, input = ""
}
view : Model -> Html Msg
view model =
div [style "display" "flex", style "flex-direction" "column", style "align-items" "center", style "margin" "40px"]
[ textarea
[style "width" "600px", style "height" "400px"
, onInput OnInputChange
]
[]
, p [style "font-size" "20px"] [text <| "Solution 1: " ++ (Tuple.first model.result)]
, p [style "font-size" "20px"] [text <| "Solution 2: " ++ (Tuple.second model.result)]
]
update : Msg -> Model -> Model
update msg model =
case msg of
OnInputChange a ->
{ model
| result = (String.fromInt <| solve1 a, String.fromInt <| solve2 a)
, input = a
}
parseNum : String -> List Int
parseNum str =
let regexNum = Maybe.withDefault Regex.never <| Regex.fromString "\\d+"
in
Regex.find regexNum str |>
List.map .match |>
Maybe.traverse String.toInt |>
Maybe.withDefault []
solve1 : String -> Int
solve1 str =
let
blocks = String.split "\n\n" str
seeds = List.head blocks |> Maybe.withDefault "" |> parseNum
mappings = List.tail blocks |> Maybe.withDefault []
in
seeds |>
List.map (traverseMapping mappings) |>
List.minimum |>
Maybe.withDefault 0
traverseMapping : List String -> Int -> Int
traverseMapping maps seed = List.foldl mapId (Just seed) maps |> Maybe.withDefault 0
mapId : String -> Maybe Int -> Maybe Int
mapId mapping in_id =
let rows = String.lines mapping |> List.tail |> Maybe.withDefault []
in
List.foldl findInRow in_id rows
type alias Range = (Int, Int)
type alias Mapping = (Range, Range)
calculateMapping : (Int, Int, Int) -> Mapping
calculateMapping t =
let
(to, from, range) = t
in
((from, from + range - 1), (to, to + range - 1))
findInRow : String -> Maybe Int -> Maybe Int
findInRow row id =
let
numbers = parseNum (Debug.log "row" row)
in
Debug.log "Result in Row: "
(Maybe.andThen (\real_id ->
case numbers of
[to, from, range] ->
if real_id >= from && real_id <= from + range - 1
then Just (real_id - from + to)
else Nothing
_ -> Nothing)
(Debug.log "With -> " id) )
solve2 : str -> Int
solve2 str = 0