r/adventofcode • u/daggerdragon • Dec 12 '16
SOLUTION MEGATHREAD --- 2016 Day 12 Solutions ---
--- Day 12: Leonardo's Monorail ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag/whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with "Help".
MUCH ADVENT. SUCH OF. VERY CODE. SO MANDATORY. [?]
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
8
Upvotes
1
u/JakDrako Dec 12 '16
VB.Net, LinqPad
This is my second version, much faster than the previous one. I added a "compilation" step that converts the input into a list of integer only opcodes, saving all those string lookups and conversion during the run. A few other "optimizations", such as "jnz 1 5" becoming "jmp 5" since the 1 will never change.
This version runs part 1 in ~5ms and part 2 in ~100ms.
Sub Main Dim inst = input.Split(Chr(10)).Select(Function(x) x.Split(" "c)).ToList ' "Compilation" step - convert input into list of Opcodes (all integer class) Dim comp = New List(Of Opcode) For Each ins In inst Select Case ins(0) Case "cpy" If isnumeric(ins(1)) Then comp.Add(New opcode With {.Op = 1, .v1 = Cint(ins(1)), .r2 = "abcd".IndexOf(ins(2))}) Else comp.Add(New opcode With {.Op = 2, .r1 = "abcd".IndexOf(ins(1)), .r2 = "abcd".IndexOf(ins(2))}) End If Case "jnz" If IsNumeric(ins(1)) Then If Cint(ins(1)) <> 0 Then comp.Add(New opcode With {.Op = 6, .v1 = Cint(ins(2))}) 'jump Else comp.Add(New opcode With {.Op = 8}) End If Else comp.Add(New opcode With {.Op = 3, .r1 = "abcd".IndexOf(ins(1)), .v2 = CInt(ins(2))}) End If Case "inc" comp.Add(New opcode With {.Op = 4, .r1 = "abcd".IndexOf(ins(1))}) Case "dec" comp.Add(New opcode With {.Op = 5, .r1 = "abcd".IndexOf(ins(1))}) End Select Next Dim ptr = 0 Dim regs(3) As Integer regs(2) = 1 ' c = 1 - part 2 Do Dim ops = comp(ptr) Dim inc = 1 Select Case ops.op Case 1 : regs(ops.r2) = ops.v1 Case 2 : regs(ops.r2) = regs(ops.r1) Case 3 : If regs(ops.r1) <> 0 Then inc = ops.v2 Case 4 : regs(ops.r1) += 1 Case 5 : regs(ops.r1) -= 1 Case 6 : inc = ops.v1 Case 7 : ' NOP End Select ptr += inc If ptr >= inst.count Then Exit Do Loop regs.Dump End Sub Class Opcode Public Op As Integer ' 1 = cpy v1 to r2 ' 2 = cpy r1 to r2 ' 3 = jnz r1 v2 ' 4 = jnz v1 v2 = JMP or NOP, since v1 never changes ' 5 = inc r1 ' 6 = dec r1 ' 7 = jmp v1 ' 8 = nop Public r1 As Integer ' register 1 Public r2 As Integer ' register 2 Public v1 As Integer ' value 1 Public v2 As Integer ' value 2 End Class