OrangeBacon's recent activity
-
Comment on Day 20: Jurassic Jigsaw in ~comp
-
Comment on Day 19: Monster Messages in ~comp
OrangeBacon Today's one, used regexes for both parts, compiled the input into a tree and then executed it, had to move from rust regex to pcre2 for pt 2. I kinda enjoyed this, was interesting to learn about...Today's one, used regexes for both parts, compiled the input into a tree and then executed it, had to move from rust regex to pcre2 for pt 2. I kinda enjoyed this, was interesting to learn about new regex features.
Runs in around 10ms for parsing and both parts
Repo link: https://github.com/OrangeBacon/adventofcode2020/blob/main/src/days/day19.rsRust code
use anyhow::Result; use hashbrown::HashMap; use libaoc::{aoc, AocResult, Timer}; use pcre2::bytes::Regex as RegexPcre2; use regex::Regex; use std::fmt::{self, Write}; #[derive(Clone, Copy, Debug)] enum RuleType { One(usize), Two(usize, usize), OneOne(usize, usize), TwoTwo(usize, usize, usize, usize), Letter(char), Rule8(usize), Rule11(usize, usize), } impl RuleType { fn to_regex( self, out: &mut String, rules: &HashMap<usize, RuleType>, ) -> Result<(), fmt::Error> { use RuleType::*; match self { Letter(a) => write!(out, "{}", a), One(a) => rules[&a].to_regex(out, rules), Two(a, b) => { rules[&a].to_regex(out, rules)?; rules[&b].to_regex(out, rules) } OneOne(a, b) => { write!(out, "(?:(")?; rules[&a].to_regex(out, rules)?; write!(out, ")|(?:")?; rules[&b].to_regex(out, rules)?; write!(out, "))") } TwoTwo(a, b, c, d) => { write!(out, "(?:(?:")?; rules[&a].to_regex(out, rules)?; rules[&b].to_regex(out, rules)?; write!(out, ")|(?:")?; rules[&c].to_regex(out, rules)?; rules[&d].to_regex(out, rules)?; write!(out, "))") } Rule8(a) => { write!(out, "(?:")?; rules[&a].to_regex(out, rules)?; write!(out, ")+") } Rule11(a, b) => { write!(out, "(?<rule11>(?:")?; rules[&a].to_regex(out, rules)?; rules[&b].to_regex(out, rules)?; write!(out, ")|(?:")?; rules[&a].to_regex(out, rules)?; write!(out, "(?&rule11)")?; rules[&b].to_regex(out, rules)?; write!(out, "))") } } } fn from_str(x: &str) -> (usize, Self) { use RuleType::*; let parts = x.split_once(':').unwrap(); let left = parts.0.parse().unwrap(); let right = parts.1.split('|'); let right: Vec<Vec<(&str, Result<usize, _>)>> = right .map(|x| x.trim().split(' ').map(|x| (x, x.parse())).collect()) .collect(); let kind = match right.len() { 1 => match right[0].len() { 2 => Two( *(right[0][0].1.as_ref().unwrap()), *(right[0][1].1.as_ref().unwrap()), ), 1 => { if let Ok(num) = right[0][0].1 { One(num) } else { Letter(right[0][0].0.chars().nth(1).unwrap()) } } _ => panic!(), }, 2 => match right[0].len() { 1 => OneOne( *(right[0][0].1.as_ref().unwrap()), *(right[1][0].1.as_ref().unwrap()), ), 2 => TwoTwo( *(right[0][0].1.as_ref().unwrap()), *(right[0][1].1.as_ref().unwrap()), *(right[1][0].1.as_ref().unwrap()), *(right[1][1].1.as_ref().unwrap()), ), _ => panic!(), }, _ => panic!(), }; (left, kind) } } #[aoc("250", "359")] pub fn solve(timer: &mut Timer, input: &str) -> Result<AocResult> { let line = Regex::new(r"(\r?\n){2}")?; let input: Vec<_> = line.split(input).collect(); let mut rules: HashMap<usize, RuleType> = input[0].lines().map(RuleType::from_str).collect(); timer.lap("Parse"); let mut reg = String::new(); write!(reg, "^(?:")?; rules[&0].to_regex(&mut reg, &rules)?; write!(reg, ")$")?; let reg = Regex::new(®)?; let part1 = input[1].lines().fold( 0, |acc, line| { if reg.is_match(line) { acc + 1 } else { acc } }, ); timer.lap("Part 1"); rules.insert(8, RuleType::Rule8(42)); rules.insert(11, RuleType::Rule11(42, 31)); let mut reg = String::new(); write!(reg, "^(?:")?; rules[&0].to_regex(&mut reg, &rules)?; write!(reg, ")$")?; let reg = RegexPcre2::new(®)?; let part2 = input[1].lines().fold(0, |acc, line| { if reg.is_match(&line.bytes().collect::<Vec<u8>>()).unwrap() { acc + 1 } else { acc } }); timer.lap("Part 2"); Ok(AocResult::new(part1, part2)) }
-
Comment on Day 7: Handy Haversacks in ~comp
OrangeBacon Rust This one seemed much harder than the previous days. I spent a while fighting the borrow checker/learning how to use rc + refcell to get the compiler to be happy. Repo link Solution to both...Rust
This one seemed much harder than the previous days. I spent a while fighting the borrow checker/learning how to use rc + refcell to get the compiler to be happy.
Solution to both parts
use regex::Regex; use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; #[derive(Debug, Clone)] struct Bag { name: String, contains: Vec<(u32, Rc<RefCell<Bag>>)>, } pub fn day07(input: String) { let mut bags: HashMap<String, Rc<RefCell<Bag>>> = HashMap::new(); let input: Vec<Vec<_>> = input .lines() .map(|x| x.split("contain").collect()) .collect(); let remove_bag_suffix = Regex::new(r" (bag|bags)\.*$").unwrap(); for line in input { let name = remove_bag_suffix.replace(line[0].trim(), ""); let contains: Vec<_> = line[1] .split(",") .map(|x| remove_bag_suffix.replace(x.trim(), "")) .collect(); let contains = contains .iter() .map(|x| x.splitn(2, " ").collect::<Vec<_>>()) .map(|x| { if x[0] == "no" { None } else { Some((x[0].parse::<u32>().unwrap(), x[1])) } }) .filter(|&x| x != None) .map(|x| x.unwrap()) .map(|(num, x)| { let bag = if bags.contains_key(&String::from(x)) { bags.get(&String::from(x)).unwrap().clone() } else { bags.insert( String::from(x), Rc::new(RefCell::new(Bag { name: String::from(x), contains: vec![], })), ); bags.get(&String::from(x)).unwrap().clone() }; (num, bag) }) .collect::<Vec<_>>(); let bag = if bags.contains_key(&String::from(name.clone())) { bags.get(&String::from(name)).unwrap().clone() } else { bags.insert( String::from(name.clone()), Rc::new(RefCell::new(Bag { name: String::from(name.clone()), contains: vec![], })), ); bags.get(&String::from(name)).unwrap().clone() }; bag.borrow_mut().contains = contains; } fn find_recurse(bag: Rc<RefCell<Bag>>) -> bool { bag.borrow().contains.iter().fold(false, |acc, val| { acc | (val.1.borrow().name == "shiny gold") | (find_recurse(Rc::new(RefCell::new(val.1.borrow().clone())))) }) } let res = bags.iter().fold(0, |acc, (_, bag)| { if find_recurse(bag.clone()) { acc + 1 } else { acc } }); println!("{}", res); fn count_recurse(bag: Rc<RefCell<Bag>>) -> u32 { bag.borrow().contains.iter().fold(1, |acc, val| { acc + val.0 * count_recurse(Rc::new(RefCell::new(val.1.borrow().clone()))) }) } let res = Rc::new(RefCell::new( bags.get("shiny gold").unwrap().borrow().clone(), )); println!("{}", count_recurse(res) - 1); }
-
Comment on Day 5: Binary Boarding in ~comp
OrangeBacon My solution in rust: Was fun to do, was expecting something much harder given that it is Saturday. Link to the repository, including test runner main.rs use std::cmp::{max}; pub fn day05(input:...My solution in rust:
Was fun to do, was expecting something much harder given that it is Saturday.Link to the repository, including test runner
main.rs
use std::cmp::{max}; pub fn day05(input: String) { let lines : Vec<_> = input.lines().collect(); let mut highest = 0; let mut seats = [[(false, 0); 8]; 128]; for line in lines { let mut row = 0; let mut col = 0; let mut row_size = 128; let mut col_size = 8; for c in line.chars() { match c { 'F' => row_size /= 2, 'B' => { // upper row += row_size; row_size /= 2; } 'R' => { // upper col += col_size; col_size /= 2; } 'L' => col_size /= 2, _ => panic!() } } seats[row/2][col/2] = (true, row/2 * 8 + col/2); highest = max(highest, row/2 * 8 + col/2); } let mut found = false; let mut id = 0; 'out: for (y, row) in seats.iter().enumerate() { if !found { for seat in row.iter() { if (*seat).0 { found = true; } } } else { for (x, seat) in row.iter().enumerate() { if !(*seat).0 { id = y * 8 + x; break 'out; } } } } println!("{}", highest); println!("{}", id); }
-
Comment on Day 6: Universal Orbit Map in ~comp
OrangeBacon Been doing it in rust this year, all solutions so far on my github. I feel like my code is really quite messy and probably could have benefited from a proper graph library, rather than a hashmap...Been doing it in rust this year, all solutions so far on my github.
I feel like my code is really quite messy and probably could have benefited from a proper graph library, rather than a hashmap of
node => value
and having the edges asvec[(start, end)]
.Part 1
use std::error::Error; use std::fs::File; use std::io::prelude::*; use std::path::Path; use indexmap::IndexMap; pub fn day6a() { let path = Path::new("data/day6.txt"); let display = path.display(); let mut file = match File::open(&path) { Err(why) => panic!("Couldn't open {}: {}", display, why.description()), Ok(file) => file, }; let mut s = String::new(); match file.read_to_string(&mut s) { Err(why) => panic!("Couldn't read {}: {}", display, why.description()), Ok(_) => {} } let mut nodes: IndexMap<&str, usize> = IndexMap::new(); let mut edges: Vec<(usize, usize)> = vec![]; for line in s.lines() { let parts: Vec<&str> = line.split(")").collect(); if !nodes.contains_key(parts[0]) { nodes.insert(parts[0], 0); } let index1 = nodes.get_full(parts[0]).unwrap().0; if !nodes.contains_key(parts[1]) { nodes.insert(parts[1], 0); } let index2 = nodes.get_full(parts[1]).unwrap().0; edges.push((index1, index2)); } let root = nodes.get_full("COM").unwrap().0; let mut to_scan = vec![root]; while to_scan.len() > 0 { let node_index = to_scan.pop().unwrap(); let node_value = *nodes.get_index(node_index).unwrap().1; for edge in &edges { if edge.0 == node_index { to_scan.push(edge.1); let x = nodes.get_index_mut(edge.1).unwrap().1; *x = node_value + 1; } } } let mut count = 0; for node in &nodes { count += node.1 } println!("{}", count); }
Part 2
use std::error::Error; use std::fs::File; use std::io::prelude::*; use std::path::Path; use indexmap::IndexMap; use std::collections::HashSet; pub fn day6b() { let path = Path::new("data/day6.txt"); let display = path.display(); let mut file = match File::open(&path) { Err(why) => panic!("Couldn't open {}: {}", display, why.description()), Ok(file) => file, }; let mut s = String::new(); match file.read_to_string(&mut s) { Err(why) => panic!("Couldn't read {}: {}", display, why.description()), Ok(_) => {} } let mut nodes: IndexMap<&str, usize> = IndexMap::new(); let mut edges: Vec<(usize, usize)> = vec![]; for line in s.lines() { let parts: Vec<&str> = line.split(")").collect(); if !nodes.contains_key(parts[0]) { nodes.insert(parts[0], 0); } let index1 = nodes.get_full(parts[0]).unwrap().0; if !nodes.contains_key(parts[1]) { nodes.insert(parts[1], 0); } let index2 = nodes.get_full(parts[1]).unwrap().0; edges.push((index1, index2)); } let get_path = |start: usize, end: usize| { let mut current = start; let mut ret: HashSet<usize> = HashSet::new(); ret.insert(current); while current != end { for edge in &edges { if edge.1 == current { current = edge.0; break; } } ret.insert(current); } ret }; let you_path = get_path(nodes.get_full("YOU").unwrap().0, nodes.get_full("COM").unwrap().0); let san_path = get_path(nodes.get_full("SAN").unwrap().0, nodes.get_full("COM").unwrap().0); println!("{}", you_path.symmetric_difference(&san_path).count() - 2); }
-
Comment on Daily Tildes discussion - minor group updates in ~tildes.official
OrangeBacon I think that there isn't really a need for new groups, a lot of topics have places and there is always ~misc for other things. I think it would be good not to create any more new groups for a now,...I think that there isn't really a need for new groups, a lot of topics have places and there is always ~misc for other things. I think it would be good not to create any more new groups for a now, to allow more people to join so the are enough people to keep all the groups active.
-
Comment on What's on everyone's mind today? in ~talk
OrangeBacon AQA for me, I don't know how it compares with OCR, though I imagine they are roughly similarAQA for me, I don't know how it compares with OCR, though I imagine they are roughly similar
-
Comment on Covers that you love much more than the originals in ~music
OrangeBacon Disturbed's cover of the sound of silence by Simon and Garfunkel is mine, I prefer the lower octave, it makes it easier to sing along to!Disturbed's cover of the sound of silence by Simon and Garfunkel is mine, I prefer the lower octave, it makes it easier to sing along to!
-
Comment on What's on everyone's mind today? in ~talk
OrangeBacon I have a physics exam for my A-levels tomorrow and I am really nervous for it, I hadn't studied any of the content for a year until last week and I am finding it hard to remember it all.I have a physics exam for my A-levels tomorrow and I am really nervous for it, I hadn't studied any of the content for a year until last week and I am finding it hard to remember it all.
-
Comment on <deleted topic> in ~tv
OrangeBacon I really like ethoslab, he mainly posts minecraft videos and is very good at redstone / I like how his chanel is more technical rather than design basedI really like ethoslab, he mainly posts minecraft videos and is very good at redstone / I like how his chanel is more technical rather than design based
-
Comment on A minor suggestion regarding voting and karma in ~tildes
OrangeBacon I agree that I am glad that ~ does not use reddit's karma system and think that post made is an alright metric, however it could lead to lots of low quality short posts for a different sort of...I agree that I am glad that ~ does not use reddit's karma system and think that post made is an alright metric, however it could lead to lots of low quality short posts for a different sort of meaningless Internet points.
I think it might be better if no number is actually visible. Instead, possibly a number acessible to the server, not any user, which should help to discourage low effirt/quality posts. I am not sure what should be used for this, @Deimos has already written about a reputation system so this might be what is needed?
-
Comment on What hobby do you wish you could do but can't? in ~hobbies
OrangeBacon Something I have been wanting to get in to is electronics, making circuits, etc. I would love to eventually make a custom computer from logic gates. I imagine it would be very satisfying to see a...Something I have been wanting to get in to is electronics, making circuits, etc. I would love to eventually make a custom computer from logic gates. I imagine it would be very satisfying to see a pile of chips I made and designed run a program!
-
Comment on Where are you from? in ~talk
OrangeBacon UK for me, near London, only a 20min train journey! I live in a small ish town though (~36,000), there are lots of fields nearby!UK for me, near London, only a 20min train journey!
I live in a small ish town though (~36,000), there are lots of fields nearby! -
Comment on Repost check in ~tildes
OrangeBacon I totally agree, I think that that time for the repost check to come off should help to ensure that the content is not on here all the time, however new users still get to see it as they might not...I totally agree, I think that that time for the repost check to come off should help to ensure that the content is not on here all the time, however new users still get to see it as they might not recognise it as a repost.
-
Comment on Write a ~ story! in ~creative
OrangeBacon Well, it all started when I was walking down the high street to get a new pen, then I saw her in a shop.Well, it all started when I was walking down the high street to get a new pen, then I saw her in a shop.
I finally finished both parts of today's!!! woo! part 2 took a very long time lol, at least the program runs quickly.
This was such a hard problem imo.
Repo link: https://github.com/OrangeBacon/adventofcode2020/blob/main/src/days/day20.rs
Notes:
For part 1 only the edges of each tile needs to be considered, as each edge is included either once or twice, it is possible to get a single way of organising the tiles. To make the edge comparison nicer, the `#` can be replaced with `1` and `.` with `0` and then each edge can be converted to a binary number. To make the rotations easier, I read those numbers clockwise round the edge of each tile, rather than left to right. For this part, the image doesn't need to be constructed as the corners will be the tiles with two edges that are included twice. For part 2, the orientation of the image doesn't matter, so it can be started from any corner. The input is small enough that all rotations of each tile can be checked to find the correct rotation, rather than trying to find a clever way of working out the tile rotations. For finding the monster, I search through the complete image for one monster, if it is not found, i rotate the whole image, repeat for all 4 orientations, flip and repeat again, to find the one orientation and flip when one monster is found. I then search through the input for all monsters, keeping a set of all coordinates included in monsters and subtract the size of that set from the total number of `#` in the input.Rust part 1 + 2 (336 lines)