#Advent of Code 2023
1 messages ยท Page 3 of 1
not difficult, except debugging the x position checker was a pain since i'm not good at visualizing those things and kept flipping the signs
it took a while
mine was very oop-y
i barely know how to oop
i avoid it when possible and just used nested lists
by nested i mean
Very Nested
example of my code
that would be unbearable without comments jeez
I mean if it works if it works
it used to be entirely uncommented
i always had like 2 screen long keys at the top of my program to let me know what indexes of what lists and sublists and subsublists meant what thing
other than that i had virtually no comments
the third screenshot was after i returned to the project a month later and was like "huh. um. what is this code for"
need to be proactive and start on the hour
https://youtu.be/IR8GTG6JcrA so nasty had to make 2 videos on it
Advent of Code day 03 refactor in Rustlang
The refactor! We use nom and nom_locate to solidify our parsing and location finding of symbols and numbers. Then discuss the differences between the original version and the refactor.
oh noooo I almost lost track of time
gotta be prompt
gogogo
I think this one ended up being my shortest code of the 4 days
oh today looks pretty easy
you know what, i have time, i'll see if i can do this one today
actually nah i'm tired i'll do it tomorrow maybe
tree shaking
or something
anyways, || everytime I try to use regex I remember I don't know regex ||
||Should I have bought that regex book at the bookstore...? Probably...||
okay i think ill like this one a lot more
fucking hell reading comprehension is hard, I took so long to realise the change in how scoring is calculated
oof
||points *= 2||
||I meant the part change, pt1 -> pt2||
||>the change in how scoring is calculated||
Day04 should be easy to do in bash, at least looking at the input and how I did it
I had failed to account for ||cascading copies|| the first time I did part 2
Me too kinda, at first I didn't fail to account for them, I just completely failed to grasp how to implement them at first, ||I tried to implement a running multiplier at first... a vector was so much better||
eats this fake quote
this was a nice break after the last couple days lol
I was bored so I did day4 pt1&2 in bash
casually winning millions of scratch cards
๐
when you wake up an hour earlier but the puzzle is so easy that you're lower same rank than yesterday
also day 3 is completely broken on windows??
giving completely different results
wild
aay first try
pog
i think ill take a break bc part two seems a little confusing
checked the stats page
apparently only 43 people have solved day 23 part 2 of AOC 2015
I solved today's part 1 on a school computer but I can't log in so I can't see part 2 :(
(I used nom! I feel the brain wrinkles forming)
Nooo my knowleegeee
shlrop
you mixed up the numbers
gold is the amount of people who have solved both
silver is the amount of people who have solved just part 1
aoc done for today
my solution is great and horrible at the same time
for part 2
part 1 was fine
||```rust
use std::collections::HashMap;
fn main() {
let input = include_str!("input.txt");
let result = calculate(input);
println!("result: {}", result);
}
fn calculate(input: &str) -> i32 {
let cards = input.lines();
let mut card_counts: HashMap<i32, i32> = HashMap::new();
for i in 1..(cards.clone().count() + 1) {
card_counts.insert(i as i32, 1);
}
let total: i32 = cards
.map(|card| {
if let Some((card_info, numbers)) = card.split_once(":") {
let card_id = card_info
.split_whitespace()
.last()
.unwrap()
.parse::<i32>()
.unwrap();
if let Some((winning_numbers_str, numbers_str)) = numbers.split_once("|") {
let winning_numbers = winning_numbers_str
.split_whitespace()
.collect::<Vec<&str>>();
let numbers = numbers_str.split_whitespace().collect::<Vec<&str>>();
let no_winning_cards: i32 = winning_numbers
.iter()
.map(|winning_num| numbers.contains(&winning_num) as i32)
.sum();
for i in (card_id + 1)..(card_id + 1 + no_winning_cards) {
if let Some(future_count) = card_counts.get(&i) {
if let Some(current_count) = card_counts.get(&card_id) {
card_counts.insert(i, future_count + current_count);
} else {
card_counts.insert(i, future_count + 1);
}
} else {
card_counts.insert(i, 1);
}
}
}
}
return 0;
})
.sum();
let total: i32 = card_counts.iter().map(|(_, v)| v).sum();
return total;
}
the map needs the .sum() on the end so that it actually runs the stuff in the closure ๐ญ
you can also do .for_each?
or just .. for card in cards
no sense making an iterator if you're not actually using it
yeah i did actually use it in part 1
and i was like "oh part 2 is just a tiny modification on part 1"
so i copy pasted and then it ended up not being useful
this is like the most year 7 thing i've heard in years LMAO
Due to yesterday I tried being more clean
.collect::<Result<_, _>>().unwrap()
what's the issue? mhuahah
I'm stealing your lunch
though there wasn't really any other way to unwrap apart from doing it inside the map, which would arguably be more ugly
yea it's not actually bad I just wanna annoy you :x
||the 1 case is superfluous, no?||
2.pow(1-1) == 1
last time I tried doing just 2_usize.pow(n.saturating_sub(1) as u32) and it didn't work so I'm trying to not do that again
well yea, cuz that's wrong
the 0-case is important
but the 1-case isn't
because your n => and 1 => are the same
yes yes
(winning_numbers_gotten != 0).then(|| 2_usize.pow(n as u32 - 1)).unwrap_or_default()
ew
I mean just rust let points = match winning_numbers_gotten { 0 => 0, n => 2_usize.pow(n as u32 - 1), };
yeah I changed it to that already
bites you
it's just I thought it was funny
holy shit part two made me doubt myself for like 30 minutes. like no way the answer is ||over 18.5 million||, there has to be something wrong with my math right
i put it in just to see how far it was out and almost got whiplash when it was like "that's right, well done!" 
tru
yeah part 2 is very exponential
The weirdest part was looking at the exponential counts resetting every now and then and thinking I'd screwed up a loop or something.
oh very interesting
I got confused for a while cuz I forgot you already had one of each card
i completely messed it up initially
yeah it's a pretty cool stochastic process
At least my code is aesthetic ๐
i spent ages being like "why tf is this not doing what i'm expecting it to".
>checks helper function
>return 1;
I love doing that. It's the programming version of "kindly disregard my previous email".
literally dbg!() everywhere being like wtf is happening
One of the things I've been trying to achieve while going through this year is building solutions that are robust enough to support the answer for part 1 and 2 of the puzzle. This one I'm particularly chuffed about.
||```typescript
type Card = {
card_number: number;
winning_numbers: number[];
uncovered_numbers: number[];
matching_numbers: number;
};
const parse_game = (line: string): Card => {
const [card, numbers] = line.split(":").map((chunk) => chunk.trim());
const card_number = parseInt(card.trim().split(" ").at(-1)!);
const [winning_numbers, uncovered_numbers] = numbers.split("|").map((chunk) =>
chunk
.split(" ")
.filter((v) => v.trim())
.map(Number),
);
const matching_numbers = winning_numbers.filter((num) =>
uncovered_numbers.includes(num),
).length;
return {
card_number,
winning_numbers,
uncovered_numbers,
matching_numbers,
};
};
export const Puzzle1 = (lines: string[]) => {
// Convert the lines of the record to a Game object.
const cards: Card[] = lines.map(parse_game);
// Find all the lines that have wins, and calculate the totals.
const card_wins = cards.reduce(
(score, card) =>
card.matching_numbers == 0
? score
: score + Math.pow(2, card.matching_numbers - 1),
0,
);
return card_wins;
};
export const Puzzle2 = (lines: string[]) => {
// Convert the lines of the record to a Game object.
const cards: Card[] = lines.map(parse_game);
const cards_won: { [card_index: number]: number } = Object.fromEntries(
cards.map((card) => [card.card_number, 1]),
);
// Find all the lines that have wins, and calculate the totals.
for (const card of cards) {
if (card.matching_numbers == 0) continue;
const copies = cards_won[card.card_number];
for (const card_number of range(
card.card_number + 1,
card.card_number + card.matching_numbers,
)) {
if (card_number in cards_won) {
cards_won[card_number] += copies;
}
}
}
// console.log(
// Object.fromEntries(
// Object.entries(cards_won).map(([card_number, count]) => [
// Card ${card_number},
// count,
// ]),
// ),
// );
return Object.values(cards_won).reduce((sum, curr) => sum + curr, 0);
};
I'm being a hack and writing them in js/ts first lol
That was a fun, simple day :)
I got to use nom too! Woo
yeah nice and easy one today
yea part 1 is pretty nice
part 1's difficulty should be swapped with day 1 part 2 lol
part 2 is a bit trickier especially since i am having difficulty parsing the instructions
yeah the step by step for it is REALLY helpful
yeah i couldn't really parse the description until i started trying to implement it
I'm really happy with my solution for it, it's so neat even if it did have to use a collection
actually i could sort of fix that...
what collection? i feel like you only need arrays, as long as you know the input length
here it is btw
Why a BTreeMap?
But don't you need to iterate on all of them regardless?
this new solution keeps the size at a minimum
part 2 is surprisingly tricky
nope
but all of them might be something else
just gotta be careful with copies that induce other copies
Here's how I dealt with it: (spoilers for both parts)
||```rs
//I parsed everything into this struct (with nom):
struct Card {
id: i32,
winning_nums: Vec<i32>,
gotten_nums: Vec<i32>,
}
// Part 1
let fin = cards.into_iter().map(|card| {
card.gotten_nums.into_iter().fold(0, |acc, num| if card.winning_nums.contains(&num) {acc + 1} else {acc})
})
.filter(|v| v != &0)
.fold(0, |acc, cnt| acc + 2i32.pow(cnt - 1));
//Part 2
let mut result = vec![1; cards[cards.len() - 1].id as usize + 1]; // One indexed, just ignore 0
for card in cards {
let mut cnt = 0;
for gotten in card.gotten_nums {
if card.winning_nums.contains(&gotten) { cnt += 1; }
}
for dx in 1..=cnt {
result[card.id as usize + dx] += result[card.id as usize];
}
}
Do you remove the prints for benchmarking?
not if you use std::hint::black_box, right?
this part 2 is faster even with the bigger collection size ๐
i guess it's just more easily optimizable
also I'm only testing part 2
with a hashmap it's very slightly faster
BTreeSet also seems to be a tiny tiny bit slower for the winning number collection ๐
part_2
smh
my part 2 code is finally no longer crashing and visually working, but is taking a Long time to process
either i coded it EXTREMELY badly and accidentally made an exponential process, or i have made incredibly poorly optimized code
it has been running for a full minute despite my previous days taking milliseconds
to do some debugging i made a simple debug thing and there are currently over 20,000 cards
can someone tell me whether this is too many so i don't have to wait seventeen years only to discover it has failed
Iirc my result was around half a million
It's about ~1ms for me, and Coca's is even faster
can't compare on different machines
though I have made it faster
slightly ugly but it reuses allocation
It's over double my speed if it's both parts lmao
I can take a look at your thing if youโd like
nah, it's kinda ugly, and i think it's working, i'll just wait a while
only slightly better
kinda funny how closing firefox improved the outliers by only like 20 microseconds
need the scooby doo meme here
Which one?
lmao
well i mad eit run much faster by storing what each card requests to add to the end of the list
however!
wait what no way is that the right answer
processing took 25 seconds and 665 milliseconds
let's see how fast it runs without printing (python takes ages to print)
wow!!! only 6 seconds
blazing fast
solves both parts
that's crazy
the regex is so unnecessary but the rest is cool
it would be way easy to use a function then a array for that
or well, faster
though idk actually
Man, that looks so elegant
I'm going to try 2022, Day 1, to learn how to parse better
https://www.youtube.com/watch?v=I0nCFMDkPNo neat way to advertise
๐ฒ Participate in Advent of Code 2023 using Kotlin and win prizes! Read more โค https://kotl.in/AoC23
This year, over the first 12 days of December, weโll hold livestreams every day to walk through the puzzle of the day together, discuss possible approaches and solutions, and chat with guests from the Kotlin team and the community.
Advent of C...
meow
what on EARTH
I am so stuck hoyl fuck
got something but it's SLOW
I think me too
Ughhh been busy yesterday and today and I'm already behind :(
ohg od moh god my cpu
why don't you like this
maybe I should use iterators instead?
where n is?
the number of seeds
jesus
I am waiting for it to compute
lmao
it's gonna take a while
I expect it to take 5-10 minutes
I will go see others people solutions while it computes
I am curious how much smarter other people are
I do not have the luxury of being able to do that without my computer dying
oof
I quit on part 2 I think
a lot of people say they solved part 2 with pen and paper but my brain is too stupid to grasp how
it's too punishing to make a small mistake
just straight up having a staring contest with the executable
it's frustrating
I have an idea but it's not entirely fleshed out
mayve in the time I figure it out my shittycode might finish
(edit: ran out of memory)
So... I guess I'm going to cry?
I realize I will probably not be able to do aoc on my travels jsut because I talk my reasoning out loud
and like
I don't need to say any more
Oh hey good to know I'm not the only one that does that
Do you also not have much of an internal monologue?
I edited the code
to fix what I had wrong
and it took 6 minutes to do 1 seed
this isn't workig
I am going to try something but I have no idea how long it'll take
never really trained it
You can train it???
idk
anyway
I think I'm on somewhat of the right track
๐
I've gone from "code that will get the right answer but also fry my computer" to "code that will get the right answer and is not too memory taxing but still really slow"
IT FINISHED ๐ฒ
Wondering if these puzzles get too hard I just do the previous years lmao
๐ตโ๐ซ
ok the input looks real hard but implementing was actually p easy
part 1?
i think this is the first day i'm going to have to ||rewrite my entire solution for part 2||
:)))))
i'm not giving up on uiua just yet but this is gonna be hard
the tricky part is that ||I'll have to split the ranges if they're not entirely in the mapping||, yea?
yeah
really just ||working with these ranges in general|| feels like it's going to be a pain
ok no I think I know how
gonna go to the bathroom and hope I don't forget before I can implement
gonna have to draw out some examples i think
You or me?
me
okay yeah the overlap calculations aren't that bad
The overlap calc was easy, but I'm hurting trying to figure out how to do that a bajillion times now ๐
where does my overlap calc fuck up AAAAAAAAAAAAAA
have you considered the case where the sets are completely disjoint?
anyway i think i have a uiua-friendly algorithm for part 2 now, just need to actually implement it lol
like optimization-wise? or just the overall structure?
fuck, now my overlap calc gives the same example output with the example input but it doesn't give expected output with my input
4.5h spent on this, nah, need sleep now, overlap calc too fucky, why do I have an endless loop somewhere
the great filter
i am still fighting
I just noticed I missed lunch
and only now realized I've spent my entire work day so far on this
hyperfocus activated
hey
wouldn't it be funny
if I spent several hours debugging something cuz I accidentally shadowed a variable
and then I fix that and I get a wrong result
๐ญ
fucken "works with sample but not real input"
noooo
I know my solution is dreadful
but I've spent so much time on it
and now it doesn't work
๐ญ
btw here's my plans for part 2, if at all comprehensible to anyone here
those notes make almost as much sense as my code
uh one moment
wanna see if there's something I missed
and your solution, if available
none yet lol
nope
doesn't crash
so IASHGOPIAHSFGOPJASO:IJFGOP:AISHJFO:IAHJSOP:IT HGo;h
o;ai
ed hgo;iszhdg ;iohas
do;ig h
oh fuck it wants the lowest one that corresponds to one of the starting values
๐
do the seed maps have overlapping zones?
wait how else would they do it? the lowest possible output would be trivial
because it's always possible to get an output of 0, right?
no?
still youd only have to look at the last one
wdym no?
I mean.. no?
if a map includes 0
I assumed you were to give the lowest value of any of your location ranges
that isn't just always 0
it's 54927065 for me
and it's 46 for the sample, which threw me off
wait i think you are?
no
you need to give the lowest value that is also in the starting ranges
basically, get the overlap of the starting value and the final value, and the lowest one of that is the answer
not "that is also in", just "that one maps to"
squint
ok I double misread
and I'm confused again
qwq
I'm applying all the thingies
then taking the smallest value in the location values
and that's too big
๐
i think that just means there's a bug in your code-
yes
but there's literally no way I can find out
short of super-fine-combing my entire code
i love higher level functions you can start by writing down what the puzzle says and then its done
I knew as much, which is why I was relieved when I thought I misread
what do I do now
suffer and debug
or suffer and rewrite everything
both :D
stares at the only person here to solve it
I'm not smart enough to make my solution solve it
holy shit i did it
I need the โsmartโ solution explained to me I donโt understand it
I need a solution
lol the uiua pad url doesn't fit in a discord message
apparently I'm really bad at giving up on purpose
uiua NOOO
i can still explain my approach at least
:3
so if you look at what i drew here
get the overlap of the sections you have already and the mapping, then make new sections from that
(mostly ignore the first page, that's just the algorithm to get the intersection and both tails)
yeah roughly
what's your range intersection algorithm?
:)
what does any of this mean?
e.g. a seed 1-20 and then a seed-to-soil of 2-10 => 1-9 ; 11-20 => 1-10
cuz I think I'm only checking for one of the mappings
(mappings is what I call the things in seed-to-soil etc)
both?
(at least i did)
like both mappings (there were two in your example)
yeah
well that'd do it
yep
gl!
now i have to go and actually write that traveling salesman implementation for my ds&a class
I recommend you look at my current part 2 attempt to see how bad it is
oooh I love tsp
I've actually got a mathematically perfect tsp solution
Simply outlaw door-to-door selling
true!
No salesmen, no peoblem
simply reduce all graphs to K_0
does a basic assert to check if my assumption was true
instantly fails
ok now I know why it didn't work
I don't know how to fix it tho
what was the assumption?
The assumption that only one of the mappings would ever apply
So now I need to reason out how to apply two or more at once
ok so
I apply all the mappings
and then, after I have all the new ranges, I need to somehow figure out the parts that weren't mapped
which
no idea
I can visualize it
I just don't know how I'd turn that into a program
can you track which ranges weren't mapped as you're finding the intersections to map?
not in a way I could think of, no
basically I start with my seeds (or otherwise) X
have a bunch of mappings of Y -> Z
and I need to remove Y from X
and at the end join X and Z, and that's the actual mapped ranges
I can do the Y -> Z, but not the remove Y from X
ohh i see
what i did was that ||my intersection function takes the range Rx from X and the range Ry from Y, and returns 3 ranges: one for what is in Rx before Ry, one for the intersection, and one for what is in Rx after Ry, and then put the first and third back into X and the second into Z||
ig really i kinda rebuild X each time?
I have the function that gives me the three different sections
implemented very badly and painfully
but I have it
if I put Z back into X immediately, then they might get double-mapped and that's wrong
very very tangential sidenote, but there's a fun property of representing ranges in uiua: you can represent it either as an array [StartingIndex Length] or an array [StartingIndex EndingIndex], and you can convert the first representation to the second with \+ and the other way around with \-
wait so what are your loop layers
presumably the outer loop iterates over entire maps (i.e. seed->soil or w/e)
no, I just do that 7 times
so you have two layers of loops then?
uh
maybe?
I have 7 loops that iterate over the seeds/soils/whatevers and applies the first mapping that overlaps that seed/soil/whatever range
just like
the same loop copy-pasted 7 times
ig my question is, does it iterate over these or these?
the former
and then the latter insofar as seed_to_soil.iter().find(|mapping| mapping.overlaps_with(seeds))
when instead it should just apply all of them instead of just the first one
yeah, i did it in the other direction
not exactly sure how i'd approach it your way, though i don't think there should be any reason for it not to work
i will refer you back to my crazed ramblings notes
this guy
so the 0,100 in the top left is just the input range we're starting with, and this part is the mappings
so then i keep two lists of ranges, applied and unapplied
I don't think starting from scratch would help either cuz I can't properly envision a different way to do it
and the table shows how they change through the process
so we start with these ranges in the unapplied array
then we look at each of these guys
for each of them, we iterate through unapplied and put the intersection into applied, and the disjoint bits into a new version of unapplied, that gets assigned back to unapplied at the end of the iteration
squint
then at the end we just join applied and unapplied
does my explanation make the diagram make more sense?
if I put the disjoint bits somewhere else, they aren't mapped by the following mappings
that's why you assign it back to unapplied after each line of the mapping
so
seeds = [array of ranges]
soil = []
for each mapping in seed_to_soil {
new_seed_ranges = []
for each seed in seeds {
apply mapping to all ranges
put moved ranges into soil
put rest into new_seed_ranges
remove seed from seeds // I can't do this because I'm iterating over seeds
}
join new_seed_ranges back into seeds
}```?
almost--you don't need remove seed from seeds, and join new_seed_ranges back into seeds goes outside of the inner loop
it's really not join
it's replace
because we're replacing all of seeds anyway, at the end of the outer loop
like just seeds = new_seed_ranges
gl!
ok implemented for the first of 7 steps and the example still works
and now I broke it
๐
ok I forgot to add the completely unaffected ones to the next step
I have once again implemented something that gives me a correct solution for the example but gives me 0 at full input
noooo
ok but it seems like it's a bug
cuz I think there's a 0 that comes from nowhere
build technical debt% speedrun
never had a single-day thing become so unmanageable so quick
lol true
when i was working on my solution i had so many dumpids (uiua's "debug print everything")
my debug output
in my defense:
it's really well formatted
(looks like this for sample input)
watr
I wanted all of them to be 4 characters so they're aligned
yea
ok it doesn't return 0
it returns something else that's too big
OFF BY ONE ERROR
I AM ONE STEP CLOSER TO RESTORING SNOW OPERATIONS
@spiral zinc tysm for help qwq
(I noticed that I had numbers that were the ending and starting value of my ranges, and I had been using inclusive ranges for everything, so I just subtracted 1 from everything's endings)
i mean the input format was like 20 5 representing 20..25
x..=x+length is length length + 1 and that's just .. THE off-by-one error
oop
:')
I got there tho
and for some reason that didn't cause an error before so who careesss
and
it still runs super fast
comparatively
695 micros
day 4 is almost a whole millisecond on average
running strings on my executables is very informative
.. huh
for RangeInclusive, start and end are private fields only exposed via getter methods
for Range, they're public
600 after I remembered to remove the printlns lel
5mins of debugging and I get the right answers :(((
Need of sleep and tiredness suck
annoying how today's one the higher/lower hint is not helpful at all
reruns same code
gets same answer
confused
i am not enjoying this one because it's a fucking pain to debug
i have NO clue where this bug is and i have NO clue if i'm over or under counting or anything like that
Chop up your splitting code into small bits which you test individually?
yeah I mean I've written this pretty modularly so it's not bad to test but
the annoying thing is that
it works on the example they gave
so I don't even have a small case I can debug

and idk where the edge cases are because the parsing seems to work fine
and it's mostly parsing
huzzah!
my parsing was wrong
||i'm parsing each map into a struct individually and then i have a traverse function which does all the looking up. in parsing each map into a struct i was just forgetting to pick up the last one because of the way my parsing works
i just got lucky that the last map in the example one didn't do anything to what ended up being the answer||
having written part 1 the way i have, it seems like part 2 should be easy (famous last words)
What structs do you have?
here is my code from part 1
||```rust
fn main() {
let input = include_str!("input.txt");
let result = calculate(input);
println!("result: {}", result);
}
#[derive(Clone, Copy, Debug)]
struct MapItem {
destination_range_start: i64,
source_range_start: i64,
range_length: i64,
}
#[derive(Clone, Debug)]
struct Map {
map_items: Vec<MapItem>,
}
impl Map {
fn new(input: &Vec<&str>) -> Self {
let mut map_iter = input.iter();
let _ = map_iter.next();
let mut map_items: Vec<MapItem> = Vec::new();
for row in map_iter {
let numbers: Vec<i64> = row
.split_whitespace()
.map(|x| x.parse::<i64>().unwrap())
.collect();
map_items.push(MapItem {
destination_range_start: numbers[0],
source_range_start: numbers[1],
range_length: numbers[2],
})
}
return Map { map_items };
}
fn traverse(&self, input: i64) -> i64 {
for map_item in &self.map_items {
if ((map_item.source_range_start)
..(map_item.source_range_start + map_item.range_length))
.contains(&input)
{
return input - map_item.source_range_start + map_item.destination_range_start;
}
}
return input;
}
}
#[derive(Clone, Debug)]
struct Maps {
maps: Vec<Map>,
}
impl Maps {
fn new<'a, I>(input_iter: I) -> Maps
where
I: Iterator<Item = &'a &'a str>,
{
let mut paragraphs: Vec<Vec<&str>> = Vec::new();
let mut temp_lines: Vec<&str> = Vec::new();
for item in input_iter {
if item != &"" {
temp_lines.push(item);
} else {
paragraphs.push(temp_lines.clone());
temp_lines = Vec::new();
}
}
paragraphs.push(temp_lines.clone());
return Maps {
maps: paragraphs.iter().map(|x| Map::new(x)).collect::<Vec<Map>>(),
};
}
fn traverse(maps: Maps, seeds: Vec<i64>) -> Vec<i64> {
let locations = seeds
.iter()
.map(|seed| {
let mut current_seed_location: i64 = seed.clone();
for map in &maps.maps {
current_seed_location = Map::traverse(&map, current_seed_location)
}
return current_seed_location;
})
.collect::<Vec<i64>>();
return locations;
}
}
fn calculate(input: &str) -> i64 {
let lines = input.lines().collect::<Vec<&str>>();
let mut lines_iter = lines.iter();
let mut seeds: Vec<i64> = Vec::new();
if let Some(seeds_line) = lines_iter.next() {
if let Some((_, seeds_str)) = seeds_line.split_once(":") {
seeds = seeds_str
.split_whitespace()
.map(|x| x.parse::<i64>().unwrap())
.collect();
}
}
// remove that one blank line lol
lines_iter.next();
let maps = Maps::new(lines_iter);
let locations: Vec<i64> = Maps::traverse(maps, seeds);
return *locations.iter().min().unwrap();
}
it's ugly asf lmao but i wanted to try parsing the data into a proper struct
i just think today maybe wasn't the day for that
i also think that this solution is too inefficient to use on part 2 lol
maybe if i leave it cooking overnight
yeah not gonna work lol
Why do you have Map and Maps?
idk horrible naming
tech tebt because of something that i threw together quickly lmao
Or rather why do you have a vector of maps and then a vector of vector of maps
MapItem is just a single row from a map, Map is then a whole map (seed-to-soil) and then Maps is just all of it
Ah
wacky i know and not very much thought has gone into it
if i had to rewrite it (which it looks like i will have to do anyway) i would not do the same thing lmao
I think I'm gonna have to work with ranges of values and then work my way down
I just had a vector of tuples for each map and put those in a vector, structs for that feels overengineered or bloaty
it almost definitely is
Day 6 gonna drop and I haven't even done 4 or 5 ๐ญ
today's had better be more tolerable
4 was ez, go go, it'll probably take under 1h
You might want to skip 5 though, at least pt2, if you care for your sanity
I looked at 5, my eyes crossed then glazed over
I'll try 4 though. Seems simple enough
naturally, I'll solve it with regex
apparently someone did day 5 part 2 with a GPU
that's great
||anyone remember what word to search for to get the "optimization" formulas related to this day? I've completely forgotten it in Finnish since my high school days and don't even know it in English :>||
||I think I have the formula but I'm kinda dumb||
||+/- 1 here and there||
I threw so hard
my code could have brute forced it in 30 seconds and I spent 5 minutes doing math
||If you were smart and know that the input goes false -> true -> false then numbers of that scale are so fast to bruteforce. If at first it's false then test if you can skip ahead, if you can then test if you can skip ahead even more until your test gives positive results and then when the results go false again then break your loop and report result||
||1.62s for the whole exec of a bruteforcing debug build (probably without any optimizations enabled) on i7-7600k||
||well ig it's nice to have a break after yesterday, but this was way too easy||
anyway here's my solution ig
||it wasn't even difficult algebra /complain||
I look forward to doing it tomorrow then :)
ok
this year is just all over the place with difficulty
12 hours yesterday, 20 minutes today
๐ตโ๐ซ
eh, it has now consistently been hard into easy in pairs
so expect tomorrow to punch your teeth out again
oh no
I literally had to change nothing for day 2
actually yes I did
the data type
from u16 to u64
solved 9 hours earlier, but only 5000 ranks higher
yeah my change was literally five characters
lol
it was 2 changed for parsing, 2 changed for not multiplying (though come to think of it they probably could've been left in), and one since it was using scalars instead of arrays
today was so easy lmao
very refreshing after yesterday
||and part 2 was just a modification to the parsing so not even difficult!||
real
i still haven't finished part 2 from yesterday lmao
still havent done day 5
i started it but my parsers werent working correctly
i do really wanna do it, and ill probably get ot it tomorrow
I wonder if they'll expand the example of day 5 eventually
Cuz there's so many edge cases that are not easy to debug at all
in general it's so hard to debug
like i think i'm close i just haec one piece of wrong arithmetic or something
what's your approach?
start with ranges of seeds
check for overlap against ranges that get mapped
map the overlap
leave the other bits
pass everything to iteration 2 and repeat
I see
is that the right angle generally speaking?
yeah that's pretty much what i did
sounds good yeah, does it work on the small data?
not quite yet
not sure where the issue is
I did have it working on small data but it broke on large data so I rewrote a bit and now it doesnโt work on either
๐
That's exactly what I did
so far i've mostly managed to avoid having algs that work for the small input but break for the big input, i hope i can keep it that way
uiua buff honestly
quite possibly
My impression of uiua is that you basically encode the underlying structure and then ask for a number
Not sure if thatโs a good impression or not but itโs the one I get
honestly that sounds more like fp than something like uiua
took me over a day
but I did day 5 part 2
in not 40 minutes
on my trash cpu
some of my proudest code
It is not good
but
I am proud of it
I should've used the
https://doc.rust-lang.org/std/ops/struct.Range.html
but I was in too deep already
I don't have a computer anymore (visiting family)
I'm going to fall so far behind :(
I'm already two days gone
that's very fp
describing what things are
declarative programming can look really lovely
Procedural programming is my beloved <3
OOP sucks and FP is too hard to grasp and keep track of
yeah i'm always out for the first 90 minutes or so from launch
I am out with people that do aoc and one of them has already expressed an interest in doing it live ๐
I have entered my depressive episode eraโข๏ธ so I have not had any ability to do them :(
Expect today to kick hard
same
lmao
I got 30 minute sfor the solve
it's either I am done in 30 minutes
or in 15 h when I am back from university
or I skip sport
hmm
oh no
I gota solution it works on the sample input not on my input fuck
I'm still grasping how should I check how many different cards there is and figure out what kind it is then
15 minutes in and 82 people have already finished
I solved it oncthe bus on my phone .-.
"oh day 5 part 2 doesnt seem that bad" oh god wait this is gonna take a millennia to figure out
How are people solving it in a way that takes so long
Are y'all actually going through every number?
this is not practical
im kinda stumped
i probably have to rewrite everything into a much more verbose structure and analyze redudant ranges
cus most of it is redudant ranges
ill work on it some more later
excited tho
this is my favorite one so far
(the more verbose structure is called Range and is included in std)
ye
I've been slacking off so much
now for pt2 /_\
150 LoC for pt1 which I needed Ord trait implementations and stuff for
*reads pt2* oh no...
it's not nearly as bad as it sounds lol
example output matches my output with example input, my input's output doesn't match expected output
That's so ass
not sure how to turn five cards into a hand
ok buddy
At least for my implementation it's completely awful
wh
why does my thing only work for sample input
what order of magnitude should the answer be?
I'm in the hundred-billions range ๐
I'm balling around 9 digits
so the same
fucking finally
D:
i love when my parser just fails. for no reason. why are you doing this
oh my god wait its bit limit again
ughn
okay day 6 was absurdly easy
I know thereโs a nice greedy solution for part 2 but you know what they say
Naive always wins
||yeah you can just assign the jokers to the most commonly repeated card||
My day 7 part 2 code passes the sample solution but not the real solution wtf ๐
I need aoc like all year, itโs actually good motivation to sharpen coding skills
Could always redo previous years
ahahahahaah
this was fun
SHIT I WOKE UP LATE
you're still miles ahead dw
is pt1 supposed to take a while to crunch..?
Or did I fuck up and loop
I let it run for a minute and 22154890 crossroads wasn't enough to find the destination, oh no
I got part 1 almost instantly
yay linked lists
im gonna make this overly complicated
Either I fucked up or 10 mins isn't enough to compute on my CPU :>
How many digits did the pt2 answer have?
If an AOC solution takes more than a few milliseconds, you're doing it wrong
I'm currently "bruteforcing" it at 662324623, I have no idea what the meth shortcut is here
Even though I only have 6 things in my vector this doesn't seem to be ever ending nor do I have any leads atm
hehe yeah
Any magic words for search engine for the meth theorem/formula? :>
Otherwise it's just a knowledge diff, completely stumped and can't finish today
yeah i had to get some hints, there's the ||chinese remainder theorem||, although ||there are certain properties that always hold with the inputs they gave to this problem that means that an easier solution is possible||
...i think i jinxed it
I literally just guessed that it would be ||the LCM of all the periods, I'm bad at math||
||if that was wrong I'd have been screwed||
Took me a few minutes to wrap my head what needed doing, but it was pretty good.
i had kinda hoped it'd be the kind of challenge where ||the straightforward solution was too slow so you had to construct a polynomial instead||
but honestly ||idk if that would even be an optimization||
probably would be if part 2 was like "generate the millionth number in the sequence" or smth like that
but even then it could be optimized without that strategy, so idk
wahoooo I forgot one
if any of y'all might be able to help out
that'd be great
I am honestly stuck
still a great meme
lmfao
"miku-chan03"
- helped installing Arch Linux on all her friends' PCs
- contributes very helpful PRs in uwulang, maintainers thank her without questioning further
- types as fast as Yuki Nagato from The Melancholy of Haruhi Suzumiya
- expert in low level graphics programming with OpenGL
- wears cute cat ears and programming socks, drinks Monster on the daily to boost up productivity
can someone give me the solution to line 1?
line 1?
the first line of the imput
so i have something better to compare against
although i think i know the problem
...i mean everyone has a different input file so unless you share yours there's not much we can do
what's your algorithm, roughly?
push a set thats the difference of each pair of the previous set until its all 0s
reverse it, push a 0 to the first set, and push the last value of the prev set added to the last value of the current set
Day 7 Part 2 Solution
I think it came out really well (highlighted is the actual computation parts)
Iโm on the bus home, no clue if Iโll make it on time yet 
part 2 is impossible
it's day number % 5
Even day hard? Did they actually mix up the days by accident
if day % 5 == 0:
difficulty = "super hard"
else if day % 2 == 1:
difficulty = "hard"
else
difficulty = "easy"
bruh I've been saying the words "up" and "down" out loud nonstop for 2 minutes trying to trace these paths and I sound like the fitnessgram audio
I think I'm close
wow that was fun
apparently there is a better way to do part 2 by using ||bfs and flood fill|| but I came up with something a little more unhinged that I'm pretty proud of
i'm gonna write an algorithm that's so inefficient--
has anyone done day8 part 2? idk if i'm doing something wrong or my input is unlucky but my algorithm is struggling
could you run this through your solution and see if yours finds an answer?
here's my code too hopefully
yep, it does
ough, idk what i'm doing wrong...
it should be moving all curr_locs to the next and check if they all end in 'Z' to stop
oh yeah ||that won't work, the total number of iterations is far too big (on the order of 10^13)||
oh... guess it's too big brained for me then i can't think of any other way
Observe: my absolute mess of a day 9 part 2!
Part 1 came out really neatly, part 2, uh, did not
(I just found out ||VecDeque doesn't have windows(), that was surprising||)
So far the only day that's bested me is day 5
I just can't with it
I parsed it and now I have no idea how to continue
||re: windows, you should take a look at VecDeque::make_contiguous||
oh no day 5, i could only do part 1 because part2 is too big brained like day8 part 2
just got on my PC for the first time in a few days
๐
guess I dropped out of aoc ๐
lol i've been dragging 2 days behind ever since it started. it'fine
vacation just started and now my body went into hibernation mode
I've slept like 16 hours the last two days
cat mode
I solved days 1-7 but a bunch of other coding projects up that are actually important have piled up so I was forced to drop out qwq
Wait, day 8 part 2? Why?
i have no intuition on why ||lcm|| works i can't convince myself it does
Like
||Imagine two clocks: one strikes 12 every 10 minutes and the other every 15||
||How much time will pass until they meet again?||
Edited, typo
Same thing but with the ||ghost paths||
||Because the cycle is closed and periodic||
aye till there i'm with you but i don't see how the input would create a cyclical structure
part of it is assumptions you can show are true about the inputs they actually give
part of it is that since there's only finitely many possibly states you're bound to return to a previous state and end up in a cycle eventually
^^
The way I see it: ||the input is finite, and you can't "stand still" (I assumed, might not be true now that I think of it), so you gotta end up at a cycle Eventually||
they only give you inputs where ||the cycle length is equal to the distance between the starting point and the z||
hmmmm make sense, you'd still need to assume that the ||the first z you meet is the end of the cycle||
i mean a cycle has no well-defined ||end point|| lol
aggh too many assumptions for my taste
yeah, you can show that they're true for your input though
but i didn't like it either
I didn't check them, I just thought ":o wait is it ||mcm||? *turns it in* it was! neat"
Aaaa (Day 10 part 1)
I can't stop the ||recursive function from spreading not-outwardly||
i suggest ||you have a param that keeps track of the previous step so you don't go back on your feets||
oh my, i think this is overcomplicating it
i started with simple and complexity encroached
i have no idea how to approach this rn
This is what i've got rn
Everything that || find_longest_path ||depends on is probably correct, but it itself eludes me
long screenshot
It's not a screenshot >:)
It's Silicon, stolen found from tris' rust's install list
long image of code then
i want to live in a world where your monitor is 2m high
but yah i still feel like this went too far into complexities
also the loop is only one, you shouldn't need a find_longest_path
Wdym
||The function starts at S and only travels across valid pipe boundaries||
I wonder what obvious result I'm missing
S has only two pipes connected to it and they are connected to each other in a loop, the junctions never diverge bit the name kinda implies you think it might
that just confused me a little
i've been trying to do all these right after i wake up but i won't be able to tomorrow
early exam :(
this one was frustrating but good
i gotta start catching up to this stuff
i haven't done anything since like
day 4 or 5
same
I am currently doing day 5 and oml
I do not understand this shit at all
nvm I just MISTYPED
i am going to implode
I think your not supposed to brute force day 2 part 2
why does it have to be so hard to spoiler code >:(
I did it anyways with rayon, I'm surprised rayon allowed me to use a slice of vecs without complaining about threads
Skill issue
||```rs
fn par_generic_solver(mappers: &[Vec<MapRange>], seeds: impl ParallelIterator<Item = u32>) -> u32 {
seeds
.map(|seed| {
mappers.iter().fold(seed, |prev, map| {
map.iter().find_map(|range| range.map(prev)).unwrap_or(prev)
})
})
.map(|n| Some(Reverse(n)))
.reduce( None, |a, b| a.max(b))
.unwrap()
.0
}
||```
...
```||
you tried
```||
...
```||
which puts the start of the spoiler inside the code block
ยฏ_(ใ)_/ยฏ
If the block has || inside it then I think you're fucked
||```bash
false || true
||```rs
println!("test");
this works :v
Skill issue :)
||```rs
println!("logic test: a || b");
welp

if you have a no-args closure or a logic or, you're fucked
let a = | | 5 * 5; isn't valid no-args closure?
time to see if day 6 part 2 can also be brute forced
yep
that was really fast
...even without rayon
day 6 part 2 nom my beloved
||```rs
fn number(i: &str) -> IResult<&str, u64> {
map_res(
fold_many1(
terminated(digit1, multispace0),
String::new,
|parts, part| parts + part,
),
|n| n.parse(),
)(i)
}
ig I'll day 7 then
no nom for this challange ๐
woah
I use nom by spamming tags and separated lists, I should look into using it properly
god have mercy (day 7 part 1)
I hate how this will probably work
wait wait
one fix
have to actually not repeat the cards.values() calls
Oh hey that's basically my solution and also my problem!
Like
Exactly that
With the length match and everything
oh god
Just executed a bit different
I take an array of card faces, sort it, then group by a==b to see what hand you have
:)
still on it ๐ญ
Me too
ah fuck
Tho I've also not really done anything except play RimWorld and Minecraft on my PC for a few days
That is so many lines
Mine was like two ifs and an else (and an impl From<usize> for HandType)
I'm going to make you cry either way
I made unit tests for that part and that part only of AoC
With the samples and with my own examples
And thank God I did because I had the logic wrong lmao
time to see which one is wrong
Yipee
I just implemented ToString for my hand, printed out all the parses hands, then compared with the input
(I presume the 0-index is just in printing here, right?)
(I don't remember how the names went, but) on the match, both 1 and 5 are HighCard?
Wasn't there a name for when there's only one type?
I might be misunderstanding what the match does, though
622 should be a full house
