#My AOC23 Day 1 solution, what can I do better?

57 messages · Page 1 of 1 (latest)

tribal stratus
late yacht
#

Oooff.... A lot of things

tribal stratus
#

I guess vectors are involved

late yacht
#

There are very many things that are rather bad with the code. I'll get back home in 20 minutes, make myself some tea and get back to you

tribal stratus
#

appreciate that

tepid hemlock
#

the code is more like C than C++

#

you're using fixed length arrays, when a vector would be far less error prone

#

same for char buffers vs. std::string

#

extractDigits is returning a size and writes into a pointer, but it could just return the vector

late yacht
#

First of all, you should not use char* in C++. We have better tools to deal with text - not much, but still

#

However, even if you want to try and use char*, you're using it in an extremely inefficient way, without actually using the standard library

#

Your function strfind has many issues.

Parameter n is unused, so it always looks for the first occurrence.

Using a separate buffer to compare the strings is very inefficient, especially since you are sitting it left all the time - it's simply bad. Instead use pointer arithmetic to just move one pointer to the next character, and then strncmp here, but...

Even if you use const char*, there is a function for searching for a string in a string. It's called strstr

#

It will return a pointer to the first found occurrence. If you need the position, subtract the pointers

#

Don't use ASCII codes, use char literals to convey meaning:

c >= '0' && c <= '9'

#

I'd recommend using std::print (if you use MSVC) or at least cout instead of printf

late yacht
#

Your control sum is boolean in nature, no point of it being an integer

#

Your while loop should be likely a for loop, counting the loops as you already do, and then as condition for continuation use the flag you'd have instead of control_sum

#

In your function extract digits you already construct a vector, only to copy it to some fixed size buffer - why not just return the vector and be happy?

#

One you do all these changes, use std:: during instead of char* you will be able to use range for loop instead of the most of your loops

tribal stratus
tribal stratus
tribal stratus
#

thank you for details answers

tepid hemlock
tribal stratus
tepid hemlock
#

yeah, so, if you just return the vector, there won't even be a copy i think

#

because of named return value optimization

tribal stratus
#

but isn't returning vector actually returning a pointer to it?

late yacht
#

Nope, that's the thing: std::strings, std::vectors, std::array and friends are ~containers~, they behave like proper objects. Returning them returns their content. Also, it is usually extremely fast. Best case - it's free, the compiler already created the object where it had to end up. Worst case - it's super cheap, as the ownership of the allocated buffer is just "move"d out of the function

tribal stratus
#

holy moly tham makes a lot of sense

#

smarter everyday :D

tepid hemlock
#

c++ has value semantics so if you return a value, it's a value, and if you return a pointer, it's a pointer

tribal stratus
#

I am gonna apply your tips

tribal stratus
#

Ownership exists indeed, addresses are the same :O

tribal stratus
#

I refactored the day 1, so it uses string utilities and map

late yacht
#

That's a very common optimization, but not always the case - you sometimes can have transfer of ownership, but the object is in a different place

#

You can check the address returned by .data(), so where string data is actually stored

#

However, strings are rather special as they use something called Small Buffer Optimization

#

So, quick intro into how strings work (kinda):

namespace std {

class string {
    union{ 
        char sbo_buffer[16];
        struct {
            char* end;
            char* storage_end;
        };
    };
    char* begin;
}

So... it's rather complicated, despite being simplified. The idea is, that allocating memory (with new) is a relatively expensive operation, that we would like to avoid. So for strings of small length (in the example above: 15 or smaller) will be stored "within the string", and bigger: will have memory allocated and stored in begin

tribal stratus
#

How do end and storage_end pointers occupy the same space as sbo_buffer?

#

this is what I understand when I see unions in action

late yacht
#

They do occupy the same space - it is kind of interpreted differently, depending on the content of begin - if begin points into the beginning of the string object, it knows it uses SBO

#

Kind of - it's not exactly like that, but that's the main idea

tribal stratus
#

I'll probably touch this in the future, I focus on exploring optimal ways of programming

#

About two months ago there was a programming contest in my area that would let you easily join any college, but it was heavily about things in which not any way of achieving a goal is the right way, they love to use fibonacci numbers to test your knowledge of algorithm optimization (because usually the first version is very ineficcient)

tepid hemlock
#

yeah, there's much more to algorithms than just that 😅 but it is a good start

tribal stratus
#

this is all fun and games until you do not have any optimization tricks left and the game still runs very slow

tepid hemlock
#

then you just have to think more wesmart

#

terrain generation can be really really difficult tho

#

in general any sort of spatial stuff is hard, in my experience

tribal stratus
#

actually yes, normally when you have a 2D camera it is not that complicated to for example hide when something is not visible, when you have additional third dimension, you have to do more calculations and invent new ways

#

it was probably called "oclussion culling"

tepid hemlock
#

yeah