#Advent of Code 2023
1 messages · Page 2 of 1
what
what
i'm still processing how to get ||the colors, since they're not ordered||
oop got it
well I just ||split sets and looped through them||
now I feel stupid about possibly misunderstanding what that meant to say
||regex to the rescue||
I feel like I should be using a benchmark library but tbh I don’t know any for rust and I wanted to write something simple enough lol
||When you have regex everything is a nail||
I got part 1 :)
This is where I will feel dumb
The way I did part 1, I think, is going to make this P2 very easy
maybe
yipee, it did!
first try, woo
My solution is 95% parsing 5% logic lmao
Here's D2P1, Part 2 is pretty trivial from it:
Why can't I spoiler code
||
#[derive(Debug)]
struct Game {
id: usize,
throws: Vec<Throw>
}
#[derive(Debug)]
struct Throw {
red: usize,
green: usize,
blue: usize,
}
fn main() -> Result<(), Box<dyn Error>>{
let input = {
if USING_TEST_INPUT {
"Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green".into()
} else {
gai::load_input(1, 2)?
}
};
let mut games = vec![];
for line in input.lines() {
let semicolon = line.find(":").unwrap();
let id: usize = line[5..semicolon].parse().unwrap();
let throws = &line[semicolon + 1..];
let mut final_throws = vec![];
for throw in throws.split(';') {
let (mut red, mut green, mut blue) = (0, 0, 0);
for dice in throw.split(",") {
let dice = dice.trim();
if let Some(i) = dice.find("red"){ red = dice[..i - 1].parse().unwrap(); }
if let Some(i) = dice.find("green"){ green = dice[..i - 1].parse().unwrap(); }
if let Some(i) = dice.find("blue"){ blue = dice[..i - 1].parse().unwrap(); }
}
final_throws.push(Throw { red, green, blue })
}
games.push(Game { id, throws: final_throws });
}
let mut valid_ids = vec![];
'game_loop: for game in games {
for throw in game.throws {
if throw.red > 12 || throw.green > 13 || throw.blue > 14 {continue 'game_loop;}
}
valid_ids.push(game.id);
}
println!("Valid ids: {:?}", valid_ids);
println!("Answer: {}", valid_ids.iter().sum::<usize>());
Ok(())
}
||
what
yes you can
I'm still up but not really able to think about code, might just do this in the morning
|| ```rust
fn main(){
println!("Beans";
I can but i am unable to
My brain too fried at 6:33
This is what I did for part 1
||```rs
use std::collections::HashMap;
fn main() {
// read input.in
let input = std::fs::read_to_string("src/input.in").unwrap();
// split input into lines
let lines = input.lines();
// for each line
let mut sum = 0;
for line in lines {
// split line into parts (game id and sets)
let parts: Vec<&str> = line.split(": ").collect();
let game_id: i32 = parts[0][5..].parse().unwrap();
let sets: Vec<&str> = parts[1].split("; ").collect();
// for each set
let mut possible = true;
for set in sets {
// for each cube
let mut cubes = HashMap::new();
for cube in set.split(", ") {
// split cube into parts (count and color)
let cube_parts: Vec<&str> = cube.split(" ").collect();
let count: i32 = cube_parts[0].parse().unwrap();
let color = cube_parts[1];
// add count to cubes map
let current_count = cubes.entry(color).or_insert(0);
*current_count += count;
// check if possible
if (*current_count > 12 && color == "red") \|\|
(*current_count > 13 && color == "green") \|\|
(*current_count > 14 && color == "blue") {
possible = false;
break;
}
}
}
// add to sum
if possible {
sum += game_id;
}
}
// print sum
println!("{}", sum);
}
comments were obviously added afterwards
right before lines
oh
start being parsed
facepalm
it's okay
i was only looking in the for, mb
I like rust a lot surprisingly
Yeah! It's a good language
It made the answer so clean, strings are actually a joy
working with strigns is not pain as it is in c... at least for me
fuck working with strings in C
or cpp
or java...
The combined solution of part 1 and 2 I did afterwards is here
||https://www.reddit.com/r/adventofcode/comments/188w447/comment/kbnervk/?utm_source=share&utm_medium=web2x&context=3||
I didn't test it hopefully it works
Edit: it works
I can't either
I kinda just stopped shaking
my heartrate went through the roof when my first part was accepted 1st try
Same but I ended up being 4000th

