1
1
import gleam/int
2
- import gleam/io
3
2
import gleam/list
4
3
import gleam/pair
5
4
import gleam/result
6
5
import gleam/string
7
6
import parse
8
7
9
8
pub fn part1 ( input : String ) -> Int {
9
+ solve ( input , [ Add , Multiply ] )
10
+ }
11
+
12
+ pub fn part2 ( input : String ) -> Int {
13
+ solve ( input , [ Add , Multiply , Concatenate ] )
14
+ }
15
+
16
+ fn solve ( input : String , operations : List ( Op ) ) -> Int {
17
+ let valid = fn ( e : # ( Int , List ( Op ) ) ) { is_valid ( e , operations ) }
18
+
10
19
input
11
20
|> parse_input
12
- |> list . filter ( is_valid )
21
+ |> list . filter ( valid )
13
22
|> list . map ( pair . first )
14
23
|> int . sum
15
24
}
@@ -18,6 +27,7 @@ pub type Op {
18
27
Number ( Int )
19
28
Add
20
29
Multiply
30
+ Concatenate
21
31
}
22
32
23
33
fn evaluate ( ops : List ( Op ) ) -> Int {
@@ -28,60 +38,38 @@ fn forward_evaluate(ops: List(Op)) -> Int {
28
38
case ops {
29
39
[ Number ( a ) , Add , .. rest ] -> a + forward_evaluate ( rest )
30
40
[ Number ( a ) , Multiply , .. rest ] -> a * forward_evaluate ( rest )
41
+ [ Number ( a ) , Concatenate , .. rest ] -> {
42
+ a
43
+ |> int . digits ( 10 )
44
+ |> result . unwrap ( [ ] )
45
+ |> list . fold ( forward_evaluate ( rest ) , fn ( acc , digit ) { acc * 10 + digit } )
46
+ }
31
47
[ Number ( a ) ] -> a
32
48
_ -> panic as { "Invalid expression" }
33
49
}
34
50
}
35
51
36
- fn is_valid ( equation : # ( Int , List ( Op ) ) ) -> Bool {
37
- let _debug_equation = fn ( ops : List ( Op ) ) {
38
- io . println_error ( "" )
39
- io . println_error (
40
- "checking if "
41
- <> int . to_string ( equation . 0 )
42
- <> " == "
43
- <> debug_ops ( ops )
44
- <> case evaluate ( ops ) == equation . 0 {
45
- True -> " (yes!)"
46
- False -> " (no, " <> int . to_string ( evaluate ( ops ) ) <> ")"
47
- } ,
48
- )
49
- ops
50
- }
51
-
52
- possible_ops ( equation . 1 )
53
- // |> list.map(debug_equation)
52
+ fn is_valid ( equation : # ( Int , List ( Op ) ) , operations : List ( Op ) ) -> Bool {
53
+ possible_ops ( equation . 1 , operations )
54
54
|> list . find ( fn ( ops ) { evaluate ( ops ) == equation . 0 } )
55
55
|> result . is_ok
56
56
}
57
57
58
- fn possible_ops ( ops : List ( Op ) ) -> List ( List ( Op ) ) {
58
+ fn possible_ops ( ops : List ( Op ) , operations : List ( Op ) ) -> List ( List ( Op ) ) {
59
59
case ops {
60
60
[ Number ( a ) ] -> [ [ Number ( a ) ] ]
61
61
[ Number ( a ) , .. rest ] -> {
62
- possible_ops ( rest )
62
+ possible_ops ( rest , operations )
63
63
|> list . flat_map ( fn ( restops ) {
64
- [ [ Number ( a ) , Add , .. restops ] , [ Number ( a ) , Multiply , .. restops ] ]
64
+ operations
65
+ |> list . map ( fn ( new_op ) { [ Number ( a ) , new_op , .. restops ] } )
65
66
} )
66
67
}
67
68
[ ] -> [ ]
68
- [ Add , .. ] | [ Multiply , .. ] ->
69
- panic as "possible_ops() requires numeric operands only"
69
+ _ -> panic as "possible_ops() requires numeric operands only"
70
70
}
71
71
}
72
72
73
- fn debug_ops ( ops : List ( Op ) ) -> String {
74
- ops
75
- |> list . map ( fn ( op ) {
76
- case op {
77
- Number ( a ) -> int . to_string ( a )
78
- Add -> "+"
79
- Multiply -> "*"
80
- }
81
- } )
82
- |> string . join ( " " )
83
- }
84
-
85
73
fn parse_input ( input : String ) -> List ( # ( Int , List ( Op ) ) ) {
86
74
input
87
75
|> parse . lines
0 commit comments