For part 2 I just searched for every A, then looked at the corners for MSMS, MMSS, SSMM, and SMSM. You can also just iterate between 1 and len() -1 because you cannot have an X-MAS at index 0 or on the edge and then you won't have to worry about bounds checking.
god fkn damn it that was my idea exactly, just iterate through As and check corners, but my answer is too large. i'm still stumped part 1 was a simple recursion, took me 15 minutes.
For part two, scanned the grid for all the 'A's and then looked to see if there was an 'M' in the two top corners and an 'S' in the two bottom corners. I then rotated the grid and scanned again. 4 rotations got me all the locations. I used the same rotating the grid solution to optimise part 1 so that I was only scanning X's to the right and down-right per rotation.
It's interest to know that you found the parte two more difficult than the part one. I spend a lot of time in the part one, and when I finally got it right, the part two took just a couple hours. And with my collegues it was also similar. Congrats on the part one and on the video!
I watched this after solving day 4 but my code was just horrible so it was very informative, thanks! for part 2 i started from the "A" and checked the 4 corners to be 2 "S" and 2 "M" and then the first corner and his opposite to be not the same letter
Something that helped me with this puzzle was to make a Grid class with primitive grid operations to get each different adjacent cell, and to get strings in all of the different directions from a cell. Once I had that it was easy to use that to solve both puzzles.
I’ve watched Eric Wastl keynote on how he creates these puzzles, where he explains what’s the idea between part 1 and part 2. There are no spoilers, it may just help understand his thinking. You may also want to browse yt to see how previous puzzles were cracked in your language of choice. You did awesome btw!
If it helps, for part 2 (written in go) I have a counter in my main that calls the checkCell function for each item in the grid and accumulates the result (this is why I’m retuning an int) The overall idea is to grab the ‘A’, check it has a padding of 1 on all directions Then check all diagonals for an ‘M’ follow by an ’S’ I tried counting letters/ accumulating them and checking for string equality etc… My current solution is by far more performant func checkCell( grid []string, rowIdx int, colIdx int, ) int { if !all([]bool{ rowIdx > 0, //canGoUp colIdx < len(grid[0])-1, //canGoRight colIdx > 0, //canGoLeft rowIdx < len(grid)-1, //canGoDown }) { return 0 // bounding box is not valid for all directions } counter := 0 if grid[rowIdx][colIdx] == 'A' { // top left to bottom right counter += xCrawl(grid, rowIdx, colIdx, 1, 1) // bottom left to top right counter += xCrawl(grid, rowIdx, colIdx, 1, -1) // top right to bottom left counter += xCrawl(grid, rowIdx, colIdx, -1, 1) // bottom right to top left counter += xCrawl(grid, rowIdx, colIdx, -1, -1) } if counter == 2 { return 1 } return 0 } func xCrawl(grid []string, rowIdx int, colIdx int, directionX int, directionY int) int { if (grid[rowIdx-directionY][colIdx-directionX] == 'M') && (grid[rowIdx+directionY][colIdx+directionX] == 'S') { return 1 } return 0 }
A mindset shift that might make the problem easier would be to think of modifying the data, then feeding it into your program--rather than treating the data like a static object and writing code around it. For example in my Part 1, to find the number of vertical matches I transposed the grid so that I could use the same function I used to find horizontal matches, and did something similar for the diagonal matches. My Part 2 solution was pretty much a copy paste of the diagonal match finder from Part 1.
I struggled with the X-MAS part 2 but got there eventually, took some thinking though! Looking forwards to comparing approaches for day 5. I tried to do a speedrun of solving days 1-4 but it was over an hour... I uploaded it anyway :D
For part 2 I searched for every 'A', then i looked at the diagonals and if they were either 'M' or 'S' pit them in a hash set and check if the Set has a size of 2.
Part 2: find all A, then for each of them iterate over 4 cross positions around it and get all of the values to a string in a circular order, then check the string for count(M)==2 and count(S)==2 and (find(MM) or find(SS))
Mine sucks. I didn't even use a proper matrix because I got lazy with parsing, haha. I just treated the data as a continuous array of characters and did some strange index operations. In the end, I managed to solve it, but it was harder than I thought, and my solution is pretty unoptimized
you way way overcomplicated for part 2. My solution: iterate over rows and columns from "1" till "len()-1", so from second till second to last, for both columns and rows. So you don't even need to check for boundaries. Then, check if character at current position is "A", as it is always in the middle. If it is - check the diagonals (again, no need to check for boundaries), I'm just lazy so I hardcoded: def part2(x, y, mat): w1 = mat[x-1][y-1]+mat[x][y]+mat[x+1][y+1] w2 = mat[x+1][y-1]+mat[x][y]+mat[x-1][y+1] if w1 in ['MAS','SAM'] and w2 in ['MAS','SAM']: return True return False so basically I am forming words from the diagonals, putting left-up + middle + right-bottom in one word, and left-down + middle + right-up in another, and check if both words are correct.
For part 2 I just searched for every A, then looked at the corners for MSMS, MMSS, SSMM, and SMSM. You can also just iterate between 1 and len() -1 because you cannot have an X-MAS at index 0 or on the edge and then you won't have to worry about bounds checking.
god fkn damn it that was my idea exactly, just iterate through As and check corners, but my answer is too large. i'm still stumped
part 1 was a simple recursion, took me 15 minutes.
For part two, scanned the grid for all the 'A's and then looked to see if there was an 'M' in the two top corners and an 'S' in the two bottom corners. I then rotated the grid and scanned again. 4 rotations got me all the locations. I used the same rotating the grid solution to optimise part 1 so that I was only scanning X's to the right and down-right per rotation.
It's interest to know that you found the parte two more difficult than the part one. I spend a lot of time in the part one, and when I finally got it right, the part two took just a couple hours. And with my collegues it was also similar.
Congrats on the part one and on the video!
I watched this after solving day 4 but my code was just horrible so it was very informative, thanks! for part 2 i started from the "A" and checked the 4 corners to be 2 "S" and 2 "M" and then the first corner and his opposite to be not the same letter
Something that helped me with this puzzle was to make a Grid class with primitive grid operations to get each different adjacent cell, and to get strings in all of the different directions from a cell. Once I had that it was easy to use that to solve both puzzles.
I’ve watched Eric Wastl keynote on how he creates these puzzles, where he explains what’s the idea between part 1 and part 2. There are no spoilers, it may just help understand his thinking. You may also want to browse yt to see how previous puzzles were cracked in your language of choice.
You did awesome btw!
If it helps, for part 2 (written in go)
I have a counter in my main that calls the checkCell function for each item in the grid and accumulates the result (this is why I’m retuning an int)
The overall idea is to grab the ‘A’, check it has a padding of 1 on all directions
Then check all diagonals for an ‘M’ follow by an ’S’
I tried counting letters/ accumulating them and checking for string equality etc…
My current solution is by far more performant
func checkCell(
grid []string,
rowIdx int,
colIdx int,
) int {
if !all([]bool{
rowIdx > 0, //canGoUp
colIdx < len(grid[0])-1, //canGoRight
colIdx > 0, //canGoLeft
rowIdx < len(grid)-1, //canGoDown
}) {
return 0 // bounding box is not valid for all directions
}
counter := 0
if grid[rowIdx][colIdx] == 'A' {
// top left to bottom right
counter += xCrawl(grid, rowIdx, colIdx, 1, 1)
// bottom left to top right
counter += xCrawl(grid, rowIdx, colIdx, 1, -1)
// top right to bottom left
counter += xCrawl(grid, rowIdx, colIdx, -1, 1)
// bottom right to top left
counter += xCrawl(grid, rowIdx, colIdx, -1, -1)
}
if counter == 2 {
return 1
}
return 0
}
func xCrawl(grid []string, rowIdx int, colIdx int, directionX int, directionY int) int {
if (grid[rowIdx-directionY][colIdx-directionX] == 'M') &&
(grid[rowIdx+directionY][colIdx+directionX] == 'S') {
return 1
}
return 0
}
A mindset shift that might make the problem easier would be to think of modifying the data, then feeding it into your program--rather than treating the data like a static object and writing code around it.
For example in my Part 1, to find the number of vertical matches I transposed the grid so that I could use the same function I used to find horizontal matches, and did something similar for the diagonal matches. My Part 2 solution was pretty much a copy paste of the diagonal match finder from Part 1.
I struggled with the X-MAS part 2 but got there eventually, took some thinking though! Looking forwards to comparing approaches for day 5. I tried to do a speedrun of solving days 1-4 but it was over an hour... I uploaded it anyway :D
For part 2 I have every possible constellation in a list. Like M,S,M,S etc. and then checked the cross if this variant is in my list
For part 2 I searched for every 'A', then i looked at the diagonals and if they were either 'M' or 'S' pit them in a hash set and check if the Set has a size of 2.
Part 2: find all A, then for each of them iterate over 4 cross positions around it and get all of the values to a string in a circular order, then check the string for count(M)==2 and count(S)==2 and (find(MM) or find(SS))
Mine sucks. I didn't even use a proper matrix because I got lazy with parsing, haha. I just treated the data as a continuous array of characters and did some strange index operations. In the end, I managed to solve it, but it was harder than I thought, and my solution is pretty unoptimized
I stumbled upon this channel and by the name of it I thought you would be coding in C#. CS Jackie - I thought CS stands for C#. 😊
I did simple brute force for both parts >.>
part2:
find 'A',
collect A_pos + [[-1,-1],[1,-1],[1,1],[-1,1]] (corners),
check corners for containing 2 'M' and containing 2 'S' and corners[0] corners[2] and corners[1]corners[3]
advent of code is getting more and more unhinged 😂
you way way overcomplicated for part 2.
My solution:
iterate over rows and columns from "1" till "len()-1", so from second till second to last, for both columns and rows. So you don't even need to check for boundaries.
Then, check if character at current position is "A", as it is always in the middle. If it is - check the diagonals (again, no need to check for boundaries), I'm just lazy so I hardcoded:
def part2(x, y, mat):
w1 = mat[x-1][y-1]+mat[x][y]+mat[x+1][y+1]
w2 = mat[x+1][y-1]+mat[x][y]+mat[x-1][y+1]
if w1 in ['MAS','SAM'] and w2 in ['MAS','SAM']:
return True
return False
so basically I am forming words from the diagonals, putting left-up + middle + right-bottom in one word, and left-down + middle + right-up in another, and check if both words are correct.
Yes!! later on I discussed this exercise with a fellow engineer and we came to this conclusion 😂 definitely over complicated this
no more python
😂