polettix / ETOOBUSY

GitHub Pages with Jekyll for the impatient
https://github.polettix.it/ETOOBUSY/
Other
6 stars 1 forks source link

Clarification on PWC 209 Task 2 #28

Closed oldtechaa closed 1 year ago

oldtechaa commented 1 year ago

Hi Flavio,

Could I get some clarification on Task 2 for PWC 209 please?

while (++$cursor < $all_groups->$#*) {
            next if defined($all_groups->[$cursor]);
            $all_groups->[$marker++] = $all_groups->[$cursor];
         }
         splice $all_groups->@*, $marker if $marker < $all_groups->@*;

This block is confusing me a little bit because I understand you're counting upwards and looking for elements (or name/address entries) that are now undef after the previous segment where you clear them. But it seems like $all_groups->[$marker++] = $all_groups->[$cursor]; is deleting data that still exists by copying from an undef location. Could you explain how it's working? I would expect to be copying data to an undef location lower in the list and then deleting the later location. Also, how would $marker ever reach more than $all_groups->@* which is limited by all_groups->$#*?

polettix commented 1 year ago

Hi! Thanks for your question, it's much appreciated because... it points out a mess 😅

It's now (and should have been at the time):

$all_groups->[$marker++] = $all_groups->[$cursor]
  if defined($all_groups->[$cursor]);

The check on the $marker's value is also unneeded as you point out, but that makes more sense to me because it's a sort of "defensive coding" approach. But anyway yes, it's totally unnecessary here. (Observation: the test does not really check if it reaches more, but equal instead. Again, using < instead of == ...->$#* is more defensive so it's my usual approach. Which it can't anyway due to how the while condition does not allow $cursor to check for the last element, which will always be undef anyway).

oldtechaa commented 1 year ago

Alright, that makes a lot more sense, thank you! I guess my thought was that with skipping the loop every time data was found later, $cursor and $marker would quickly diverge in value, so $marker would end up being very far away from $cursor, which already wouldn't reach the end of the array.

Anyways, great work and your solutions to 208 and (especially) 209 task 1 have been very efficient clean implementations. I've been looking very closely at your solutions to see where I need to improve on mine. I took so long figuring out everyone else's solutions to 208 that I didn't get to write 209 solutions myself.

P.S. I didn't test the old code, but the new code prints out A, then B, then A again, which isn't exactly the ordering in the example.

polettix commented 1 year ago

Regarding the solution to 209/1, I'd suggest that you take a look at this - I guess it's the most efficient around as it has the potential to stop very early (my solution has to always go through the whole string). As a matter of fact, it's only not efficient if it's all 1s followed by a single 0.

Regarding the new code in my solution for 209/2, the output is actually the same as before and it's correct according to my goals (you find them in the blog post). At least I hopeso.

The input in the example is the following (NOTE: different from the challenge, and I added comments with numbers):

my @accounts = (
   ['A', 'a1@a.com', 'a2@a.com'],  # 1
   ['B', 'b1@b.com'],              # 2
   ['A', 'a3@a.com', 'a4@a.com'],  # 3
   ['B', 'b2@b.com', 'b1@b.com'],  # 4
   ['A', 'a8@a.com'],              # 5
   ['A', 'a3@a.com', 'a2@a.com'],  # 6
);

In the Perl solution, my goal was to be "stable", i.e. make output items appear in the same order as they appear in the input for what is possible. In this case, groups 1, 3, and 6 merge into 1, groups 2 and 4 merge into 2, group 5 remains intact. As a result, the output is A (1<- 1U3U6), B(2<- 2U4), A(3<- 5).

I know, I know.

oldtechaa commented 1 year ago

All makes sense. And yes, I guess E. Choroba's solution does make it very efficient, although the regex is probably the simplest way to do it and not particularly efficient. One of those tradeoffs, I guess. Anyway, I'm on to my 210 solutions. Thanks!