I still haven't finished mine :(
I forgot the days made a pretty picture
aa I love this
small difference in time jumps for pt1 to pt2 between day 1 and day 2
rip bedtime being on time
the first one took me like 15 total minutes
the second one should take less than an hour
Man my code is so fucking ugly
same...
clean code is for wimps and dweebs
yay I got a cleaner v2 version
part one code with commented explanations because i was getting confused with all the nested for loops
I'm apparently too dumb or something and can't figure out what's causing a way too high of a number. Can I get some help?
solves both at once and with annotations
unfortunately, i don't speak rust, and i can't help much, but i am noticing a few things that seem a little weird to me (but could just be how rust works)
||first thing i notice:
if number_half > MAX_BLUE{ truth = false; break; }
this is being done in this section only for blue, and not for any other colors
second thing i notice: it looks like you're splitting the things by semicolon, but you aren't handling the whitespace. in addition, after you split by comma, you split by whitespace, which amkes me think it would split "7 red, 4 blue" into [["7","red"],["","4","blue"]]||
but also i don't know how to read rust and i don't know what i'm talking about
The first one was to early abort easily without having to check each pair. I could make it more robust to early eject on all 3 and not bother.
Oh hmmm, I wonder if that does matter. I'll look into that. Thank you!
Also I'm super noob to programming so this could all just be me not knowing what to do
no worries! we all started as noobs and ideally eventually became not noobs
i hope my advice is helpful even though i have no clue how rust works
alright, have fun!
you're a mad duck
and I respect that
my parsing code is abhorrent lol, kinda tempted to redo it
IT'S SO CONCISE WTF
hey rust programmers would you like a crate that would download the input for you?
nice!
||I barely changed anything, I moved the rejection part into the section where I insert into the hashmap||
||and thanks to clippy I learn I don't even need a hashmap||
|| reading part 2. Oh no I definitely have fucked up||
someone else in the uiua server has an absurdly good solution
I was bored and did day2 pt1&2 in bash
legend
we have Hello World hehehehehe!
Why not UwU
I am a silly programmer uwu
wow day 2 part 2 was so easy
wow
I was earlier today than yesterday
ig not working helps even if I'm too lazy to get out of bed for 5 hours
here's my justfile
arch := "x86_64-unknown-uefi"
ovmf_path := "/usr/share/OVMF/x64"
default: run
build:
cargo build
run: build
#!/usr/bin/env bash
cd target/{{arch}}
mkdir esp/efi/boot
ln -s debug/*.efi esp/efi/boot/bootx64.efi
qemu-system-x86_64 -enable-kvm \
-drive if=pflash,format=raw,readonly=on,file={{ovmf_path}}/OVMF_CODE.fd \
-drive if=pflash,format=raw,readonly=on,file={{ovmf_path}}/OVMF_VARS.fd \
-drive format=raw,file=fat:rw:esp
and I'm using the uefi crate
it's all surprisingly simple to set up
and now is when I run other people's solutions only to see that they're shorter, just as correct, and faster
brb gotta swap all my unwraps with unsafe ones
(that doesn't actually improve performance afaict)
having less branches should do something
also this takes 90% the time of miy solution
I'd say the compiler already knows
cuz whenever I do it, there's literally no difference
in some cases definitely
what's yours then?
pasted twice 😔
how do I keep doing that
oh, truee
that's why I skipped on using iterators fully
though for part 2 it's probably viable to do so
ok that saved a bit
like 30 micros
heck yea
statistically almost insignificant performance difference
except sometimes mine apparently runs at 1.8 millis for no reason I can imagine
changes something
it gets worse
undoes changes
it stays worse
A library for finding occurrences of many patterns at once. This library provides multiple pattern search principally through an implementation of the Aho-Corasick algorithm, which builds a fast finite state machine for executing searches in linear time.
this crate is exactly what I wanted yesterday
though it doesn't have reverse searching so it's fine
I want to avoid crates if at all possible
I would probably implode before implementing an algorithm like that
wait what do you use
hyperfine
Advent of Code 2023 is UPON US! What better way to spend the holiday season, learn to program, and test your skills against your friends. This year, I've decided to try something kind of insane. I'll be choosing a language off the wheel every day.... let's see what happens.
🏫 COURSES 🏫
Learn to code in C at https://lowlevel.academy
🙌 SUPPORT T...
reminds of Lashette's regex last time
Me seeing the solutions of Day 1 Part 1
"You mean I didn't have to spend an hour reading the Regex crate docs?"
ok time to start this
I will actually try and use regex !!
bruh so close to perfect I did ||min instead of max|| 💀
aight lfg
that was easier than yesterday
not using regex definitely helped me in that
I feel is one of the "what your are familiar with" things
I defaulted to regex because you use that extensively in scripting
Basically I had to spend a hour trying random stuff then discarding it instead >.>
Binary search always finishes at the sweet spot though: not too high or too low
I'm predicting my next answer will be too low then the one after that will be right
Computer assisted brute force binary search
is there a leaderboard for the server?
2265237-0f8ae43d
Can a mod pin that code for this thread?
HOLY SHIT I GOT IT
pogger
or @slate zephyr, cuz they made the thread, no?
I tried to, but cannot
Behold the ugliest, working code
I... really hope AoC makes me a better programmer lmao
I really just kinda threw things at the wall for part 2
very... interesting
why rust l.as_mut().expect("Couldn't parse line"); l.as_mut().unwrap().replace_range(..=7, "");
no idea what's going on there+
remove the initial part which we don't need for part 2
so... less space?
no
why both of those
instead of just the second line
or the first one with replace_range
oh then god knows
I didn't want to bother with the game part of the line since I knew what number it is from the lines index
also you can just l[7..]
ish
yes I know
This is what happens when an idiot codes :)
What happens? I see no idiots coding here
but why are you doing l.as_mut().unwrap(); l.as_mut().unwrap();
you're doing the same thing twice
having the code using a BufReader when your collecting into strings at the start is the only meh part really
the compiler commanded it
You did not observe the code xP
commanded what exactly
also wow I once again forgot that it's possible to make a program that solves both parts in one
which would also save me a bunch of performance
or or use include_str!("day2.txt") so you do all the IO at the start
that's smart
that's actually super smart
no runtime IO
woop
reading files and parsing them is always my least favorite part of AOC
Actually I couldn't quite get the right number if I kept in part 1. I'm trying to fix that so I get both answers at once
the logic can be so simple but just parsing it into a format you can work with is annoying
So true
I don't want to do AST in AOC
When I did AoC in 2018 with C I wanted to die
I like doing IO but only if it's something I can optimize like in day 1
Also thanks for the encouragement and advice guys 🥺 I really appreciate it
i do!
honestly i need to learn more about parsing asts and stuff
😭
sadness
idk if it's accurate to describe it as ASTs
just a vibe thing with "how neat is it to turn this into what I want"
and with day 1 there were tricks like "search for the first occurrence and then search for the last in reverse order so you skip the middle "
and when the problem because more complicated it often becomes less neat
I need to learn chumsky just for this, but the tutorial is so daunting
Like
what
How am I supposed to come up with that
whuh
The [activation energy] of learning these types of parsers seems so high
Does these help? https://bodil.lol/parser-combinators/ https://blog.subnetzero.io/post/building-language-vm-part-00/ https://stopa.io/post/222 @spiral zinc
Covers general elements of computer hardware useful to know before reading the rest of the tutorials
I'm currently doing the parser one. I did the lisp one, that was super fun. Haven't started the language VM yet
oh thanks
also this showed up https://createlang.rs/
this is a bit less interesting to me, i want to learn how to do this kind of stuff manually first
thanks anyway though
Tried my best haha, these kind of things are great for me though since well I don't know a lot of stuff
this has weird priorities
first result of google ¯_(ツ)_/¯
I never tried that one yet and it wasn't recommended to me so yeah
I tried 😭
like introducing JIT before bytecode interpretation
I personally like https://craftinginterpreters.com
ooo
hmmm lol
that's certainly a Choice
okay maybe ignore that one lmao
done today's!
part 2 was SUPER easy after doing part 1
it was like a 3 line change xd
lol yeah
already written the function that did the bulk of the work so just copy paste that lmao
the only change between part 1 and 2 in my uiua solution
that is beauty
also i think i'm doing this wrong
like obvs i'm getting the answers but
they're HELLA ugly
certainly far more beautiful than the string-parsing part of my solution lol
because it's all string handling and bc i'm doing it in rust i'm ending up in like 5 or 6 layers of if lets
which doesn't feel right
||```rust
for game in games {
if let Some((game_id_str, rounds)) = game.split_once(": ") {
if let Some((_, id_str)) = game_id_str.split_once(" ") {
if let Ok(id) = id_str.parse::<i32>() {
let largest_cubes = largest_cubes(rounds);
let max_red = largest_cubes.get("red").unwrap();
let max_green = largest_cubes.get("green").unwrap();
let max_blue = largest_cubes.get("blue").unwrap();
match (max_red <= &12, max_green <= &13, max_blue <= &14) {
(true, true, true) => {
valid_games.push(id as i32);
}
_ => { /* do nothing */ }
}
}
}
} else {
println!("Unable to split game: {}", game);
}
like wtf is this ????
that's pretty close to mine, I just unwrapped everything lol
yeah honestly for aoc unwrap is fine
yeah i mean i should probs just unwrap everything because the input is obvs so well defined
but
on the plus side
at least i know how if lets work now!
in AOC code quality is the friends we made along the way
yeah i think i'll just unwrap everything tomorrow
@real robin I like seeing your solutions :)
should I try a no-regex solution for the lols
Idk I just do! I like seeing everyone's solution I guess and I noticed yours /shrug
I solved both parts in under 10 minutes with it, but without it is going to be a nightmare
My regex fu was not strong enough
i'm always so impressed by how much power regex has and it makes me want to learn how to use it properly
It's very strong and very finicky
I don't think it was extreme but it was definitely surprising for the first day
the main issue I had with it is my brain screeching at the performance
ahahaha fair enough that'll do it
I had a harder time with day2 tbh
yeah for me this was more difficult because good string parsing in rust is a bit of a pain it seems
emphasis on good though
tomorrow i will be .unwrap()ing everything
that's honestly fair.
|| I regexed the first day so it wasn't bad ||
This one hurt my brain with all the nested loops and string parsing
maybe one day i will sit and do the data model and then write something that parses the string into the data model nicely as an exercise
just a bunch of splitting
yeah
it was nice to see all the different types of splitting that rust offers built in tho
but you see. I am very new, and very easily confused
dbg! in every for each
what made it tricky was that part 2 included an unmentioned and ambiguous side case
at least for me
what side case was that?
oneightwoneightwoneightw--
i didn't even consider it tbh
yeah my solution got lucky and didn't have to worry about it eighetr
i typed eight so much that i spelled either as eighetr lol
i just checked for the first one by getting checking every one and then moving the slice by 1
and then vice versa for the last
ig it was meant to catch if you were using a consuming parsing method like i was, but i just kinda considered that an expected side effect
i mean i just solved it by not eating the entire word after and just leaving the last character
makes this macro look silly
to be fair, it's the same as my ||silly regex
pub fn day_one() {
let file = File::open("day1.txt").expect("You did it wrong, dingus");
let content = BufReader::new(file)
.lines()
.map(|l| l.expect("Unparseable line"))
.collect::<Vec<String>>();
let mut total = 0;
let re = Regex::new(r"[0-9]|one|two|three|four|five|six|seven|eight|nine|zero").unwrap();
let er = Regex::new(r"[0-9]|orez|enin|thgie|neves|xis|evif|ruof|eerht|owt|eno").unwrap();
for strang in content {
let a_str = day_one_matcher(re.find(&strang).unwrap().as_str());
let blah = &strang.chars().rev().collect::<String>();
let b_str = day_one_matcher(er.find(blah).unwrap().as_str());
total += (a_str.to_string() + &b_str.to_string())
.parse::<i32>()
.unwrap();
}
println!("{total}");
```||
that is smart
don't you only have to do this for numbers which start with a character at the end of the other numbers?
like six could be eaten completely
yeah probably
would just doing this for the words that end in e work
but i was too lazy to check them all
this is actually a really good optimization
and this makes finding through reverse searching much faster!
if you did it in reverse I don't think there is any opportunity for this to occur
omg i never even thought about reverse searching
i was reverse searching for the last number
but this might make it better to do it for the entire thing
and yeah it wouldnt happen if you searched like that
i forgot how long the input lines were
I love how much we learn from how other's do their work
It's incredibly how much diversity there is in approaching these
its the heart of aoc
In computer science, the Aho—Corasick algorithm is a string-searching algorithm invented by Alfred V. Aho and Margaret J. Corasick in 1975. It is a kind of dictionary-matching algorithm that locates elements of a finite set of strings (the "dictionary") within an input text. It matches all strings simultaneously. The complexity of the algorithm ...
i need to make the input 50 times longer so that theres an actual notable performance time
I solved it in Typescript with a regex using greedy and non-greedy matching. Felt pretty great getting regex so close first time 😂
regex is too declarative for me :p
conclusion: regex is a functional language
fastest solution for day one: macro that solves the input at compile time and puts it into a print /j
write your entire solution in a const fn
certainly a challenge
then just try to print to stdout as fast as possible
const PART1_SOLUTION: usize = {
todo!()
};
the issue being no heap allocation
with external libraries you can use ArrayVec and still use iterators with collection though
day 1 should be fine though
well, no
there is plenty of non const stuff apart from that
ah nvm nvm
no iterators even with that
since you can't use mutable references
no god why
this looks funny
on tw thre fou fiv si seve eigh nin te
its silly
teeen
ill make a script to like tripple the length of each line and duplicate it 50 times
to make perf differences way more visible
would be kinda fun if aoc included like extended inputs
just to test on
a lot of this depends on how the data set is generated
because if you know that most of the time the last number will be close to the end then reverse searching for it is the better route
oh true
hmm
maybe it would be fun to make my own input generator
include a bunch of different settings
mix em up
ey day 3 incomming
y'all ready?
AoC got me donating for the first time to something free
:))
so ready
wooo
I should not be awake at 6am, but i am ready nonetheless
Do not be 🔫
I am literally preparing boilerplate for the solution
Somehow getting a solution in 4 minutes
got me really pumped about being competitive
I'm forcing myself to not rush
Yesterday I could've bodged the solution together but forced myself to make it nice and clean, and I think it benefited me in part 2
I think even if I could go fast (I probably can't), I'm going to not stress
What an adrenaline rush does to a mf
yep
i already don't like today
i'll do day 3's advent tomorrow
i have a Programming Idea™️ of Questionable Complexity™️ and Possible Profitability™️ i wanna focus on
thos looks evil
I have it parsed
Now it's time for ||neighbor analysis||, yayyy /s
||The only idea I have is to enumerate a line by char, check the previous line, current, and next line at each and every char in a box ||
and the top 100 part 2 is already done jesus fucking christ
holy shit this is hard
I am waiting because I put the same input in 3 times
liek a idiot
I'm already defeated by day 3 :(
YOU WHAT?
the thing that messes with me is that numbers ||are of diff lengths||
and I totally forgot to account for that
got it
oh fuck I just did too
I had a stupid issue staring at me
now I am waiting to submit
I am on a cooldown
I will share (cw: python)
same here
||```py
class Number:
def init(self, row, start_idx, length):
self.first_col = start_idx
self.last_col = start_idx + length
self.row = row
self.coords = [(row, i) for i in range(start_idx, start_idx + length)]
def value(self):
val = ""
for row, col in self.coords:
val += G[row][col]
return int(val)
def check_bounding_box(self):
for row in range(self.row - 1, self.row + 2):
for col in range(self.first_col - 1, self.last_col + 1):
if G[row][col] not in non_symbols:
return self.value()
return 0
f = open("03.txt").read()
lines = f.splitlines()
pad = ["."] * len(lines[0])
G = [pad]
non_symbols = [str(x) for x in range(10)] + ["."]
for l in lines:
G.append(["."] + list(l) + ["."])
G.append(pad)
numbers = []
for row in range(len(G)):
col = 0
while col < len(G[row]):
if G[row][col].isnumeric():
start = col
length = 1
while G[row][col + 1].isnumeric():
length += 1
col += 1
numbers.append(Number(row, start, length))
col += 1
a_ans = sum([x.check_bounding_box() for x in numbers])
print(a_ans)
oh god that's huge
i'm getting|| that 114 sees it because 467 only counts as length 1 aaa||
part 2 looks even worse
yep it does
cursed
I'm starting to form an idea how to approach it
But :( adversity hard
I just got an epic idea
just gotta say those 4 lines must be the stupidest looking code I ever wrote

That's actually kinda genius haha
btw it doesn't
I checked
they're literally all the same
||```rs
fn main() {
let input = std::fs::read_to_string("src/input.in").unwrap();
let grid: Vec<Vec<char>> = input.lines().map(|line| line.chars().collect()).collect();
let grid_height = grid.len();
let grid_width = grid[0].len();
let is_symbol = |c: char| !c.is_digit(10) && c != '.';
let is_valid_coordinate = |row: isize, col: isize| 0 <= row && row < grid_height as isize && 0 <= col && col < grid_width as isize;
let mut sum = 0;
for row in 0..grid_height {
let mut col = 0;
while col < grid_width {
if grid[row][col].is_digit(10) {
let mut number = 0;
let start_col = col;
while col < grid_width && grid[row][col].is_digit(10) {
number = number * 10 + (grid[row][col] as u8 - b'0') as i32;
col += 1;
}
let end_col = col - 1;
let mut is_adjacent_to_symbol = false;
for k in (start_col as isize - 1)..=(end_col as isize + 1) {
for ii in (row as isize - 1)..=(row as isize + 1) {
if is_valid_coordinate(ii, k) && is_symbol(grid[ii as usize][k as usize]) {
is_adjacent_to_symbol = true;
break;
}
}
if is_adjacent_to_symbol {
break;
}
}
if is_adjacent_to_symbol {
sum += number;
}
} else {
col += 1;
}
}
}
println!("{}", sum);
}
I did it
no, like
holy shit
done
first row has 6 elems, second has 11 or so
I'm so proud of my sol
did part 2 is so easy
thank god becuase part 1 feels just out of reach
I need to add comments to my solution
I would look at y'all's if I could understand rust 😭
just git gud /j
um 👉🏻 👈🏻 I really want to solve this without cheating and looking at others, so can yall just see if I'm on the right track given my code comment explanation to myself?
Am I on the right track, no pitfalls?
whyyy
the big leap for me for part 2 was ||storing what entire part number is located at every cell, in a hashmap||
also I padded the whole grid with periods, just to avoid indexing errors
might help y'all
oh that's smart
i am regressing
almost danger number
make sure your bounding box actually includes everything
aa i'm so close suddenly
This is so much spaghetti, I don't know where I was going with it
It's in the shape of Triangle ™️
nevermind i am not close at all
even diagonally oh god
all my code for today in rust with comments
||https://github.com/sopyb/AoC/tree/main/2023/day_03||
brr
part2 took me 3 minutes to crack
while part 1 took me over half a hour because I was stupid
:)
my guess for part 2 ||theres gonna be symbols you need to ignore||
slaying
KNOW I WILL FIGHT YOU FOR #1
my idea
yeah that seems to be the "intended" approach
Go sleep
my intermediate steps are perfectly normal, thank you very much
This one has been kicking my ass 🙃
yeah it's definitely getting harder lol
Use expect :(
Just ask other participants for their inputs, then merge all of them together
why can't you index str with usize
ugh idk if i wanna do this one
I'm very close
ayyy
part 1 done
well shit
my solution for part 2 works for the sample
but not for my input
That was my situation for part 1 😂
fixed
group_by did not do what I thought it did
and despite how awful it is, still 587 micros
I can live with that
either part took me roughtly 40 minutes
woop
you can make main return an option and effectively turn ? into unwrap which is so much prettier and nicer to type/read
i think returning none/error literally just invokes the panic handler
oh nvm main can only return a result
still
A trait for implementing arbitrary return types in the main function.
weird little c traits
actually pretty cool that this isnt a hard coded rule from the standard library
genuinely super useful for embedded
Do the symbols in day 3 overlap in their part zones?
they probably do
which is such a aaaaaaaaa moment
||you mean do any two symbols share a number?||
||yes||
||it doesn't say that they can't||
||well like ofc, but just by looking at the input I can't see any overlapping numbers, just overlapping periods||
||what about the actual puzzle input?||
||that is what I was looking at||
the concrete answer is ||yes there are|| if you've given up on figuring it out
there's this in my input
overlapping periods
"periods" as in...?
.
what does it mean for them to overlap?
well they don't overlap
it's just the symbol zones only overlap in periods
not in numbers
or well that is what I'm trying to see if it is true
oh, "the overlap between symbol zones contains exclusively periods"
yes
I do not see any number that touches two symbols eitehr
I will simply carry on with what I'm doing and see if it blows up 😎
which would've probably been useful for me to know when I did my solution
same lol
there are definitely some possible solutions i ditched bc i expected that kind of overlap
oh interesting
I'm trying to do everything in a single iteration which I think would've been impossible with overlap
There's some extra complication I did in part 2 under the assumption that a number can touch multiple gears
💀
I might've misread my own input
||I decided to just overwrite numbers with periods after detecting them mainly so numbers that touch a symbol both vertically and diagonally don't get detected more than once|| (solution spoiler)
oh that's a clever way of doing it
my solutions are less clever more first thing my brain thinks of at 6 in the morning after waking up 30 minutes earlier than usual for the sole purpose of doing AoC the moment it comes out
I just wanted to explain how I did it but realized I already forgot what part 1 even was
forbidden
go eep
yeah i'm not rushing to do it the moment it comes out, and i don't wake up until an hour and a half afterwards anyway once i do wake up it's the first thing i do lol
idk what that circle is gonna be
it was a tradition that I started in 2021 during lockdown becuase at the time I woke up at 6 anyway and I would have 2 hours until school started
though I limited myself to 1 hour before I would have to take a break from it and do my morning routine
I'm having trouble avoiding duplicates
I might yield and look at someone else's solution
look at mine
I did
I obtained no information for it 🥲
it may not be directly applicable to rust but at least it's got some fucked up unicode!
I might be approaching it wrong
I tried two approaches but they both seem bad
I can't think of anything else, though
what approaches did you try?
||- Paring the schematics into a sort of AST (but not really) and looking at that when I find a symbol||
||- Looking at the chars directly and if a digit neighbours a symbol, walk backwards to recover the full number||
why did that second one not work out?
should i explain my general approach?
Please do /gen
||i take the grid and extract out a list of all the numbers in order, then create a new grid where each digit of each number is replaced by the index of said number in the list. after that i just look at all the cells next to a symbol and use the values there to look up the number in the table||
there's a bit of extra logic to avoid ||having issues with duplicates, but that's the gist of it||
I'm struggling with ||duplicates||
Like
||Both 3 and 5 see the symbol, so both 3 and 35 are pushed||
Do I just ||check if the next one isn't a digit?||
||That seems to obvious now that I've thought of it||
oh those kinds of ||duplicates||
||And only the 6 and 3 see the input, so I get [6, 63] but not 633||
aa
hm yeah idk how i'd handle ||those kinds of duplicates|| tbh
i mean it's out
wait it's out already?
yes
i'm just looking forward to the day 3 low level learning video lol
Internet historian posted 7h ago, whoops
For the learning? [Nah]
To see them use a cursed language like php? [Ofc]
waiting for chat to add haskell to the wheel lol
yess
I should pick up Haskell
It think it's easier than uiua, tbf
Someone should put uiua on the wheel
yessss
honestly the worst part of haskell imo is the precedence rules
i struggle to parse it so badly lol
All I remember from those is the $, and I remember thinking it was really smart
it is, yeah
What's weird about the rules?
the fact that there is juxtaposition for function application as well as infix operators just throws me off when i try to parse the order of operations
Right, right
I dislike the concept of infix operators in general in a function-driven language
I think how Lisp does it is the best way (just, not having any)
I wonder how much non-array based languages could take from uiua
i'm not really sure, it feels like most of its features would be significantly more obstructive elsewhere
despite my annoyances with infix operaators, uiua has me trying to learn apl now lol
You should make a thread with your findings
I'm curious, but kind of defeated after uiua kicked my ass
idk if i'll make a thread, but i'll keep you updated somehow lol
quack
It's out, but it uses for loops, which is what I was trying to avoid
"Ive got a refactor video coming later today too showing a much different approach", he says, so I'll wait for that
ok can someone please explain to me why doing include_str!("filename.txt").split("\n") to get all the lines individually always gives me an empty string "" as the last element?
the input file has a trailing newline iirc
fishing pond
We're on a cloud and turning on a snow machine
I am just resorting to this :( ```rust
let mut rows = input.split("\n").collect::<Vec<&str>>();
rows.truncate(rows.len() - 1);
rows.pop()
Some editors might ignore ending last lines
But also, don't split by \n, that won't work with windows (crlf) files
can't this easily be fixed by using .lines()
this is better ty
Use .lines
yes it can thank you
Also have you tried printing the last character of the string to see if it's a newline or a symbol?
not yet
seems like it's something to do with the include_str! macro because last year i was doing this
let calories_string = fs::read_to_string("input_valid").expect("Unable to read the file");
let calories_vec = calories_string.split("\n").collect::<Vec<&str>>();
and that was working fine
?????
use a different editor ¯_(ツ)_/¯
neovim screwing me over wtf
ok well regardless, I'm just gonna use .lines() from now on
ty for the help everyone
sorry nvim screwed me
it is so over
what is that
my sum for the test sample
part 1 or 2
part 1
oh well no like
i was well undershooting the actual number
that would be hilarious though
this is what trying to do this in a single iteration does to a mfer
god damn
mine was so ugly lol
i am rewriting the whole thing baso for part 2 because
it's easier than adapting what i've done for part 1
xd
progress
forward movement!
progress 2: actual progress
success!
this will not go well for the actual data set
it did not go well
I'm going to need to steal someone elses solution I cannot wait a minute to see if my answer is incorrect
this is honestly the worst part of AOC
cmonnn
Simply wait faster smh my head
xd
well they need some way to stop you from just doing a binary search on possible inputs and just winning that way
yeah someone would figure that out in like 5 mins lmfao
change the input on every submission
easy fix
"oop, you got it wrong, redownload your input data"
me: OMG I FOUND THE ERROR
me when I realize 99+391=490
hahahahah
that's high-key annoying though
would scare off lots of new people also
could someone run this input on their part 1 and tell me if it is lower or higher then 524608
AOC is refusing to tell me, idk why
i got higher
a lot higher or a tiny bit
it started 53
oml that's 10K unaccounted for
which is too little
I am basically searching for the error in the haystack rn
YES
YESSSS
hahahaha
IT HAS BEEN FOUND
: (
I am currently getting 530662
do you want to know which direction that is from when i ran it?
sure
you are still short
also would make submission even more costly server-side
yeah
way too much
FINALLY
congration
it was code to deal with skipping already processed numbers
:3
congrats!
i just got part 2 in which took me a whole extra 2 & 1/2 hours after getting part 1 in lol
this is art
I honestly am surprised I successfully did it in one iteration of the entire string
I expect my idea to do very well if I parallelize the search
I'm full of chili, baguette, and tea
feasting like a queen
delightful
gAsp
WOO
eats it
ofc you do not, for it was eaten
Is 536667 around the right order of magnitude?
I'm probably missing one or two values
I... I guess I'll check against the input manually
sigh
The first twenty look correct
fml
can someone run it with my input and tell me which value i'm missing
I can't :3
I am out of ideas otherwise
My algorithm came out very neat, I don't see anything wrong
:0
That shouldn't matter, the 9 is seeing it
:(
just throwing a random guess out
I investigate
it's still missing in your output
also check for this 448 maybe
there appears to be 3 numbers at the end of lines
maybe manually add those to your previous result and see if it's correct? :p
I recommend excessive print debugging if line_idx == {whatever line that 982 is on}
😎
:o
the input, uh, doubled
that does not seem correct
Yipee!
I was forgetting to add numbers not followed by a symbol, and newlines don't count
I'm still missing P2
I'm firmly in 5th place
honestly don't blame yourself i spent like 6 hours on today's one lmfao
P2 should be pretty relaxed with how I structured P1
No comparing placements allowed >:(
:3
that's fair but I get discouraged sooo fast 😭
adhd is a curse
I took 40 minutes and probably could've spent another 8 hours without managing to make it actually look good lol
just checked all my scores and i'm glad to now be above half in the three private leaderboards of which i'm a member
the dropoff is really steep this year omg
wait what's that view?
oh damn
or just initial bias
also consider that that has a whole extra year of people doing stuff
as more people do 2023 it will go up
ah yeah that's true it stays open all year doesn't it
it stays open permanently
ah, nevermind, i read it the wrong way around
fml
idk how long they count stats for
star count is just forever
what's your source code
you got me beat by four orders of magnitude
there's something about my parsing code that the uiua interpreter really doesn't like, performance-wise
i think it might have something to do with your code being entirely incomprehensible to me
lol really?
yes
go through each line, find every number, go through all the neighboring symbols of that number
check if any of them is a not-.
hmmm
sum up all the numbers where it does
right
so this sort of comes down to how I initially thought we were using digits and not like multi digit numbers
I looked at the input to check what the smallest data type I could use was, and saw numbers from like 8 to 800
70% of all AoC errors are caused by not reading the full instructions
25% are by stuff not said explicitly in the instructions
the rest is rounding errors /j
ok so I was busy this weekend but I finally have time to do AoC
here's my solution to day1 part 2 uwu
const INPUT: &'static str = include_str!("../input/1");
pub fn part2() {
let rez = INPUT.lines()
.map(|line|{
let mut digits = Digits::new(line);
let first = digits.next().unwrap();
let last = digits.last().unwrap_or(first);
first*10+last
})
.sum::<u32>();
println!("{rez}");
}
(of course I had to implement an iterator)
||```rust
struct Digits<'a> {
input: &'a str,
chars: CharIndices<'a>,
}
impl<'a> Digits<'a> {
pub fn new(input: &'a str)->Self {
Digits {
input,
chars: input.char_indices(),
}
}
}
impl<'a> Iterator for Digits<'a> {
type Item = u32;
fn next(&mut self) -> Option<Self::Item> {
const WORDS: &[(&str, u32)] = &[
("one",1),("two",2),("three",3),("four",4),("five",5),("six",6),("seven",7),("eight",8),("nine",9),
];
while let Some((i,c)) = self.chars.next() {
if let Some(d) = c.to_digit(10) {
return Some(d);
}
for (word, d) in WORDS {
if self.input[i..].starts_with(word) {
return Some(*d);
}
}
}
None
}
}
I mean I don't think it's very succinct but it's definitely fancy
okay turns out there was a three-character change that improved my runtime by around 30x lol
replacing ||⊐≡(↯⧻)|| with ||≡(□↯⧻⊔)|| (in a vague sense, this is like manually de/referencing instead of telling the interpreter "just figure it out")
also lighting fast! it doesn't allocate any memory
even tho I am running this as an EUFI application I do have an allocator set up so it's not neccesary... but it's neat :p
Oh yeah I forgot you're doing no_std no_main. Awesome work
Did the things I sent help any?
yee
setting everything up was surprisingly easy
#![no_main]
#![no_std]
extern crate alloc;
use uefi::prelude::*;
#[entry]
fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
uefi_services::init(&mut system_table).unwrap();
system_table.stdout().clear().unwrap();
// ...
// wait for end
let event = system_table.stdin().wait_for_key_event().unwrap();
let _ = system_table.boot_services().wait_for_event(&mut [event]);
Status::SUCCESS
}
yay
I imagine this would be suuuch a pain in C++
what do no_std and no_main do?
I did it! :D
Now I'm looking at the lints and I am confused
From Day 2: "id" is never constructed"
But... but it is
no standard library (std, but core is still available)
no compiler provided entry point
:LspRestart
sounds like masochism to me :)
it's like a no belts factorio playthrough
Nope, still there after :CocRestart
heh, coc
(cargo check also shows it)
huh
gonna make an lsp client called pen-15
yes
look ma, hard coded variables!
What is a program if not a hard coded megavariable
honestly
what are you, a haskell user?
mostly because I forget how to find how many index numbers a vec contains and I'm too lazy and stubborn to look it up when I can see the txt is 140 lines
Like, input.len()?
that's fair
this is like the biggest thing i've learned from aoc lol
if in doubt, .clone()
unwrap less so because it's like i want my code to still run even in the edge cases
Amen
The best thing about rust is my worst algorithm is as fast as the fastest javascript, or python, or java...
and won't cause nasal demons like C
me rn
I'll let myself have code duplication, as a treat
parsing for day 2
||```rust
fn parse() -> impl Iterator<Item=impl Iterator<Item=Rgb>> {
INPUT.lines()
.map(|line| {
let matches = line.split_once(": ").unwrap().1
.split("; ");
matches.map(|m| {
m.split(", ").fold((0,0,0), |rgb, pair| {
let (number, color) = pair.split_once(' ').unwrap();
let number = number.parse::<u32>().unwrap();
match color {
"red" => (number, rgb.1, rgb.2),
"green" => (rgb.0, number, rgb.2),
"blue" => (rgb.0, rgb.1, number),
_ => unreachable!(),
}
})
})
})
}
yep, no memory allocated UWU
for day 3 ||it was a major mistake to have 3 rolling lines and find *s of the center line and then detect and parse the surrounding numbers instead of first collecting a list of numbers and symbols with their coordinates and then checking which of them are close enough to each other...|| but at least I got exercise for fucking around with string slices
i did it that way and it was surprisingly pain free somehow
||```rust
fn collect_number(x: usize, y: usize, grid: &Vec<Vec<char>>) -> Option<i32> {
let max_len = grid[0].len() - 1;
let mut num_string: String = "".to_string();
let mut building_forwards = true;
let mut building_backwards = true;
// Put the first one in!
if grid[y][x].is_numeric() {
num_string.push(grid[y][x]);
} else {
return None;
}
if let Some(row) = grid.get(y) {
let mut i = 1;
loop {
if building_backwards {
if (x as i32 - i as i32) < 0 {
building_backwards = false;
} else {
let prev_char = row[x - i];
if prev_char.is_numeric() {
num_string.insert(0, prev_char);
} else {
building_backwards = false;
}
}
}
if building_forwards {
if (x as i32 + i as i32) > max_len as i32 {
building_forwards = false;
} else {
let next_char = row[x + i];
if next_char.is_numeric() {
num_string.push(next_char);
} else {
building_forwards = false;
}
}
}
if !building_backwards & !building_forwards {
break;
}
i += 1;
}
}
return Some(num_string.parse::<i32>().unwrap());
}
fn get_neighbours(x: usize, y: usize, grid: &Vec<Vec<char>>) -> [Option<&char>; 8] {
// Given an x & y, return an array of 8 items containing the neighbours.
// Example 1
// Input: 1 2 3
// 4 x 5
// 6 7 8
// get_neighbours(1, 1): [Some(1), Some(2), Some(3), Some(4), Some(5), Some(6), Some(7), Some(8)]
//
// Example 2
// Input: x 1
// 2 3
// get_neighbours(0, 0): [None, None, None, None, Some(1), None, Some(2), Some(3)]
//
// Example 3
// Input: 1 2
// 3 x
// get_neighbours(1, 1): [Some(1), Some(2), None, Some(3), None, None, None, None]
let height = grid.len();
let width = grid[0].len();
let mut neighbours: [Option<&char>; 8] = [None; 8];
let top_y = y as i32 - 1;
let bot_y = y as i32 + 1;
let top_x = x as i32 - 1;
let bot_x = x as i32 + 1;
// top row
if top_y >= 0 {
if let Some(top_row) = grid.get(y - 1) {
if top_x >= 0 {
neighbours[0] = top_row.get(x - 1);
}
neighbours[1] = top_row.get(x);
if bot_x as usize <= width {
neighbours[2] = top_row.get(x + 1);
}
}
}
// middle row
if let Some(mid_row) = grid.get(y) {
if top_x >= 0 {
neighbours[3] = mid_row.get(x - 1);
}
if bot_x as usize <= width {
neighbours[4] = mid_row.get(x + 1);
}
}
// bottom_row
if bot_y as usize <= height {
if let Some(bot_row) = grid.get(y + 1) {
if top_x >= 0 {
neighbours[5] = bot_row.get(x - 1);
}
neighbours[6] = bot_row.get(x);
if bot_x as usize <= width {
neighbours[7] = bot_row.get(x + 1);
}
}
}
return neighbours;
}
@fickle hornet (and @quiet frigate ) ^
that's the bulk of my solution, the rest is just processing and feeding data from get_neighbours() to collect_numbers()
Nice! I'm currently at a bookstore to avoid hurting my brain further lmao
I'm probably making the problem harder on myself but I don't want to cheat
wdym by cheat?
Looking at other solutions
ah right fair enough
yeah obvs no pressure to look just sent it bc you liked my one from yday (ty btw :) )
♥️
yeah it was really good once you get it but it was a bit of a pain to get there
at least this is making me good at string parsing lmao
i do wonder how far i can get
especially because i have a VERY busy week next week lmao
I’m going to be traveling home for the holidays so we’ll see
aoc on the plane (train? (boat??))
Hovercraft, obviously
the latest I got was 8 last time but that's because I never knew about AOC earlier
yeah fortunately aoc will probably work with on-board wifi, all you’re really doing is entering numbers
Automobiles?
we do not stan
oh wait my idea may not work
iterators only have a .next and not a previous... does it?
more cloning to the rescue I guess
you could potentially use .peek() to get the next value, if you can refactor your code to do so
A trait for dealing with iterators.
Oh that's nice for my look at next line part
|| my original plan was to go back a line, and look up left and right. But that seems a bit harder than expected. Looking down left and right is definitely fine though||
Ah that is actually perfect for my usecase, at least for the look ahead
okay I give up
Same happened to me in the morning
I switched approach entirely and it came out decently well
i brute forced mine by taking a break, eating spaghetti, and spending some hours doing it
In order to decrease the amount of spaghetti (code), you must first eat the spaghetti
- Toby (probably)
rethinking approaches would've probably been a good idea since my initial mental model when I came up with what I was going to do was wrong and I didn't readjust it
