It’s funny because it’s true.
Love the movie “Office space” (o;
A clip of “Bob & Bob” was shown to new employees when I started in a network consulting company (o;
As an aside, my Advent of Code project was designed to use a Thread for each puzzle. This year I converted those from cooperative threads to preemptive just by setting the Type before starting the Thread. And this has presented exactly zero issues.
Just now I introduced a “Run 'Em All” option that runs every one across the years simultaneously. I haven’t counted, but that’s well over 100 puzzles. Again, no problem.
Day 5 - Part 1 Solution
So I simply added all the rules to a dictionary where the key values are the rule (e.g. 91|95) and the value is always true. So the rules dictionary now looks like follow:
{“91|95”:true,“64|54”:true,…}
Then I implemented a ValidOrder function to check if pages are in a valid order like so…
Public Function ValidOrder(arr() As String, rules As Dictionary) As Boolean
Var valid As Boolean
Var i As Integer
Var j As Integer
valid = true
while i < arr.Ubound and valid
j = i + 1
while j <= arr.Ubound and valid
if rules.HasKey(arr(j) + "|" + arr(i)) then
valid = false
end if
j = j + 1
wend
i = i + 1
wend
return valid
End Function
Day 5 - Part 2 Solution
Part two I used the same rules dictionary as in part one, and implemented a function to correct the order of pages like so…
Public Sub CorrectOrder(arr() As String, rules As Dictionary)
Var i As Integer
Var j As Integer
Var tmpVal As String
while i < arr.Ubound
j = i + 1
while j <= arr.Ubound
if rules.HasKey(arr(j) + "|" + arr(i)) then
tmpVal = arr(i)
arr(i) = arr(j)
arr(j) = tmpVal
i = 0
j = 0
end if
j = j + 1
wend
i = i + 1
wend
End Sub
Day 5 solution
var et As Double = Microseconds
PrintLine "Day 5 Parts 1 & 2 - Print Queue"
'Process input data
LoadData
var inpData() As String = Split(pzlData,EndOfLine)
var orderRules(99) As String 'dataset references no more than 99 pages
var prntListStart As Integer = 0
'Read page order info and create array of all pages that must precede a given page
for i as Integer = 0 to inpData.LastIndex
if trim(inpData(i))="" then 'Check for blank line separating data groups
'Encountered end of page order info and start of print list
prntListStart = i+1
exit for i
end if
var order() As String = inpData(i).Split("|")
var indx As integer = order(0).ToInteger
var posn as string = order(1)
orderRules(indx) = orderRules(indx)+"|"+posn
next i
PrintLine "Input Parse Time: "+TimeFormat(Microseconds-et)
et = Microseconds
var pSum,sReordered As Integer = 0 'puzzle solution values for parts 1 and 2
'Check each print list for correctly ordered pages
for i as Integer = prntListStart to inpData.LastIndex
var ptLst As String = inpData(i)
var valid As Boolean = True
var pL() As String = ptLst.Split(",")
for j as Integer = 1 to pL.LastIndex 'for each page in the print list
var pageNo As Integer = pL(j).ToInteger
var pOrder As String = orderRules(pageNo)
'Check that each preceding page is in order
for k as Integer = 0 to j-1
if pOrder.IndexOf(pL(k))>-1 then
'Pages are out of order
valid = False
'Reorder the pages
var jj As Integer = 1
while jj <= pL.LastIndex
for ij as Integer = jj to pL.LastIndex
pageNo = pL(ij).ToInteger
pOrder = orderRules(pageNo)
for ik as Integer = 0 to ij-1
if pOrder.IndexOf(pL(ik))>-1 then
'remove pL(ij) and insert it before pL(ik)
var pg As string = pL(ij)
pL.RemoveAt(ij)
pL.AddAt(ik,pg)
jj=ik+1 'restart the check from the insertion point
exit for ij
end if
next ik
jj=ij+1 'continue checking from next element
next ij
wend
'Sum the middle value of the reordered print list (part 2 solution)
sReordered = sReordered+pL(pL.LastIndex\2).ToInteger
exit for j
end if
next k
next j
if valid then
'Original order is correct
'Sum the middle value of the original print list (part 1 solution)
pSum = pSum+pL(pL.LastIndex\2).ToInteger
end if
next i
PrintLine "Part 1 solution: "+str(pSum)
PrintLine "Part 2 solution: "+str(sReordered)
PrintLine "Time: "+TimeFormat(Microseconds-et)
Why doesn’t my code display in colour?
My guess is that it is too big for the auto-format and that is why it doesn’t show the colors.
Test breaking the code in parts
var et As Double = Microseconds
PrintLine "Day 5 Parts 1 & 2 - Print Queue"
'Process input data
LoadData
var inpData() As String = Split(pzlData,EndOfLine)
var orderRules(99) As String 'dataset references no more than 99 pages
var prntListStart As Integer = 0
'Read page order info and create array of all pages that must precede a given page
for i as Integer = 0 to inpData.LastIndex
if trim(inpData(i))="" then 'Check for blank line separating data groups
'Encountered end of page order info and start of print list
prntListStart = i+1
exit for i
end if
var order() As String = inpData(i).Split("|")
var indx As integer = order(0).ToInteger
var posn as string = order(1)
orderRules(indx) = orderRules(indx)+"|"+posn
next i
PrintLine "Input Parse Time: "+TimeFormat(Microseconds-et)
et = Microseconds
var pSum,sReordered As Integer = 0 'puzzle solution values for parts 1 and 2
'Check each print list for correctly ordered pages
for i as Integer = prntListStart to inpData.LastIndex
var ptLst As String = inpData(i)
var valid As Boolean = True
var pL() As String = ptLst.Split(",")
for j as Integer = 1 to pL.LastIndex 'for each page in the print list
var pageNo As Integer = pL(j).ToInteger
var pOrder As String = orderRules(pageNo)
'Check that each preceding page is in order
for k as Integer = 0 to j-1
if pOrder.IndexOf(pL(k))>-1 then
'Pages are out of order
valid = False
'Reorder the pages
var jj As Integer = 1
while jj <= pL.LastIndex
for ij as Integer = jj to pL.LastIndex
pageNo = pL(ij).ToInteger
pOrder = orderRules(pageNo)
for ik as Integer = 0 to ij-1
if pOrder.IndexOf(pL(ik))>-1 then
'remove pL(ij) and insert it before pL(ik)
var pg As string = pL(ij)
pL.RemoveAt(ij)
pL.AddAt(ik,pg)
jj=ik+1 'restart the check from the insertion point
exit for ij
end if
next ik
jj=ij+1 'continue checking from next element
next ij
wend
'Sum the middle value of the reordered print list (part 2 solution)
sReordered = sReordered+pL(pL.LastIndex\2).ToInteger
exit for j
end if
next k
next j
if valid then
'Original order is correct
'Sum the middle value of the original print list (part 1 solution)
pSum = pSum+pL(pL.LastIndex\2).ToInteger
end if
next i
PrintLine "Part 1 solution: "+str(pSum)
PrintLine "Part 2 solution: "+str(sReordered)
PrintLine "Time: "+TimeFormat(Microseconds-et)
@Robert_Weaver - I was getting similar results as @AlbertoD . So it may be length or a combination of length and complexity (number of conditionals, etc.) breaking the auto-formatting.
@Alwyn_Bester - your method is very close to mine (though more elegantly coded)
I went with a more OOP approach (where I had a ‘print_validator’ and a ‘print_run’ class with a single instance of ‘print_validator’ (with the rules list) and an n instances of the
‘print_run’ (one for each “run”).
Doing it OOP helped me handle working on it “piecemeal” in the breaks between time-sensitive work tasks.
That is what I like about Advent of Code… there are many solutions for the same problem (divergent thinking), and it is always interesting to learn about how others approached the puzzle.
Day 6 complete. This one was pretty easy.
Nice… looking forward to it. Due to workload constraints I’ll only be able to do it a bit later.
Couldn’t stay up last night so I did Day 6 this morning. Other than my key management in part 2 tripping me up, it wasn’t hard.
FYI, when using a Dictionary
, if you only need to track keys, not values, you can assign nil
as the value.
Or use a Set
.
Nice… will definitely keep that in mind.
It never occurred to me to use a dictionary. I just marked the path on the grid array. It wasn’t terribly efficient, but I just wanted to get it done so I could go to bed. Part 2 took a minute and a half on my old 2015 MacBook.
It takes 30s here, but I want to try using ThreadPool to check possibilities in parallel.
Even with dictionaries, part 2 took 1 minute on my gaming laptop.
It’s definitely an ideal application for parallel processing.