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_04.part_1
|
||||
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_03;
|
||||
mod day_04;
|
||||
mod day_05;
|
||||
|
||||
pub fn day_01() {
|
||||
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 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_03();
|
||||
aoc_2024::day_04();
|
||||
aoc_2024::day_05();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue