aboutsummaryrefslogtreecommitdiff
path: root/2022/src/utils.rs
blob: 8230c69b4f88d0f1a4a67ebc631d8ae968df7641 (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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#![allow(unused)]
use std::{fs::File, io::Read, str::FromStr};

pub fn read_input() -> String {
    let mut args = std::env::args();

    let mut file = File::open(
        args.nth(1)
            .expect("first argument should be input filename"),
    )
    .expect("could not open input");
    let mut out = String::new();
    file.read_to_string(&mut out)
        .expect("could not read input file");

    out
}

pub fn max_n<T: Ord>(vec: &mut Vec<T>, n: usize) -> &[T] {
    top_n_by(vec, |a, b| a > b, n)
}

pub fn top_n_by<T, F: FnMut(&T, &T) -> bool>(vec: &mut Vec<T>, mut f: F, n: usize) -> &[T] {
    for _ in 0..n {
        for i in 0..vec.len() - 1 {
            if f(&vec[i], &vec[i + 1]) {
                vec.swap(i, i + 1);
            }
        }
    }

    &vec[vec.len() - n..]
}

pub fn iter_pair<T>(mut i: impl Iterator<Item = T>) -> (T, T) {
    (i.next().unwrap(), i.next().unwrap())
}

pub fn iter_triple<T>(mut i: impl Iterator<Item = T>) -> (T, T, T) {
    (i.next().unwrap(), i.next().unwrap(), i.next().unwrap())
}

#[inline(always)]
pub fn parse_num<T: FromStr>(string: &str) -> (T, &str)
where
    <T as FromStr>::Err: std::fmt::Debug,
{
    let count = string
        .chars()
        .take_while(|x| x.is_numeric() || *x == '-')
        .count();

    (string[..count].parse().unwrap(), &string[count..])
}

#[inline(always)]
pub fn parse_static<'a>(exp: &'static str, source: &'a str) -> &'a str {
    &source[exp.len()..]
}