aboutsummaryrefslogtreecommitdiff
path: root/aoc-2020-gleam/src/ext/iteratorx.gleam
blob: 6c7838d5bed8b2562086bf4e722cc4de2a886e40 (plain)
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
import gleam/int
import gleam/result as res
import gleam/dict.{type Dict}
import gleam/iterator.{type Iterator, Next} as iter

pub fn length(iterator: Iterator(a)) -> Int {
  iterator
  |> iter.fold(from: 0, with: fn(c, _) { c + 1 })
}

pub fn count(iterator: Iterator(a), satisfying predicate: fn(a) -> Bool) -> Int {
  iterator
  |> iter.filter(keeping: predicate)
  |> length
}

pub fn counts(iterator: Iterator(a)) -> Dict(a, Int) {
  iterator
  |> iter.fold(from: dict.new(), with: fn(acc, value) {
    acc
    |> dict.insert(
      value,
      dict.get(acc, value)
      |> res.unwrap(or: 0)
      |> int.add(1),
    )
  })
}

pub fn filter_map(
  iterator: Iterator(a),
  with mapper: fn(a) -> Result(b, c),
) -> Iterator(b) {
  iterator
  |> iter.flat_map(with: fn(elem) {
    case mapper(elem) {
      Ok(new) -> iter.single(new)
      Error(_) -> iter.empty()
    }
  })
}

pub fn unfold_infinitely(from state: a, with fun: fn(a) -> a) -> Iterator(a) {
  iter.unfold(from: state, with: fn(s) { Next(element: s, accumulator: fun(s)) })
}