aboutsummaryrefslogtreecommitdiff
path: root/2024/01/solve.effekt
blob: 64999423d1bdfb4e87e68872bb47ba0a8f69fa4e (plain) (blame)
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
import io/error
import exception
import char
import stream

def collectNumber(): Unit / { read[Char], emit[Char], stop } = {
  val c = do read[Char]()
  if (not(c.isDigit)) do stop()
  do emit(c)
  collectNumber()
}

def parse(): Unit / { read[Char], emit[Tuple2[Int, Int]], stop } = {
  with on[WrongFormat].default { do stop() }

  val a: Int = collectString {
    with exhaustively
    collectNumber()
  }.toInt

  do read[Char]()
  do read[Char]()

  val b: Int = collectString {
    with exhaustively
    collectNumber()
  }.toInt

  do emit((a, b))
}

def transpose[R] { stream : () => R / emit[Tuple2[Int, Int]] }: (R, Tuple2[List[Int], List[Int]]) = {
  var a = Nil()
  var b = Nil()
  try {
    (stream(), (a, b))
  } with emit[Tuple2[Int, Int]] { v =>
    a = Cons(v.first, a)
    b = Cons(v.second, b)
    resume(())
  }
}

def part1(a: List[Int], b: List[Int]) =
  zipWith(a, b) { (a, b) => abs(a - b) }.sum

def count(lst: List[Int], el: Int) =
  collect(lst) { x => if (x == el) Some(()) else None() }.size

def part2(a: List[Int], b: List[Int]) = {
  var res = 0
  a.foreachIndex { (index, value) =>
    res = res + value * b.count(value)
  }
  res
}

def main() = {
  with on[IOError].panic
  with readFile("input")
  with decodeUTF8

  val input: Tuple2[List[Int], List[Int]] = transpose {
    with exhaustively
    parse()
  }.second

  println(part1(input.first.sort, input.second.sort))
  println(part2(input.first, input.second))
}