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