day_2

Part 1 is more or less straightforward. The interesting thing is the pairwise comparison with a given comparator, making ascending(l) and descending(l) possible without too much code duplication.

The more elegant approach could’ve been to infer whether the list is ascending or descending by comparing the first and second elements, and then using that to determine the comparator. This way, we’re checking the list twice, but hey, what’s a factor of two between friends? Part 2 is a bit more tricky. The techniques are mostly the same as the one used in part 1, save for allowing one constraint violation per row. For that, this solution uses brute force to generate all possible distinct sublists of same ordering and length n-1, checks all of them for monotonicity and safe distances and then passes if any of them pass. The more efficient way to solve this would be to keep count of the number of unsafe distances/monotonicity violations in the list during the entire comparison, and allow one. That would still allow for pairwise comparisons and thus be O(n).

Functions

pub fn ascending(l: List(Int)) -> Bool

Returns true if all successive pairs of elements in list are ascending

pub fn compare_pairwise(
  l: List(Int),
  comparator: fn(Int, Int) -> Bool,
) -> Bool

Returns true if all successive pairs of elements in list satisfy the comparator and are within a safe distance

pub fn descending(l: List(Int)) -> Bool

Returns true if all successive pairs of elements in list are descending

pub fn get_sublists(l: List(Int)) -> List(List(Int))

Given a list of integers of length n, return n distinct, same-ordered sublists of length n-1

pub fn main() -> Nil
pub fn monotonic(l: List(Int)) -> Bool

Returns true if list is either ascending or descending

pub fn part_1() -> String
pub fn part_2() -> String
pub fn safe_dist(a: Int, b: Int) -> Bool

Returns true if difference between parameters is within safe range (1 - 3)

Search Document