What are you coding?

I am somewhat proud of my parser thingy for today’s input. Particularly this part:

depth = depth + child.chars().map( c -> c=='[' ? 1 : (c==']' ? -1 : 0)).reduce( 0,Integer::sum );

Part 1: It took me just 2 attempts and a rewrite

of the main compare function to get it right:

private int compareContents( List<PacketContent> otherContents){
            LinkedList<PacketContent> otherStack = new LinkedList<>( otherContents );
            LinkedList<PacketContent> stack = new LinkedList<>(this.contents);
            while(!otherStack.isEmpty()&&!stack.isEmpty()){ 
                PacketContent content = stack.pop();
                PacketContent otherContent = otherStack.pop();
                int result = content.compareTo( otherContent );
                if(result!=0) {
                    return result;
                }
            }
            return Integer.compare( stack.size(), otherStack.size() );
        }

In Part 2 News:

image

It took me almost 5 minutes to debug that.

3 Likes
Day 13

Normally I like to have very little reliance on libraries. But today I just couldn’t be bothered to parse the brackets, so I converted them into nested (as necessary) lists by way of json.loads() from the Python3 standard libraries.

I wrote my Part 1 comparison, initially as a __le__() magic method, but ended up calling it separately so that I could include parameters if needed to enable debug output.

So for Part 2, I just removed my class PacketPairs, threw all of the packets into a list in my class PacketDecoder and used Python magic methods for the rest:

class PacketDecoder:
    def __init__(self, packet_data):
        self.packets = list()
        for line in packet_data:
            if line:
                self.packets.append(Packet(line))
        self.sort()

    def sort(self):
        self.packets = sorted(self.packets)

    def index_of(self, packet):
        return self.packets.index(packet) + 1
2 Likes

My first attempt failed badly I admit… but then I remembered taking “Compiler Construction” at uni and I do enjoy this kind of stuff.

Day 13 Parser
Matcher packetMatcher = Pattern.compile( "\\[(.*)\\]" ).matcher( packetString );
Matcher numberMatcher = Pattern.compile("(\\d+)").matcher( packetString );
if(packetString.equals( "[]" )){
       //do nothing
} else if(packetMatcher.matches()){
      String[] children = packetMatcher.group(1).split( "," );
      int depth = 0;
      StringBuilder childPacketString = new StringBuilder();
      for ( String child : children )  {
             depth = depth + child.chars().map( c -> c=='[' ? 1 : (c==']' ? -1 : 0)).reduce( 0,Integer::sum );
              childPacketString.append( ( childPacketString.length() == 0 ) ? "" : "," ).append( child );
              if ( depth == 0 ) {
                  contents.add( new PacketContent( childPacketString.toString() ) );
                   childPacketString = new StringBuilder();
               }
      }
} else if(numberMatcher.find()){
     value = Integer.parseInt( numberMatcher.group(1) );
}

I also wrote an “unparser” aka prettyPrinter and used BeyondCompare to verify that I had indeed reproduced the entire thing correctly :slight_smile:

Ouchy.

3 Likes

My nephew (12 years old, maybe?) sent me his Christmas wishlist, which contains a T48 programmer, a Linux kernel programming book, Stroustrup’s C++ book (:face_vomiting:) and K&R’s C Programming Language book.

He’s getting K&R C for Christmas, and I cannot be prouder of my nephew than I am right now.

5 Likes

I too couldn’t be arsed with the parsing but I got there a different way using ast.literal_eval(x). I did wonder if you could do it your way as well.

I didn’t go OO this time which did make the part 2 a bit tricky as apparently Python doesn’t allow you to pass custom comparison functions into sorted or sort without a bit of extra work.

My final function was probably a bit more verbose than it needed to be but I’ll take readability/understandability at this point.

3 Likes

I think I still have an ancient Borland C (or C++?) book that my uncle gave to me when I was a youngster looking at getting into coding.

1 Like
A meme for Day 13

I just browsed the subreddit for the first time and had to laugh outloud at this. I am obviously the dimmest one … funny thing is I was working with a stupid json file for work the last few days and never realized this was that format)

3 Likes

I just went back (and stepped down a tier?) by creating a generic parser for nested lists of integers.

At some point, when AoC presents the opportunity, I may add '' and "" encoded string support. But at that point, I might as well just stick with json.loads().

