There might be a way to do it, but I imagine that will lead to abuses.
- I start a fake Google account to look at the puzzle and write my solution.
- With code in hand, I log into my real account, grab the data, and run my already-written code.
- I am now at the top of the leaderboard, having solved both parts in 7 seconds.
Sure, one can cheat. But some do that with ChatGPT already. too.
But I requested this particularly for the private boards, where people know and trust each other not to cheat - hopefully.
I don’t even want the default display to change, which always starts at GMT-5. I just want the start time recorded and delivered in the JSON data, so that the plugin I linked to above would be able to use that for the “adjusted” puzzle times.
1 Like
BTW, the guy who solved day 1 in 52 seconds (or whatever) posted a video of him doing it. He used the node console in his browser, which is kind of impressive.
There are some who write extra scripts so that they just have to paste the puzzle description and the test input and output data, which trains the AI, and then ask it to apply the learned to the puzzle input.
There’s currently a lot of criticism about ChatGPT because when it relies on data from the internet, it often gives wrong answers in a very confident way that looks right.
But with AoC, there’s training data, which makes it much more reliable. It might later still get things wrong with the more complex puzzles. We’ll see. I remember from 2021 that often my solutions were wrong even though I got the test results right because I missed a tiny detail (for instance, in a path finding puzzle, the test input only had a path in 3 directions, but the real input required a path with all 4 directions, which my algo didn’t get right at first.)
The Leaderboard is just a side artifact of having fun together with these puzzles… and we are not going to win against Kem anyway so…
3 Likes
I’ve been typing with my toes, just to give you all a chance.
4 Likes
Like some of the others, I used the specs from the example when trying to solve part 2. Then, reread the problem, and misinterpreted what needed to be done. Reread it again, and finally figured it out. Fortunately, all of the needed data had been calculated in part 1.
Day 7 Spoiler
Class fldrItm
Parent as fldrItm
child() as fldrItm
fullpath as string 'Full path name
itmSize as integer 'total space used by files in this dir
chTotal as integer 'total space used by subdirs
dirTotal as integer 'total of itmSize & chTotal
end class
Public Sub Day07()
tf3.Text = "Day07 Parts 1 & 2"+EndOfLine+EndOfLine
inpReset 'Init input data
dim txt As String = rdLine
dim cDir As String = ""
dim dSize As Integer = 0
dim cNode As new fldrItm
cNode.Parent=nil
cNode.fullpath = "/"
dim nodeList() As fldrItm
nodeList.Append cNode
dim topNode As fldrItm = nodeList(0)
'Input read and process loop
while txt<>""
if left(txt,1)="$" then
'process cmd
select case MidWords(txt,2,1)
case "cd"
'Navigate directories
select case MidWords(txt,3,1)
case "/"
'root dir
cNode = topNode
cDir = cNode.fullpath
case ".."
'up one level
if cNode.Parent = Nil then
cNode = topNode
Else
cNode = cNode.Parent
end if
cDir = cNode.fullpath
else
'down one level
dim makeNew As Boolean
dim testname As string = cNode.fullpath +" "+MidWords(txt,3,1)
if cNode.child.Ubound<0 then
'No child nodes, so add this one
makeNew = True
else
'check child nodes for match
makeNew = True
for i as Integer = 0 to cNode.child.Ubound
if cNode.child(i).fullpath = testname then
makeNew = False
'set new node to the child
cNode=cNode.child(i)
'get current name
cDir = cNode.fullpath
exit for i
end if
next
end if
if makeNew then
'subdir doesn't exist, so add it
nodeList.Append new fldrItm
dim lastNode As fldrItm = nodeList(nodeList.Ubound)
lastNode.fullpath = testname '<--- Arrrrgh, this was the culprit
lastNode.Parent = cNode
cNode.child.Append lastNode
cNode=lastNode
cDir = cNode.fullpath
end if
end select
case "ls"
'do nothing
end select
else
'Input is not a command, so scan for files and sizes
select case MidWords(txt,1,1)
case "dir"
'do nothing
Else
'add file size to dir total
dSize = val(LeftWords(txt,1))
cNode.itmSize = cNode.itmSize + dSize
end select
end if
txt=rdLine 'read next input line
wend
'
'The full node tree is now built.
'
'Recursive size calc:
dim totalfilesize As Integer = calcSize(topNode,0)
'
'Find part 1 solution by totalling all dirs of size 100000 or smaller
'
Dim grandtotal As Integer = 0
for i as Integer = 0 to nodeList.Ubound
nodeList(i).dirTotal = nodeList(i).itmSize + nodeList(i).chTotal
if nodeList(i).dirTotal<=100000 then
grandtotal = grandtotal+nodeList(i).dirTotal
end if
next
tf3.AppendText "Part 1 solution: "+str(grandtotal)+EndOfLine
'
'Part 2
'
dim tgtsize As Integer = topNode.dirTotal-40000000
tf3.AppendText "Total used: "+str(topNode.dirTotal)+EndOfLine
tf3.AppendText "Target size: "+str(tgtsize)+EndOfLine
dim bestnode As Integer =-1
dim bestsize As Integer =70000000
for i as Integer = 0 to nodeList.Ubound
if nodeList(i).dirTotal>=tgtsize and nodeList(i).dirTotal<bestsize then
bestsize = nodeList(i).dirTotal
bestnode = i
end if
next
if bestnode>=0 then
tf3.AppendText "Part 2 solution: "+str(bestsize)+EndOfLine
end if
End Sub
Public Function CalcSize(nd As fldrItm, level As Integer) as Integer
'Traverse the node tree and calculate directory sizes
'If no child nodes, just return total at this level
if nd.child.Ubound < 0 then
return nd.itmSize
else
'Calculate total size of child nodes
nd.chTotal = 0
for i as Integer = 0 to nd.child.Ubound
nd.chTotal = nd.chTotal + CalcSize(nd.child(i), level+1)
next
Return nd.itmSize+nd.chTotal
end if
End Function
'Note Code for the text functions LeftWords, RightWords, MidWords and WordCount are not shown.
'They are the word equivalents of the character based functions Left, Right, Mid and Len.
1 Like
I see @Paul_Lefebvre is now also part of the private AoC leaderboard. Welcome!
2 Likes
Today I couldn’t come up with a good algorithm.
Spoiler
Tried initially to rotate the input field (I have already code for that) so that I could simply go over each line, but then it got too complicated to rotate the coordinates when I wanted to record a tree’s visibility. So I wrote instead separate code for up/down and for left/right scanning. Which then worked out fine the first try.
Then part 2 - where my code wasn’t going to work, so I had to end up writing a function that would advance the x/y coord depending on a direction. All that felt familiar (we had something like that in 2021 as well). Not happy with my code. I like to see more elegant solutions.
Sooo tired.
I had all kinds of mental blocks today and made silly errors. I’m guessing my code looks similar to yours.
I’m not happy with my today puzzle code. It works, but…
I just gave Day 1 a try using Atari BASIC. Haven’t had a chance to look at others yet.
2 Likes
Garry, seems you partook in Day 7 - but forgot to upload your code?
The first part, yes. The second I made more concise by using only one nested loop over x, y and direction (0-3). And used a subroutine that moves x/y according to the direction. Makes it much more readable, I think.
BTW, I need to stop staying up all night. This evening the gold points are all yours to get again
Spoiler (Code)
My code for part 2:
Private height As Integer
Private width As Integer
Private Function Solve2(input as TextParser, part as Integer) As Variant
dim result as Integer
dim field() as VarArray = input.Section(0).VariantsSepBy("")
dim w as Integer = field(0).Count
dim h as Integer = field.Ubound+1
self.width = w
self.height = h
// Visit every tree inside the perimeter,
// counting how many trees are visible in each of the 4 directions
for y0 as Integer = 1 to h-2
for x0 as Integer = 1 to w-2
dim score as Integer = 1
for dir as Integer = 0 to 3
dim x as Integer = x0
dim y as Integer = y0
dim limit as Integer = field(y).ar(x)
dim dist as Integer = 0
while advance(x, y, dir)
dist = dist + 1
if field(y).ar(x) >= limit then
exit
end if
wend
score = score * dist
next
if score > result then
result = score
end if
next
next
return result
end function
Private Function advance(ByRef x as Integer, ByRef y as Integer, dir as Integer) As Boolean
select case dir
case 0
x = x + 1
case 1
y = y + 1
case 2
x = x - 1
case 3
y = y - 1
end select
return x >= 0 and y >= 0 and x < width and y < height
end function
It sounds like my solution for Day 8 part 1 was the same as others. My part 2 may be different.
I’ve now uploaded my AOC project here after stripping out a lot of detritus.
I’m in the process of refactoring, and my new code is slower but worlds better than it was. I’ll post soon…
My code is so much cleaner now. I wish I had done it this way last night, I’d have been done in 5 minutes.
Spoiler: 2022 Day 8
I enhanced my existing ObjectGrid class to include functions like Above( member As GridMember )
I also defined a Delegate, NextDelegate
. Finally, I defined the class as Iterable and an Iterator.
The code then became simple. I convert the input to an ObjectGrid, then call for each square as GridMember in grid
. I create an array of NextDelegates that I can cycle through on each square to keep fetching the next one in a given direction, then make decisions based on that.
For example:
Private Function CountVisible(grid As ObjectGrid) As Integer
var lastRowIndex as integer = grid.LastRowIndex
var lastColIndex as integer = grid.LastColIndex
var directionals() as ObjectGrid.NextDelegate
directionals.Add AddressOf grid.Above
directionals.Add AddressOf grid.Right
directionals.Add AddressOf grid.Below
directionals.Add AddressOf grid.Left
var count as integer
for each square as GridMember in grid
if square.Row = 0 or square.Column = 0 or square.Row = lastRowIndex or square.Column = lastColIndex then
count = count + 1
continue for square
end if
var height as integer = square.RawValue
for each directional as ObjectGrid.NextDelegate in directionals
var thisSquare as GridMember = square
do
thisSquare = directional.Invoke( thisSquare )
if thisSquare is nil then
count = count + 1
continue for square
end if
if thisSquare.RawValue.IntegerValue >= height then
continue for directional
end if
loop
next
next
return count
End Function
The ScenicScore
function is similar:
Private Function ScenicScore(grid As ObjectGrid, square As GridMember) As Integer
if square.Row = 0 or square.Row = grid.LastRowIndex or square.Column = 0 or square.Column = grid.LastColIndex then
return 0
end if
var directionals() as ObjectGrid.NextDelegate
directionals.Add AddressOf grid.Above
directionals.Add AddressOf grid.Right
directionals.Add AddressOf grid.Below
directionals.Add AddressOf grid.Left
var height as integer = square.RawValue
var score as integer = 1
for each directional as ObjectGrid.NextDelegate in directionals
var nextSquare as GridMember = square
var thisScore as integer
do
nextSquare = directional.Invoke( nextSquare )
if nextSquare is nil then
exit do
end if
thisScore = thisScore + 1
if nextSquare.RawValue >= height then
exit
end if
loop
score = score * thisScore
next
return score
End Function
I just got up after going to bed earlier.
Damnit. The second one is tricky. Got my algo wrong again.
The example for part 2 doesn’t make any sense to me.
Haha, we obviously all struggle at part 2