summaryrefslogtreecommitdiffstats
path: root/day03a/src/main.rs
blob: eafb25fe2e06b97367689c3b67d329b929a9ca9e (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/// --- Day 3: Rucksack Reorganization ---
///
/// One Elf has the important job of loading all of the rucksacks with supplies for the jungle
/// journey.  Unfortunately, that Elf didn't quite follow the packing instructions, and so a few
/// items now need to be rearranged.
///
/// Each rucksack has two large compartments.  All items of a given type are meant to go into
/// exactly one of the two compartments.  The Elf that did the packing failed to follow this rule
/// for exactly one item type per rucksack.
///
/// The Elves have made a list of all of the items currently in each rucksack (your puzzle input),
/// but they need your help finding the errors.  Every item type is identified by a single lowercase
/// or uppercase letter (that is, a and A refer to different types of items).
///
/// The list of items for each rucksack is given as characters all on a single line.  A given
/// rucksack always has the same number of items in each of its two compartments, so the first half
/// of the characters represent items in the first compartment, while the second half of the
/// characters represent items in the second compartment.
///
/// For example, suppose you have the following list of contents from six rucksacks:
///
/// ```
/// vJrwpWtwJgWrhcsFMMfFFhFp
/// jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
/// PmmdzqPrVvPwwTWBwg
/// wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
/// ttgJtRGJQctTZtZT
/// CrZsJsPPZsGzwwsLwLmpwMDw
/// ```
///
///     The first rucksack contains the items vJrwpWtwJgWrhcsFMMfFFhFp, which means its first
///     compartment contains the items vJrwpWtwJgWr, while the second compartment contains the
///     items hcsFMMfFFhFp.  The only item type that appears in both compartments is lowercase p.
///     The second rucksack's compartments contain jqHRNqRjqzjGDLGL and rsFMfFZSrLrFZsSL.  The only
///     item type that appears in both compartments is uppercase L.
///     The third rucksack's compartments contain PmmdzqPrV and vPwwTWBwg; the only common item
///     type is uppercase P.
///     The fourth rucksack's compartments only share item type v.
///     The fifth rucksack's compartments only share item type t.
///     The sixth rucksack's compartments only share item type s.
///
/// To help prioritize item rearrangement, every item type can be converted to a priority:
///
///     Lowercase item types a through z have priorities 1 through 26.
///     Uppercase item types A through Z have priorities 27 through 52.
///
/// In the above example, the priority of the item type that appears in both compartments of each
/// rucksack is 16 (p), 38 (L), 42 (P), 22 (v), 20 (t), and 19 (s); the sum of these is 157.
///
/// Find the item type that appears in both compartments of each rucksack. What is the sum of the
/// priorities of those item types?
use clap::Parser;

use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::PathBuf;

const FILEPATH: &'static str = "examples/input.txt";

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Cli {
    #[clap(short, long, default_value = FILEPATH)]
    file: PathBuf,
}

fn main() {
    let args = Cli::parse();

    let file = File::open(&args.file).unwrap();
    let reader = BufReader::new(file);
    let res = reader
        .lines()
        .map(|l| l.unwrap())
        .inspect(|l| {
            if l.len() % 2 != 0 {
                panic!("odd number of items in rucksack")
            }
        })
        .map(|l| {
            let (l, r) = l.split_at(l.len() / 2);
            (l.to_owned(), r.to_owned())
        })
        .map(|(lhs, rhs)| {
            lhs.chars()
                .filter(|l| rhs.contains(*l))
                .map(|l| {
                    let b = l as u8;
                    if b > b'a' {
                        (b - b'a') as u16 + 1
                    } else {
                        (b - b'A') as u16 + 27
                    }
                })
                .next()
                .unwrap()
        })
        .sum::<u16>();

    println!(
        "The sum of the priorities of the item that appear in both compartments of each rucksack is {}",
        res
    );
}