Add Rust & Python day 5
parent
ee4e8eccfb
commit
4dba9ee6bf
File diff suppressed because it is too large
Load Diff
2
main.py
2
main.py
|
@ -6,3 +6,5 @@ import src.day_03.part_1
|
||||||
import src.day_03.part_2
|
import src.day_03.part_2
|
||||||
import src.day_04.part_1
|
import src.day_04.part_1
|
||||||
import src.day_04.part_2
|
import src.day_04.part_2
|
||||||
|
import src.day_05.part_1
|
||||||
|
import src.day_05.part_2
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod part_1;
|
||||||
|
pub mod part_2;
|
|
@ -0,0 +1,41 @@
|
||||||
|
def main():
|
||||||
|
rules_raw, handbooks_raw = open('inputs/05.txt').read().split("\n\n")
|
||||||
|
|
||||||
|
rules = []
|
||||||
|
for rule in rules_raw.strip().split('\n'):
|
||||||
|
l, r = rule.split('|')
|
||||||
|
rules.append((int(l), int(r)))
|
||||||
|
|
||||||
|
handbooks = []
|
||||||
|
for handbook in handbooks_raw.strip().split('\n'):
|
||||||
|
handbooks.append([ int(h) for h in handbook.split(',') ])
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
for handbook in handbooks:
|
||||||
|
if follows_rules(handbook, rules):
|
||||||
|
total += middle_number(handbook)
|
||||||
|
|
||||||
|
print(f"Day 05 part 1: {total}")
|
||||||
|
|
||||||
|
def follows_rule(handbook, rule):
|
||||||
|
try:
|
||||||
|
first = handbook.index(rule[0])
|
||||||
|
second = handbook.index(rule[1])
|
||||||
|
except ValueError:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return first < second
|
||||||
|
|
||||||
|
def follows_rules(handbook, rules):
|
||||||
|
for rule in rules:
|
||||||
|
if not follows_rule(handbook, rule):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def middle_number(items):
|
||||||
|
return items[len(items) // 2]
|
||||||
|
|
||||||
|
# if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,55 @@
|
||||||
|
use crate::utils;
|
||||||
|
|
||||||
|
type HandBook = Vec<u32>;
|
||||||
|
type RuleSet = Vec<(u32, u32)>;
|
||||||
|
|
||||||
|
pub fn answer(s : &str) -> u32 {
|
||||||
|
let ( rules, handbooks ) = parse_input(s);
|
||||||
|
|
||||||
|
handbooks.iter()
|
||||||
|
.filter(|hb| follows_rules(hb, &rules))
|
||||||
|
.map(middle_value)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn follows_rules(handbook : &HandBook, rules : &RuleSet) -> bool {
|
||||||
|
rules.iter().all(|rule| follows_rule(handbook, rule))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn follows_rule(handbook : &HandBook, (first, second) : &(u32, u32)) -> bool {
|
||||||
|
let mut encountered_second : bool = false;
|
||||||
|
|
||||||
|
for num in handbook.iter() {
|
||||||
|
if num == first {
|
||||||
|
return !encountered_second;
|
||||||
|
} else if num == second {
|
||||||
|
encountered_second = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn middle_value(handbook : &HandBook) -> u32 {
|
||||||
|
handbook[handbook.len() / 2]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_hand_line(s : &str) -> Option<Vec<u32>> {
|
||||||
|
let v : Vec<u32> = s.split(",").filter_map(utils::str_to_u32).collect();
|
||||||
|
|
||||||
|
if v.len() == 0 { None } else { Some(v) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(s : &str) -> (RuleSet, Vec<HandBook>) {
|
||||||
|
let (r, h) = s.split_once("\n\n").unwrap_or(("", ""));
|
||||||
|
|
||||||
|
( r.split("\n").filter_map(parse_rule_line).collect()
|
||||||
|
, h.split("\n").filter_map(parse_hand_line).collect()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_rule_line(s : &str) -> Option<(u32, u32)> {
|
||||||
|
let (l, r) = s.split_once("|")?;
|
||||||
|
|
||||||
|
Some(( utils::str_to_u32(l)?, utils::str_to_u32(r)? ))
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
def main():
|
||||||
|
rules_raw, handbooks_raw = open('inputs/05.txt').read().split("\n\n")
|
||||||
|
|
||||||
|
rules = []
|
||||||
|
for rule in rules_raw.strip().split('\n'):
|
||||||
|
l, r = rule.split('|')
|
||||||
|
rules.append((int(l), int(r)))
|
||||||
|
|
||||||
|
handbooks = []
|
||||||
|
for handbook in handbooks_raw.strip().split('\n'):
|
||||||
|
handbooks.append([ int(h) for h in handbook.split(',') ])
|
||||||
|
|
||||||
|
total = 0
|
||||||
|
|
||||||
|
for handbook in handbooks:
|
||||||
|
if not follows_rules(handbook, rules):
|
||||||
|
reorder(handbook, rules)
|
||||||
|
total += middle_number(handbook)
|
||||||
|
|
||||||
|
print(f"Day 05 part 2: {total}")
|
||||||
|
|
||||||
|
def follows_rule(handbook, rule):
|
||||||
|
try:
|
||||||
|
first = handbook.index(rule[0])
|
||||||
|
second = handbook.index(rule[1])
|
||||||
|
except ValueError:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return first < second
|
||||||
|
|
||||||
|
def follows_rules(handbook, rules):
|
||||||
|
for rule in rules:
|
||||||
|
if not follows_rule(handbook, rule):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def middle_number(items):
|
||||||
|
return items[len(items) // 2]
|
||||||
|
|
||||||
|
def reorder(handbook, rules):
|
||||||
|
# Use bubble sort method
|
||||||
|
all_match = False
|
||||||
|
|
||||||
|
while not all_match:
|
||||||
|
all_match = True
|
||||||
|
|
||||||
|
for rule in rules:
|
||||||
|
try:
|
||||||
|
i1 = handbook.index(rule[0])
|
||||||
|
i2 = handbook.index(rule[1])
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# If the order is wrong, swap the two
|
||||||
|
if i1 > i2:
|
||||||
|
handbook[i1], handbook[i2] = handbook[i2], handbook[i1]
|
||||||
|
all_match = False
|
||||||
|
|
||||||
|
# if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,72 @@
|
||||||
|
use crate::utils;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
type HandBook = Vec<u32>;
|
||||||
|
type RuleSet = Vec<(u32, u32)>;
|
||||||
|
|
||||||
|
pub fn answer(s : &str) -> u32 {
|
||||||
|
let ( rules, mut handbooks ) = parse_input(s);
|
||||||
|
|
||||||
|
handbooks.iter_mut()
|
||||||
|
.filter(|hb| !follows_rules(hb, &rules))
|
||||||
|
.map(|hb| { reorder_pages(hb, &rules); middle_value(hb) })
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn page_cmp(a : &u32, b : &u32, rules : &RuleSet) -> Ordering {
|
||||||
|
for (r1, r2) in rules.iter() {
|
||||||
|
if r1 == a && r2 == b {
|
||||||
|
return Ordering::Less;
|
||||||
|
} else if r1 == b && r2 == a {
|
||||||
|
return Ordering::Greater;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ordering::Equal
|
||||||
|
}
|
||||||
|
|
||||||
|
fn follows_rules(handbook : &HandBook, rules : &RuleSet) -> bool {
|
||||||
|
rules.iter().all(|rule| follows_rule(handbook, rule))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn follows_rule(handbook : &HandBook, (first, second) : &(u32, u32)) -> bool {
|
||||||
|
let mut encountered_second : bool = false;
|
||||||
|
|
||||||
|
for num in handbook.iter() {
|
||||||
|
if num == first {
|
||||||
|
return !encountered_second;
|
||||||
|
} else if num == second {
|
||||||
|
encountered_second = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn middle_value(handbook : &HandBook) -> u32 {
|
||||||
|
handbook[handbook.len() / 2]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_hand_line(s : &str) -> Option<Vec<u32>> {
|
||||||
|
let v : Vec<u32> = s.split(",").filter_map(utils::str_to_u32).collect();
|
||||||
|
|
||||||
|
if v.len() == 0 { None } else { Some(v) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(s : &str) -> (RuleSet, Vec<HandBook>) {
|
||||||
|
let (r, h) = s.split_once("\n\n").unwrap_or(("", ""));
|
||||||
|
|
||||||
|
( r.split("\n").filter_map(parse_rule_line).collect()
|
||||||
|
, h.split("\n").filter_map(parse_hand_line).collect()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_rule_line(s : &str) -> Option<(u32, u32)> {
|
||||||
|
let (l, r) = s.split_once("|")?;
|
||||||
|
|
||||||
|
Some(( utils::str_to_u32(l)?, utils::str_to_u32(r)? ))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reorder_pages(handbook : &mut HandBook, rules : &RuleSet) {
|
||||||
|
handbook.sort_unstable_by(|a, b| page_cmp(a, b, rules));
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ mod day_01;
|
||||||
mod day_02;
|
mod day_02;
|
||||||
mod day_03;
|
mod day_03;
|
||||||
mod day_04;
|
mod day_04;
|
||||||
|
mod day_05;
|
||||||
|
|
||||||
pub fn day_01() {
|
pub fn day_01() {
|
||||||
let s : String = utils::read_from_file("inputs/01.txt");
|
let s : String = utils::read_from_file("inputs/01.txt");
|
||||||
|
@ -27,3 +28,9 @@ pub fn day_04() {
|
||||||
println!("Day 04 part 1: {}", day_04::part_1::answer(s.as_str()));
|
println!("Day 04 part 1: {}", day_04::part_1::answer(s.as_str()));
|
||||||
println!("Day 04 part 2: {}", day_04::part_2::answer(s.as_str()));
|
println!("Day 04 part 2: {}", day_04::part_2::answer(s.as_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn day_05() {
|
||||||
|
let s : String = utils::read_from_file("inputs/05.txt");
|
||||||
|
println!("Day 05 part 1: {}", day_05::part_1::answer(s.as_str()));
|
||||||
|
println!("Day 05 part 2: {}", day_05::part_2::answer(s.as_str()));
|
||||||
|
}
|
||||||
|
|
|
@ -3,4 +3,5 @@ fn main() {
|
||||||
aoc_2024::day_02();
|
aoc_2024::day_02();
|
||||||
aoc_2024::day_03();
|
aoc_2024::day_03();
|
||||||
aoc_2024::day_04();
|
aoc_2024::day_04();
|
||||||
|
aoc_2024::day_05();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue