Quest 13: Unlocking the Mountain
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
Link to participate: https://everybody.codes/
You must log in or register to comment.
Rust
pub fn solve_part_1(input: &str) -> String { let numbers = input .lines() .map(|l| l.parse().unwrap()) .collect::<Vec<i64>>(); let offset = 2025 % (numbers.len() + 1); if offset == 0 { 1 } else if offset > numbers.len().div_ceil(2) { numbers[(numbers.len() - offset) * 2 + 1] } else { numbers[(offset - 1) * 2] } .to_string() } fn find_number(ranges: &[(i64, i64)], mut offset: i64, counterclockwise: bool) -> i64 { for (from, to) in ranges { let segment_size = (to - from) + 1; if offset >= segment_size { offset -= segment_size; continue; } return if counterclockwise { to - offset } else { from + offset }; } panic!("find_number gave up and died"); } fn solve_part_2_with_turns(input: &str, turns: i64) -> String { let ranges = input .lines() .map(|l| { let (l, r) = l.split_once("-").unwrap(); (l.parse().unwrap(), r.parse().unwrap()) }) .collect::<Vec<(i64, i64)>>(); let mut clockwise_length = 0; let mut clockwise_ranges = vec![]; let mut counterclockwise_length = 0; let mut counterclockwise_ranges = vec![]; for (i, (from, to)) in ranges.into_iter().enumerate() { if i % 2 == 0 { clockwise_length += to - from + 1; clockwise_ranges.push((from, to)); } else { counterclockwise_length += to - from + 1; counterclockwise_ranges.push((from, to)); } } counterclockwise_ranges.reverse(); let offset = turns % (clockwise_length + counterclockwise_length + 1); if offset == 0 { 1 } else if offset > clockwise_length { find_number( &counterclockwise_ranges, offset - clockwise_length - 1, true, ) } else { find_number(&clockwise_ranges, offset - 1, false) } .to_string() } pub fn solve_part_2(input: &str) -> String { solve_part_2_with_turns(input, 20252025) } pub fn solve_part_3(input: &str) -> String { solve_part_2_with_turns(input, 202520252025) }Python
A much simpler problem compared to earlier ones
# generator to yield dial values in the required order # yields (value: str, is_reverse: bool) def yield_dial_vals(coll: list): n = len(coll) for i in range(0, n, 2): yield coll[i], False right_start = n - 2 if n % 2 == 1 else n - 1 for i in range(right_start, -1, -2): yield coll[i], True def part1(data: str): nums = data.splitlines() n = len(nums) # total number of values on the dial # + 1 for the '1' value total_vals = n + 1 # effective rotation after full cycles effective_rot = 2025 % total_vals # if full cycles, return '1' if effective_rot == 0: return 1 # adjust for 0-indexing the remaining dial values effective_rot -= 1 # skip numbers on the dial until we reach the final value val_gen = yield_dial_vals(nums) for _ in range(effective_rot): next(val_gen) # return the final value return int(next(val_gen)[0]) assert (t := part1("""72 58 47 61 67""")) == 67, f"Expected: 67, Actual: {t}" def part2(data: str, rotations = 20252025): ranges = data.splitlines() # count values on the dial other than '1' n = 0 for val, _ in yield_dial_vals(ranges): a, b = map(int, val.split("-")) n += b - a + 1 # total number of values on the dial # + 1 for the '1' value total_vals = n + 1 # effective rotation after full cycles effective_rot = rotations % total_vals # if full cycles, return '1' if effective_rot == 0: return 1 # adjust for 0-indexing the remaining dial values effective_rot -= 1 # iterate through ranges until we reach the one the dial lands on for val, is_reverse in yield_dial_vals(ranges): # get range bound and size a, b = map(int, val.split("-")) r = b - a + 1 # check if the dial lands within this range if effective_rot < r: # it does! # return the appropriate value in the range based on direction if is_reverse: return b - effective_rot else: return a + effective_rot # consume the rotations for skipping this range effective_rot -= r assert False, "Should have found the target range" assert part2("""10-15 12-13 20-21 19-23 30-37""") == 30 # part 3 is just part 2 with a larger number of rotations from functools import partial part3 = partial(part2, rotations = 202520252025)I just noticed that you’re probably the first person I’ve seen to include tests.
Yeah, it’s an easy way to make sure everything is working correctly when I refactor or optimize. I used to keep samples in their own text files before but EC samples are small enough to include directly.

