Advertisement
Guest User

Untitled

a guest
Dec 21st, 2024
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.27 KB | None | 0 0
  1. # Input: three-digit numbers followed by "A"
  2. # Output: using three tiers of directional keypads
  3. #            ^A
  4. #           <v>
  5. #         (A = push button), get a numeric keypad
  6. #           789
  7. #           456
  8. #           123
  9. #            0A
  10. #         to type each line (while never pointing to a gap)
  11. #         find sum of (shortest sequence * three-digit number)
  12.  
  13. import itertools
  14.  
  15. from functools import cache
  16.  
  17. lines = []
  18.  
  19. file = open("21_input.txt", "r")
  20. for line in file:
  21.   line = line.replace("\n", "")
  22.   lines.append(line)
  23.  
  24. dk_keys = {} # key = character, value = [row, column]
  25. dk_keys[" "] = [0, 0]
  26. dk_keys["^"] = [0, 1]
  27. dk_keys["A"] = [0, 2]
  28. dk_keys["<"] = [1, 0]
  29. dk_keys["v"] = [1, 1]
  30. dk_keys[">"] = [1, 2]
  31.  
  32. nk_keys = {}
  33. nk_keys["7"] = [0, 0]
  34. nk_keys["8"] = [0, 1]
  35. nk_keys["9"] = [0, 2]
  36. nk_keys["4"] = [1, 0]
  37. nk_keys["5"] = [1, 1]
  38. nk_keys["6"] = [1, 2]
  39. nk_keys["1"] = [2, 0]
  40. nk_keys["2"] = [2, 1]
  41. nk_keys["3"] = [2, 2]
  42. nk_keys[" "] = [3, 0]
  43. nk_keys["0"] = [3, 1]
  44. nk_keys["A"] = [3, 2]
  45.  
  46. # assumption: longer sequence of presses never has lower cost
  47.  
  48. def get_sequences(dict):
  49.   derived_dict = {}
  50.   for current in dict:
  51.     if current == " ":
  52.       continue
  53.     for goal in dict:
  54.       if goal == " ":
  55.         continue
  56.       cr, cc = dict[current][0], dict[current][1]
  57.       gr, gc = dict[goal][0], dict[goal][1]
  58.       keys_to_press = []
  59.       for r in range(abs(cr - gr)):
  60.         if cr > gr:
  61.           keys_to_press.append("^")
  62.         if cr < gr:
  63.           keys_to_press.append("v")
  64.       for c in range(abs(cc - gc)):
  65.         if cc > gc:
  66.           keys_to_press.append("<")
  67.         if cc < gc:
  68.           keys_to_press.append(">")
  69.       options = []
  70.       for key_permutation in list(itertools.permutations(keys_to_press)):
  71.         # if it crosses a gap, then omit it
  72.         r, c = cr, cc
  73.         key_list_valid = True
  74.         key_list = ""
  75.         for key in key_permutation:
  76.           if key == "^":
  77.             r -= 1
  78.           if key == "v":
  79.             r += 1
  80.           if key == "<":
  81.             c -= 1
  82.           if key == ">":
  83.             c += 1
  84.           if r == dict[" "][0] and c == dict[" "][1]:
  85.             key_list_valid = False
  86.             break
  87.           key_list += key
  88.         if key_list_valid:
  89.           options.append(key_list)
  90.       derived_dict[current + goal] = options
  91.   return derived_dict
  92.  
  93. d2d = get_sequences(dk_keys)
  94. n2d = get_sequences(nk_keys)
  95.  
  96. @cache
  97. def get_all_sub_sequences(str, use_n2d):
  98.   dict = d2d
  99.   if use_n2d:
  100.     dict = n2d
  101.   if len(str) == 1:
  102.     return [""]
  103.   options = []
  104.   for next_step in dict[str[:2]]:
  105.     for rest_of_steps in get_all_sub_sequences(str[1:], use_n2d):
  106.       options.append(next_step + "A" + rest_of_steps)
  107.   return list(set(options))
  108.  
  109. @cache
  110. def get_all_sequences(str, use_n2d):
  111.   return get_all_sub_sequences("A" + str, use_n2d)
  112.  
  113. total = 0
  114. for line in lines:
  115.   code = int(line.replace("A", ""))
  116.   options = get_all_sequences(line, True)
  117.   shortest_option = -1
  118.   for option in options:
  119.     for option2 in get_all_sequences(option, False):
  120.       for option3 in get_all_sequences(option2, False):
  121.         if shortest_option == -1 or shortest_option > len(option3):
  122.           shortest_option = len(option3)
  123.   total += code * shortest_option
  124. print (total)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement