Advent of Code 2023

Es gibt 103 Antworten in diesem Thema. Der letzte Beitrag () ist von nogood.

    D16 Part 1

    VB.NET-Quellcode

    1. Private curGrid As Char()()
    2. Private chkList As New List(Of Current)
    3. Sub Main()
    4. Dim input = IO.File.ReadAllLines(FilePathOfData).Select(Function(l) l.ToCharArray).ToArray
    5. curGrid = input
    6. WalkGrid(Direction.East, 0, 0)
    7. Dim result = chkList.Cast(Of Object).Distinct.Count
    8. End Sub
    9. Private Sub WalkGrid(dir As Direction, y As Integer, x As Integer)
    10. Dim cury = y
    11. Dim curx = x
    12. Dim curdir = dir
    13. Dim cur = New Current With {.X = curx, .Y = cury, .Dir = curdir}
    14. While Not chkList.Contains(cur)
    15. chkList.Add(cur)
    16. curdir = CheckNext(curdir, cury, curx)
    17. Select Case curdir
    18. Case Direction.North
    19. cury -= 1
    20. Case Direction.West
    21. curx -= 1
    22. Case Direction.South
    23. cury += 1
    24. Case Else
    25. curx += 1
    26. End Select
    27. If cury < 0 OrElse cury >= curGrid.Length OrElse curx < 0 OrElse curx >= curGrid(0).Length Then Exit While
    28. cur = New Current With {.X = curx, .Y = cury, .Dir = curdir}
    29. End While
    30. End Sub
    31. Private Function CheckNext(curDir As Direction, cury As Integer, curx As Integer) As Direction
    32. Dim c = curGrid(cury)(curx)
    33. If c = "/"c Then
    34. curDir = CType(If(curDir Mod 2 = 1, curDir + 1, curDir + 3) Mod 4, Direction)
    35. ElseIf c = "\"c Then
    36. curDir = CType(If(curDir Mod 2 = 0, curDir + 1, curDir + 3) Mod 4, Direction)
    37. ElseIf c = "-"c AndAlso curDir Mod 2 = 0 Then
    38. WalkGrid(CType((curDir + 1) Mod 4, Direction), cury, curx)
    39. curDir = CType((curDir + 3) Mod 4, Direction)
    40. ElseIf c = "|"c AndAlso curDir Mod 2 = 1 Then
    41. WalkGrid(CType((curDir + 3) Mod 4, Direction), cury, curx)
    42. curDir = CType((curDir + 1) Mod 4, Direction)
    43. End If
    44. Return curDir
    45. End Function
    46. Friend Enum Direction
    47. North
    48. West
    49. South
    50. East
    51. End Enum
    52. Friend Class Current
    53. Implements IEquatable(Of Current)
    54. Property Y As Integer
    55. Property X As Integer
    56. Property Dir As Direction
    57. Public Overloads Function Equals(other As Current) As Boolean Implements IEquatable(Of Current).Equals
    58. Return _Y = other.Y AndAlso _X = other.X AndAlso _Dir = other.Dir
    59. End Function
    60. Public Overrides Function Equals(obj As Object) As Boolean
    61. Return _Y = DirectCast(obj, Current).Y AndAlso _X = DirectCast(obj, Current).X
    62. End Function
    63. Public Overrides Function GetHashCode() As Integer
    64. Return 1000 * _Y + _X
    65. End Function
    66. End Class

    D16 Part2
    Läuft ca. 4 Minuten, habe aber schon eine Idee wie ich den Ansatz aus Part 1 beschleunige, dann sollte Part 2 auch ok sein.
    Den größten Teil der hier geprüft wird kann man überspringen.

    VB.NET-Quellcode

    1. Sub Main()
    2. Dim input = IO.File.ReadAllLines(FilePathOfData).Select(Function(l) l.ToCharArray).ToArray
    3. curGrid = input
    4. WalkGrid(Direction.East, 0, 0)
    5. Dim resultPart1 = chkList.Cast(Of Object).Distinct.Count
    6. Dim resutlPart2 = resultPart1
    7. chkList.Clear()
    8. For y = 1 To curGrid(0).Length - 1
    9. WalkGrid(Direction.East, y, 0)
    10. Dim chk = chkList.Cast(Of Object).Distinct.Count
    11. If chk > resutlPart2 Then resutlPart2 = chk
    12. chkList.Clear()
    13. Next
    14. For x = 0 To curGrid(0).Length - 1
    15. WalkGrid(Direction.South, 0, x)
    16. Dim chk = chkList.Cast(Of Object).Distinct.Count
    17. If chk > resutlPart2 Then resutlPart2 = chk
    18. chkList.Clear()
    19. Next
    20. For x = 0 To curGrid(0).Length - 1
    21. WalkGrid(Direction.North, curGrid.Length - 1, x)
    22. Dim chk = chkList.Cast(Of Object).Distinct.Count
    23. If chk > resutlPart2 Then resutlPart2 = chk
    24. chkList.Clear()
    25. Next
    26. For y = 0 To curGrid(0).Length - 1
    27. WalkGrid(Direction.West, y, curGrid(0).Length - 1)
    28. Dim chk = chkList.Cast(Of Object).Distinct.Count
    29. If chk > resutlPart2 Then resutlPart2 = chk
    30. chkList.Clear()
    31. Next
    32. End Sub
    :cursing: Part 1 Testdaten ok, Part 2 Realdaten ok, Part 2 Testdaten ok, Part 2 Realdaten fail
    Dauer bei mir 30 Sekunden.

    ##########

    :whistling: Wenn man dauernd die Richtungen Left und Right verwechselt …
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Class ValueCalculatorForDay16
    2. Private ReadOnly Mirrors As New List(Of Mirror)
    3. Private ReadOnly Rays As New List(Of Ray)
    4. Private MaximumX As Integer
    5. Private MaximumY As Integer
    6. Private ReadOnly VisitedPositions As New Dictionary(Of String, VisitedPosition)
    7. Private ReadOnly EnergizedPositions As New List(Of Position)
    8. Private Part1Value As Integer
    9. Private Part2Value As Integer
    10. Private TempValue As Integer
    11. Function GetValueFor(FilePath As String) As (Integer, Integer)
    12. BuildMirrorsFrom(FilePath)
    13. AddDefaultRay()
    14. TraceRays(True)
    15. RetrievePart2Value()
    16. Return (Part1Value, Part2Value)
    17. End Function
    18. Private Sub RetrievePart2Value()
    19. For x = 0 To MaximumX
    20. Rays.Clear()
    21. VisitedPositions.Clear()
    22. EnergizedPositions.Clear()
    23. TempValue = 0
    24. Rays.Add(New Ray With {.Direction = Direction.Down, .X = x, .Y = 0})
    25. TraceRays(False)
    26. Part2Value = Math.Max(Part2Value, TempValue)
    27. Next
    28. For x = 0 To MaximumX
    29. Rays.Clear()
    30. VisitedPositions.Clear()
    31. EnergizedPositions.Clear()
    32. TempValue = 0
    33. Rays.Add(New Ray With {.Direction = Direction.Up, .X = x, .Y = MaximumY})
    34. TraceRays(False)
    35. Part2Value = Math.Max(Part2Value, TempValue)
    36. Next
    37. For y = 0 To MaximumY
    38. Rays.Clear()
    39. VisitedPositions.Clear()
    40. EnergizedPositions.Clear()
    41. TempValue = 0
    42. Rays.Add(New Ray With {.Direction = Direction.Right, .X = 0, .Y = y})
    43. TraceRays(False)
    44. Part2Value = Math.Max(Part2Value, TempValue)
    45. Next
    46. For y = 0 To MaximumY
    47. Rays.Clear()
    48. VisitedPositions.Clear()
    49. EnergizedPositions.Clear()
    50. TempValue = 0
    51. Rays.Add(New Ray With {.Direction = Direction.Left, .X = MaximumX, .Y = y})
    52. TraceRays(False)
    53. Part2Value = Math.Max(Part2Value, TempValue)
    54. Next
    55. End Sub
    56. Private Sub AddDefaultRay()
    57. Rays.Add(New Ray With {.Direction = Direction.Right, .X = 0, .Y = 0})
    58. End Sub
    59. Private Sub BuildMirrorsFrom(FilePath As String)
    60. Dim FileLines = IO.File.ReadAllLines(FilePath)
    61. For y = 0 To FileLines.Count - 1
    62. For x = 0 To FileLines(0).Count - 1
    63. Dim Character = FileLines(y)(x)
    64. If Character = "/"c Then Mirrors.Add(New Mirror With {.Power = 0, .Type = MirrorType.LeftToDownAndRightToUpAndDownToLeftAndUpToRight, .X = x, .Y = y})
    65. If Character = "\"c Then Mirrors.Add(New Mirror With {.Power = 0, .Type = MirrorType.LeftToUpAndRightToDownAndDownToRightAndUpToLeft, .X = x, .Y = y})
    66. If Character = "|"c Then Mirrors.Add(New Mirror With {.Power = 0, .Type = MirrorType.UpDownSplit, .X = x, .Y = y})
    67. If Character = "-"c Then Mirrors.Add(New Mirror With {.Power = 0, .Type = MirrorType.LeftRightSplit, .X = x, .Y = y})
    68. Next
    69. Next
    70. MaximumX = FileLines(0).Count - 1
    71. MaximumY = FileLines.Count - 1
    72. End Sub
    73. Private Sub TraceRays(IsPart1 As Boolean)
    74. Do Until Rays.Count = 0
    75. EnergizePosition(Rays.First)
    76. RememberPosition(Rays.First)
    77. InteractWithMirrors(Rays.First)
    78. MoveRay(Rays.First)
    79. If IsInLoop(Rays.First) Then
    80. Rays.Remove(Rays.First)
    81. Continue Do
    82. End If
    83. PossiblyRemoveRay(Rays.First)
    84. Loop
    85. If IsPart1 Then
    86. Part1Value = EnergizedPositions.Distinct.Count
    87. Else
    88. TempValue = EnergizedPositions.Distinct.Count
    89. End If
    90. End Sub
    91. Private Function IsInLoop(Ray As Ray) As Boolean
    92. Return VisitedPositions.ContainsKey($"{Ray.X}/{Ray.Y}/{Ray.Direction}")
    93. End Function
    94. Private Sub EnergizePosition(Ray As Ray)
    95. EnergizedPositions.Add(New Position With {.X = Ray.X, .Y = Ray.Y})
    96. End Sub
    97. Private Sub RememberPosition(Ray As Ray)
    98. Dim Key = $"{Ray.X}/{Ray.Y}/{Ray.Direction}"
    99. If Not VisitedPositions.ContainsKey(Key) Then VisitedPositions.Add(Key, New VisitedPosition With {.X = Ray.X, .Y = Ray.Y, .Direction = Ray.Direction})
    100. End Sub
    101. Private Sub MoveRay(Ray As Ray)
    102. If Ray.Direction = Direction.Down Then Ray.Y += 1
    103. If Ray.Direction = Direction.Right Then Ray.X += 1
    104. If Ray.Direction = Direction.Left Then Ray.X -= 1
    105. If Ray.Direction = Direction.Up Then Ray.Y -= 1
    106. End Sub
    107. Private Sub InteractWithMirrors(Ray As Ray)
    108. Dim InteractingMirror = Mirrors.SingleOrDefault(Function(x) x.X = Ray.X AndAlso x.Y = Ray.Y)
    109. If InteractingMirror Is Nothing Then Return
    110. If Ray.Direction = Direction.Up AndAlso InteractingMirror.Type = MirrorType.LeftToDownAndRightToUpAndDownToLeftAndUpToRight Then Ray.Direction = Direction.Right : Return
    111. If Ray.Direction = Direction.Up AndAlso InteractingMirror.Type = MirrorType.LeftToUpAndRightToDownAndDownToRightAndUpToLeft Then Ray.Direction = Direction.Left : Return
    112. If Ray.Direction = Direction.Down AndAlso InteractingMirror.Type = MirrorType.LeftToDownAndRightToUpAndDownToLeftAndUpToRight Then Ray.Direction = Direction.Left : Return
    113. If Ray.Direction = Direction.Down AndAlso InteractingMirror.Type = MirrorType.LeftToUpAndRightToDownAndDownToRightAndUpToLeft Then Ray.Direction = Direction.Right : Return
    114. If (Ray.Direction = Direction.Down OrElse Ray.Direction = Direction.Up) AndAlso InteractingMirror.Type = MirrorType.LeftRightSplit Then Ray.Direction = Direction.Left : Rays.Add(New Ray With {.Direction = Direction.Right, .X = Ray.X, .Y = Ray.Y}) : Return
    115. If Ray.Direction = Direction.Left AndAlso InteractingMirror.Type = MirrorType.LeftToDownAndRightToUpAndDownToLeftAndUpToRight Then Ray.Direction = Direction.Down : Return
    116. If Ray.Direction = Direction.Left AndAlso InteractingMirror.Type = MirrorType.LeftToUpAndRightToDownAndDownToRightAndUpToLeft Then Ray.Direction = Direction.Up : Return
    117. If Ray.Direction = Direction.Right AndAlso InteractingMirror.Type = MirrorType.LeftToDownAndRightToUpAndDownToLeftAndUpToRight Then Ray.Direction = Direction.Up : Return
    118. If Ray.Direction = Direction.Right AndAlso InteractingMirror.Type = MirrorType.LeftToUpAndRightToDownAndDownToRightAndUpToLeft Then Ray.Direction = Direction.Down : Return
    119. If (Ray.Direction = Direction.Left OrElse Ray.Direction = Direction.Right) AndAlso InteractingMirror.Type = MirrorType.UpDownSplit Then Ray.Direction = Direction.Up : Rays.Add(New Ray With {.Direction = Direction.Down, .X = Ray.X, .Y = Ray.Y}) : Return
    120. End Sub
    121. Private Sub PossiblyRemoveRay(Ray As Ray)
    122. If Ray.IsOutOfSpace(MaximumX, MaximumY) Then
    123. Rays.Remove(Ray)
    124. End If
    125. End Sub
    126. End Class
    127. Structure Position
    128. Property X As Integer
    129. Property Y As Integer
    130. End Structure
    131. Class Mirror
    132. Property Type As MirrorType
    133. Property X As Integer
    134. Property Y As Integer
    135. Property Power As Integer
    136. End Class
    137. Class Ray
    138. Property X As Integer
    139. Property Y As Integer
    140. Property Direction As Direction
    141. Function IsOutOfSpace(MaximumX As Integer, MaximumY As Integer) As Boolean
    142. Return X < 0 OrElse X > MaximumX OrElse Y < 0 OrElse Y > MaximumY
    143. End Function
    144. End Class
    145. Enum MirrorType
    146. LeftToDownAndRightToUpAndDownToLeftAndUpToRight
    147. LeftToUpAndRightToDownAndDownToRightAndUpToLeft
    148. UpDownSplit
    149. LeftRightSplit
    150. End Enum
    151. Enum Direction
    152. Up
    153. Down
    154. Left
    155. Right
    156. End Enum
    157. Class VisitedPosition
    158. Property X As Integer
    159. Property Y As Integer
    160. Property Direction As Direction
    161. End Class

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

    So nach einem Fehlschlag von Tag 17 ist Tag 18 wieder etwas leichter. Tag 17 hab ich nun eine Idee, die es aber noch zu probieren gilt.

    D18 Part 1

    VB.NET-Quellcode

    1. Sub Main()
    2. Dim input = IO.File.ReadAllLines(FilePathOfData)
    3. Dim instructions = input.Select(AddressOf ExtractInstruction).ToArray
    4. Dim isKonvex = False 'Ist unbestimmt, beides probieren.
    5. Dim directionary As New Dictionary(Of String, Integer()) From {
    6. {"R", {1, 0}},
    7. {"D", {0, 1}},
    8. {"L", {-1, 0}},
    9. {"U", {0, -1}}}
    10. Dim x = 0, y = 0
    11. Dim dirandlengthPrev, dirandlengthCur, dirandlengthNext As String()
    12. dirandlengthPrev = {instructions.Last()(0)}
    13. Dim coords As New List(Of Point) From {GetCorner(New Rectangle(x, y, 1, 1), dirandlengthPrev(0), instructions.First()(0), isKonvex)}
    14. For i = 0 To Input.Length - 2
    15. If i > 0 Then dirandlengthPrev = instructions(i - 1)
    16. dirandlengthCur = instructions(i)
    17. dirandlengthNext = instructions(i + 1)
    18. Dim dir = directionary(dirandlengthCur(0))
    19. Dim length = Integer.Parse(dirandlengthCur(1))
    20. x += dir(0) * length
    21. y += dir(1) * length
    22. Dim rect = New Rectangle(x, y, 1, 1)
    23. If dirandlengthNext(0) = dirandlengthPrev(0) Then isKonvex = Not isKonvex
    24. coords.Add(GetCorner(rect, dirandlengthCur(0), dirandlengthNext(0), isKonvex))
    25. Next
    26. Dim result = gausTrap(coords)
    27. End Sub
    28. Private Function GetCorner(rect As Rectangle, cur As String, nex As String, iskonv As Boolean) As Point
    29. If (cur = "R" AndAlso nex = "D") OrElse (cur = "U" AndAlso nex = "L") Then
    30. Return New Point(If(iskonv, rect.Right, rect.Left), If(iskonv, rect.Top, rect.Bottom))
    31. ElseIf (cur = "R" AndAlso nex = "U") OrElse (cur = "D" AndAlso nex = "L") Then
    32. Return New Point(If(iskonv, rect.Right, rect.Left), If(iskonv, rect.Bottom, rect.Top))
    33. ElseIf (cur = "L" AndAlso nex = "D") OrElse (cur = "U" AndAlso nex = "R") Then
    34. Return New Point(If(iskonv, rect.Left, rect.Right), If(iskonv, rect.Top, rect.Bottom))
    35. ElseIf (cur = "L" AndAlso nex = "U") OrElse (cur = "D" AndAlso nex = "R") Then
    36. Return New Point(If(iskonv, rect.Left, rect.Right), If(iskonv, rect.Bottom, rect.Top))
    37. End If
    38. Return Nothing
    39. End Function
    40. Private Function gausTrap(coords As IEnumerable(Of Point)) As Long
    41. Dim sum As Long
    42. For i = 0 To coords.Count - 1
    43. Dim ip = (i + 1) Mod coords.Count
    44. sum += (coords(i).Y + coords(ip).Y) * CLng(coords(i).X - coords(ip).X)
    45. Next
    46. Return CLng(Math.Abs(sum) / 2)
    47. End Function
    48. Private Function ExtractInstruction(input As String) As String()
    49. Return input.Split(" "c)
    50. End Function

    D18 Part 2
    Funktion ersetzen

    VB.NET-Quellcode

    1. Private Function ExtractInstruction(input As String) As String()
    2. Dim idx = input.IndexOf("#"c) + 1
    3. Dim dir As String
    4. Select Case input.Substring(idx + 5, 1)
    5. Case "0"
    6. dir = "R"
    7. Case "1"
    8. dir = "D"
    9. Case "2"
    10. dir = "L"
    11. Case Else
    12. dir = "U"
    13. End Select
    14. Dim length = Convert.ToInt32(input.Substring(idx, 5), 16).ToString
    15. Return {dir, length}
    16. End Function

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()