My solutions to 2018's advent of code
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
Ce dépôt est archivé. Vous pouvez voir les fichiers et le cloner, mais vous ne pouvez pas pousser ni ouvrir de ticket/demande d'ajout.

day16.nim 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import sequtils, strutils
  2. let ops = [
  3. proc(regs: seq[int], a,b: int): int = regs[a] + b,
  4. proc(regs: seq[int], a,b: int): int = regs[a] + regs[b],
  5. proc(regs: seq[int], a,b: int): int = regs[a] * b,
  6. proc(regs: seq[int], a,b: int): int = regs[a] * regs[b],
  7. proc(regs: seq[int], a,b: int): int = regs[a] and b,
  8. proc(regs: seq[int], a,b: int): int = regs[a] and regs[b],
  9. proc(regs: seq[int], a,b: int): int = regs[a] or b,
  10. proc(regs: seq[int], a,b: int): int = regs[a] or regs[b],
  11. proc(regs: seq[int], a,b: int): int = a,
  12. proc(regs: seq[int], a,b: int): int = regs[a],
  13. proc(regs: seq[int], a,b: int): int = cast[int](a > regs[b]),
  14. proc(regs: seq[int], a,b: int): int = cast[int](regs[a] > b),
  15. proc(regs: seq[int], a,b: int): int = cast[int](regs[a] > regs[b]),
  16. proc(regs: seq[int], a,b: int): int = cast[int](a == regs[b]),
  17. proc(regs: seq[int], a,b: int): int = cast[int](regs[a] == b),
  18. proc(regs: seq[int], a,b: int): int = cast[int](regs[a] == regs[b]),
  19. ]
  20. func toInstr(line: string): seq[int] = line.strip.split(" ").map(parseInt)
  21. func toRegisterSample(line: string): seq[int] = line.substr(9, line.len - 2).split(", ").map(parseInt)
  22. proc execute(regs: var seq[int], instr: seq[int], opcodes: array[16, proc(regs: seq[int], a,b: int): int]) =
  23. regs[instr[3]] = opcodes[instr[0]](regs, instr[1], instr[2])
  24. var
  25. before, instr, after: seq[int]
  26. opPossibilities: array[16, array[16, bool]]
  27. opMappings: array[16, proc(regs: seq[int], a,b: int): int]
  28. threeOrMore = 0
  29. step = 0
  30. registers = @[0, 0, 0, 0]
  31. for line in readFile("data/16.txt").splitlines:
  32. if step == 0 and line.len > 6 and line[0..5] == "Before":
  33. before = line.toRegisterSample
  34. step.inc
  35. elif step == 1:
  36. instr = line.toInstr
  37. step.inc
  38. elif step == 2:
  39. after = line.toRegisterSample
  40. var count = 0
  41. for i, op in ops:
  42. var actual: seq[int]
  43. actual.shallowCopy(before)
  44. actual[instr[3]] = op(before, instr[1], instr[2])
  45. if actual == after:
  46. count.inc
  47. else:
  48. opPossibilities[instr[0]][i] = true
  49. if count >= 3:
  50. threeOrMore.inc
  51. step = 0
  52. if step == 0 and line.len > 5 and line[0].isdigit:
  53. # First instruction found after the samples -- figure out which
  54. # opcode belongs to which...
  55. var found: array[16, bool]
  56. while not found.all(proc(v: bool): bool = v):
  57. for opcode, possibilities in opPossibilities:
  58. let matrix = zip(possibilities, found)
  59. if matrix.count((false, false)) == 1:
  60. let index = matrix.find((false, false))
  61. found[index] = true
  62. opMappings[opcode] = ops[index]
  63. step = -1
  64. if step == -1 and line.len > 5:
  65. registers.execute(line.toInstr, opMappings)
  66. echo threeOrMore
  67. echo registers[0]