Untitled

 avatar
unknown
plain_text
15 days ago
2.0 kB
7
Indexable
import gleam/list
import gleam/option.{type Option, None, Some}

import tops

pub type Place =
  Option(Int)

pub type Artist =
  String

pub type Title =
  String

pub type Entry =
  #(Artist, Title)

pub fn main() {
  let result = trends([tops.top2024])
  echo result
}

// Finding an entry //

pub fn find(entry: Entry, entries: List(Entry)) -> Place {
  find_helper(entry, entries, 1)
}

fn find_helper(entry: Entry, entries: List(Entry), position: Int) -> Option(Int) {
  case entries {
    [] -> None
    [x, ..xs] ->
      case entry == x {
        True -> Some(position)
        False -> find_helper(entry, xs, position + 1)
      }
  }
}

// HERSCHRIJF:
//    find(#("Hotel California", "Eagles"), top2020)
// => ...
//    ...

// Deterimining the status //

pub type Status {
  In(Int)
  Moved(Int)
  Steady
  Out
}

pub fn status(old: Option(Int), new: Option(Int)) -> Status {
  case old, new {
    // Not in old, but in new → In(p)
    None, Some(p) -> In(p)

    // In both → compare positions
    Some(o), Some(n) ->
      case o - n {
        0 -> Steady
        d -> Moved(d)
      }

    // In old, not in new → Out
    Some(_), None -> Out

    // Not in either → Steady
    None, None -> Steady
  }
}

// HERSCHRIJF:
//    status(Some(78), Some(79))
// => ...
//    ...

// Determining the trend //

pub fn trend(entry: Entry, years: List(List(Entry))) -> List(Status) {
  case years {
    [] -> []
    [_] -> []
    [a, b, ..rest] -> {
      let old_pos = find_helper(entry, a, 1)
      let new_pos = find_helper(entry, b, 1)
      let current_status = status(old_pos, new_pos)
      list.append([current_status], trend(entry, [b, ..rest]))
    }
  }
}

// Finding all trends //

pub fn trends(years: List(List(Entry))) -> List(#(Entry, List(Status))) {
  let all_entries = list.flatten(years)
  let unique_entries = list.unique(all_entries)
  list.map(unique_entries, fn(entry) { #(entry, trend(entry, years)) })
}
Editor is loading...
Leave a Comment