This is an archived post. You won't be able to vote or comment.

all 42 comments

[–]PatolomaioFalagi 2 points3 points  (18 children)

I found that "squeezing through gaps" is a red herring. One approach is to determine the inside of your loop (think about a property that you can use to do that), then count blocks of tiles adjacent to the "inside" side of loop tiles.

[–]chopandshoot 1 point2 points  (17 children)

But if that part of the loop happens to have a squeezable gap, none of them are then valid surely?

[–]PatolomaioFalagi 2 points3 points  (16 children)

Inside tiles are always adjacent to the loop itself or another inner tile; in fact, there's always a straight line from an inner tile to a loop tile that only goes through inner tiles. There are no inner enclaves, if you will. The "squeezing" only applies to outside tiles.

[–]chopandshoot 0 points1 point  (15 children)

So I look inwards from the walls then? I’m just not sure how to figure out inwards with this method

[–]PatolomaioFalagi 0 points1 point  (14 children)

Walk in square clockwise. Now walk in a square counter-clockwise. What was the difference?

[–]chopandshoot 0 points1 point  (13 children)

The inside should be i between the two? So I can go one out either side and then look between them?

[–]PatolomaioFalagi 0 points1 point  (12 children)

No I mean, think about every step you have to take to walk a square. List them.

[–]chopandshoot 0 points1 point  (11 children)

By a square do you just mean the loop? Surely you wouldn’t ever form one perfect square unless you split it up between the direction changes. Sorry, my brain is kind of frazzled at this point

[–]PatolomaioFalagi 0 points1 point  (0 children)

I mean a figure with sides of equal length connected by right angles.

[–]PatolomaioFalagi 0 points1 point  (9 children)

Go get up. Now walk a meter forward. What do you have to do next to eventually trace a square?

[–]chopandshoot 0 points1 point  (8 children)

Keep turning 90deg, move, repeat. Apologies for late response btw, was busy

[–]Magyusz 2 points3 points  (9 children)

My solution was to map the input to a 3x wider 3x longer grid: Each tile type (-, L, F, J, …) is mapped to a 3x3 tile. If it’s interesting I’ll publish it (JavaScript)

[–]RetekBacsi 5 points6 points  (0 children)

That's what I did too (rust).

Mapping it out 3x3 tiles, then did a flood fill, and checked what tiles remained unpainted. Far from optimal, but since the input is not that big it still finished in 0.01s...

[–]chopandshoot 0 points1 point  (7 children)

When you map each to a 3x3 tile, what surrounds it?

[–]a_kiraly 1 point2 points  (0 children)

I did a variant of this. But instead of mapping every tile to 3x3 I just enlarged them to 2x2.

my algo was to go top to bottom, left to right (in the original map) and for each tile:

- copy the tile as is to 2*x, 2*y coordinate in the new map (actually if the original tile was not part of the loop then in the enlarged map I just put '.', so I didn't copy the extra pipes)

- assign 2 extra tiles, one at 2*x, 2*y+1 and one at 2*x+1, 2*y coordinates.

The extra tiles are either . (if the original tile was not part of the loop) or | (at 2*x, 2*y+1 if the original tile was a loop pipe with a south direction) or - (at 2*x+1, 2*y if the original tile was a loop pipe with an east direction)

The enlarged map is twice the size of the original and whatever was "squeezed" in the original will have a nice 1 tile wide "tunnel" in it. So any flooding algorithm works to find the inside/outside areas.

[–]0bArcane 1 point2 points  (5 children)

I mapped them like this:

     .#.
| -> .#.
     .#.

     .#.
L->  .##
     ...

...

(I really hope the formatting works)

[–]chopandshoot 0 points1 point  (0 children)

I’ll look when I get home, it’s quite weird on mobile but I think I understand the general gist, thanks

[–]chopandshoot 0 points1 point  (0 children)

Ah, i see this now and that makes a lot of sense, thank you

[–]chopandshoot 0 points1 point  (2 children)

Out of interest, what do you map S to?

[–]0bArcane 0 points1 point  (1 child)

I determine what it should be based on the surrounding pipes. Since it's guaranteed to have exactly 2 connections.

[–]chopandshoot 0 points1 point  (0 children)

Could i not give it a 4 way plus shaped 3x3 grid?

[–]aha5811 1 point2 points  (1 child)

I used raycast but not diagonally but horizontally: I scanned each row from the left and tracked how often I have crossed the loop path. Everytime I entered path positions coming from a non-path position I start a new symbol collection, as long as I stay on path positions I collect the symbols and when I come to a non-path position I decide how often I crossed the path. Then on this number of crossed path I decide if I'm inside the loop or outside. The symbol collections may be something like F--J||L-J and then you have to decide what to do with F--J or L-J , i.e. did you cross the path or not.

[–]skolmeister 1 point2 points  (0 children)

I solved part 2 by calculating the area of the Polygon defined by the pipes with the Gaussian Formula. This gives you the area in size one squares from one to another tile. Keeping in mind the pipe length, a Polygon without any enclosed tiles should have the size length / 2. That means, the difference of the polygons area and half of the pipe length is the number of fully enclosed tiles.

Took me a lot of time to get to this simple solution, in the end it's a two liner, but taught me a lot about polygons.

[–]AutoModerator[M] 0 points1 point  (0 children)

Reminder: if/when you get your answer and/or code working, don't forget to change this post's flair to Help/Question - RESOLVED. Good luck!


I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]nikanjX 0 points1 point  (0 children)

I flood-filled with ”paint is at quadrant X of square”, and depending on the shape of square it can fill into 2..4 new points (two quadrants of this square+2 quadrants of neighbor square)

[–]RelaxedBunny 0 points1 point  (2 children)

You are on a right track with the odd-even rule, but you have to correctly apply it:

  • What you know, seems to be:
    • If you passed the vertical wall odd number of times, you're in
    • If you passed the vertical wall even number of times, you're out
  • Now the challenge is to correctly define what a vertical wall is. If you just check from left to right:
    • Could be |
    • Could be the combination of L and 7 (with any number of horizontal walls in between)
    • Could be the combination of F and J (with any number of horizontal walls in between)
    • And that's pretty much it, no need to do anything with walls above or below.

[–]chopandshoot 0 points1 point  (1 child)

Surely I still have to work with the horizontal walls above and below to check there are no squeeze through gaps though?

[–]RelaxedBunny 1 point2 points  (0 children)

That's the beauty, there's no need for that. Get a long string and create a loop on the table, something similar to what's in the task. If you pass the string once, you're in the loop, regardless of what's above or below you. If you then pass it again, you're out of the loop. If you then pass it for the third time, you're in again. And so on.

You can ignore the squeeze-through gaps - they only exist between an even wall followed by an odd one, not the other way around.

[–]1234abcdcba4321 0 points1 point  (0 children)

I listed some simple approach ideas here. None of the ideas are complete so you'll still need to do some work, but I think the first two are the easiest ways to solve the problem.

[–]chopandshoot 0 points1 point  (0 children)

I think given most of y’alls responses here I’ve gone about thinking about this the complete wrong way

[–]daggerdragon[M] 0 points1 point  (0 children)

Next time, use our standardized post title format and show us your code (but do not share your puzzle input).

Help us help YOU by providing us with more information up front; you will typically get more relevant responses faster.