Discussion thread for day 22 of the Advent of Code : https://adventofcode.com/2020/day/22
Back to the familiar, if somewhat finicky, realm of substring parsing to play a macro free game for part I. Like the answer to the question of Life, the Universe and Everything, part II will require Deep Thought.
Dan
Here is my solution for part 1. I took the iterative approach.
iterative Macro
I toyed with the idea of replacing the macro for a combination of tools for the first part, but thought "let's wait for part 2"...
Took a bit longer than I would have liked to solve part 1 with first an error of mixing numbers and strings so not getting the desired output in the example dataset, and then when running the full dataset being out by one which was just to do with how I dealt the last cards in the pack, but managed to fix it.
It's nice being back into it as I just didn't really have the time last week to participate.
Macro
Ok, so Part 2 is horrific... but done in BaseA
My approach for Part 2 is to turn the recursion into iteration and use generate rows.
- I encode the 1-50 as ASCII characters (value plus 48 so 1=1, 2=2,...9=9,10=:,...)
- First 2 words of the string are state if player 1 and 2 in the current game (or subgame)
- After word 2, the previous state of the current game is stored as (P1#P2) separated by spaces
- This is checked to see if P1 wins the game, if so the current game is ended and the change made to parent game (or iteration terminates) and current game is removed (replace up to first ` ! `)
- Otherwise, if need to recurse then a new pair of P1 and P2 are added followed by a ` ! ` which marks the end of the current game state
- If someone wins a game as other player runs out, then as above with P1 happens
- If someone wins a round then the state is added to list and word 1 and word 2 are manipulated to be the new value
The horrific formula is below:
IF REGEX_CountMatches(C," ") = 0 THEN
"*"
ELSEIF Contains(REGEX_Replace(C, " ! .*$", ""),GetWord(C,0) + "#" + GetWord(C,1)) THEN
// Player 1 win by termination
iif(Contains(C," ! "),
Substring(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0), 1)
+ Left(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0), 1)
+ Left(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1), 1)
+ " " + Substring(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1), 1)
+ " " + GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0) + "#" + GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1)
+ Regex_Replace(C, "^[^!]+ ! [^ ]+ [^ ]+ ?", " "),
Substring(GetWord(C,0),1) + Left(GetWord(C,0),1) + Left(GetWord(C,1),1))
ELSEIF CharToInt(GetWord(C,0)) - 48 < Length(GetWord(C,0)) and CharToInt(GetWord(C,1))-48 < Length(GetWord(C,1)) THEN
// Do I need to recurse
Substring(GetWord(C,0),1,CharToInt(GetWord(C,0)) - 48) + " " + Substring(GetWord(C,1),1,CharToInt(GetWord(C,1))-48) + " ! "+ C
ELSEIF CharToInt(GetWord(C,0)) > CharToInt(GetWord(C,1)) AND Length(GetWord(C,1)) = 1 THEN
// Player 1 win
iif(Contains(C," ! "),
Substring(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0), 1)
+ Left(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0), 1)
+ Left(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1), 1)
+ " " + Substring(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1), 1)
+ " " + GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0) + "#" + GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1)
+ Regex_Replace(C, "^[^!]+ ! [^ ]+ [^ ]+ ?", " "),
Substring(GetWord(C,0),1) + Left(GetWord(C,0),1) + Left(GetWord(C,1),1))
ELSEIF CharToInt(GetWord(C,0)) < CharToInt(GetWord(C,1)) AND Length(GetWord(C,0)) = 1 THEN
// Player 2 win
iif(Contains(C," ! "),
Substring(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0), 1)
+ " " + Substring(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1), 1)
+ Left(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1), 1)
+ Left(GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0), 1)
+ " " + GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 0) + "#" + GetWord(REGEX_Replace(C, "^[^!]+ ! ", ""), 1)
+ Regex_Replace(C, "^[^!]+ ! [^ ]+ [^ ]+ ?", " "),
Substring(GetWord(C,1),1) + Left(GetWord(C,1),1) + Left(GetWord(C,0),1))
ELSE
// Play a turn
iif(CharToInt(GetWord(C,0))>CharToInt(GetWord(C,1)),
Substring(GetWord(C,0),1) + Left(GetWord(C,0),1) + Left(GetWord(C,1),1) + " " +Substring(GetWord(C,1),1),
Substring(GetWord(C,0),1) + " " +Substring(GetWord(C,1),1)+ Left(GetWord(C,1),1) + Left(GetWord(C,0),1))
// Add New Played
+ " " + GetWord(C,0) + "#" + GetWord(C,1)
// Keep Old
+ Regex_Replace(C,"^[^ ]+ [^ ]+ ?", " ")
ENDIF
Just about 1 mm iterations in about an hour
Day22!
I cleared Part 1 only.
Iterative Macro
AS anonymous user #1105310
https://github.com/AkimasaKajitani/AdventOfCode
Doing some cleaning up I realized I didn't post my final approach. It did take a looong time
While I was building the iterative macro, I thought that a lot of the steps were just moving data from one place to another and it was all just a big "if else" statement. @jdunkerley79 's generate rows proves that was right, but I was not able to come up with a solution like that. Quite impressive.