I did go back and return to AoC 2021 because I remember seeing nested lists of ints when solving snails’ homework. I cannot read my code from 2021.

3 Likes

Day 14: I have a worrying feeling that I’m getting better at doing string parsing in PostScript.

The fiddliness of multidimensional arrays/hashes does lead me to convert coordinates to x * n + y where n is larger than any possible y.

2 Likes

Day 14: After fiddling around with my helper classes--I’ve caved and made both a Matrix and Coordinates classes–I have now visualized the initial input. Oh that looks fun. Now for the actual puzzle.

3 Likes

Day 14 took far too long to solve. Also at some point of part 2 it was impossible to visualize further.
I spent quite some time today cleaning up my Matrix / Coordinate manipulation classes because I was getting sick of java’s arrays of arrays… messing with me..

Who knew how difficult it might be to find the right exit strategy from a loop?

Anyway, I cheated for part 1
while(true) {
            try {
                //begin a new grain
                Coordinates last = null;
                Coordinates currentGrain = move( new Coordinates( 500, 0, SOURCE ), cave );
                while ( currentGrain != null )
                {
                    last = currentGrain;
                    currentGrain = move( currentGrain, cave );
                }
                if(last==null){
                    break;
                }
                cave.setValue( last );
            } catch (ArrayIndexOutOfBoundsException e){ //cheating but who cares
                break;
            }
}

I had a ton of difficulty determining when to get out of the loop without eliminating legal moves
The last==null is the exit for part 2. Also I remember complaining about starting to count at 1… the offsets today were maddening.

3 Likes

Saw something puzzling me: people writing the code in python complained it took 10 minutes to complete a solution? Is python really that slow?

When I don’t mess up by writing infinite loops or multiplying very large integers, my solutions usually finish in no time at all (I could measure if anyone wants to know, but at the very longest it is seconds and I don’t optimize)

2 Likes

Python is generally rather faster than PostScript under GhostScript, and my day 4 part 2 takes about 3.7 seconds here. (And I didn’t use any of the short-cuts - my code simulates each particle individually.) There may be some perverse corner case that’s being tickled, but…

2 Likes

Maybe I misunderstood and it was just people who were doing visualizations of yesterdays puzzle who took some time to get those done…

Day 15: did you know PostScript arrays and dicts are traditionally
limited to 65,536 entries?

GhostScript is not quite that limited, but still can’t stretch to the full span, so I ended up writing an interval collapser. Even then part 2 takes A While to run (six and a half minutes on my test machine, three and a half on the shiniest newest box I have). As a Finnish car mechanic once said, “it’s not pretty, but it’ll get you home”.

3 Likes

I think for the hill climbing the other day I probably spent more time making the animation than I did on the exercise itself.

I’m a couple of days behind but I just finished work for the year so hoping to catch up tomorrow.

2 Likes

For Day15 part 1 I am trying to do without an actual array. Coordinates are too large. My plan is to calculate the 2 points on the line in question that are the maxium distance, for each sensor and then collect all the points in between. make sure no beacons are in the set and all points are unique and count. I am almost there–my first attempt had the mistaken assumption about there being a radius involved.

edit: And there was a comment on my code saying “maybe radius needs +1” which was the only mistake I made this round. Now on to part 2.

2 Likes

Meh. OutOfHeapSpace.
And for the first time I felt compelled to time my calculations and it suggested that my solution is not good enough. Meh. I think I need to recycle some code from day … 4 .

Sadly, my python solution for Day 14 part 2 is still running after an hour or two. Why, you ask? Because I like robust simulations and I don’t optimize a solution until it needs it.

And instead of trying to optimize it, I just wrote an alternate approach, which took about half a second to run.

./day14_2a.py input.txt 0.44s user 0.03s system 89% cpu 0.522 total

Day 14 Part 2

Rather than simulating each piece of sand, I just calculated the which (x,y) coordinates would be expected without any obstructions, and then analyzed each space within that pyramid to see if all of the 3 spaces above it would be unable to be filled.

It makes me sad to have to do things the analytical way.

I’m a little behind after not feeling too good yesterday… so I’m not sure if I’m going to tackle Day 15 yet or not.

EDIT: just checked, it’s been running for almost 3.5 hours

EDIT 2: it finished after roughly 4 hours and 8 minutes with the correct answer

3 Likes

Actually, it makes me sad that I am not always able to see the math to do this. I very much admire your second approach.

2 Likes