illuminati229

AoC Day 10

Dec 10th, 2021 (edited)
238
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.95 KB | None | 0 0
  1. def char_score(char):
  2.     if char == ')':
  3.         return 3
  4.     elif char == ']':
  5.         return 57
  6.     elif char == '}':
  7.         return 1197
  8.     elif char == '>':
  9.         return 25137
  10.     else:
  11.         return -1
  12.  
  13. def line_score(line):
  14.     score = 0
  15.     score_dict = {
  16.         ')': 1,
  17.         ']': 2,
  18.         '}': 3,
  19.         '>': 4}
  20.     for char in line:
  21.         score = score * 5 + score_dict[char]
  22.  
  23.     return score
  24.  
  25. def flip_char(char):
  26.     if char == '(':
  27.         return ')'
  28.     elif char == '[':
  29.         return ']'
  30.     elif char == '{':
  31.         return '}'
  32.     elif char == '<':
  33.         return '>'
  34.     else:
  35.         return '!'
  36.    
  37. def matched_set(a,b):
  38.     opens = ['(', '<', '{', '[']
  39.     closes = [')', '>', '}', ']']
  40.  
  41.     if opens.index(a) == closes.index(b):
  42.         return True
  43.     else:
  44.         return False
  45.  
  46. def syntax_score(file_path, bad_only):
  47.  
  48.     with open(file_path) as fin:
  49.         chunk_lines = [x.strip() for x in fin.readlines()]
  50.  
  51.     matched = [([False] * len(row)) for row in chunk_lines]
  52.  
  53.     opens = ['(', '<', '{', '[']
  54.     closes = [')', '>', '}', ']']
  55.  
  56.     bad_chars = []
  57.     bad_lines = []
  58.  
  59.     for r_i in range(len(chunk_lines)):
  60.         for c_i in range(len(chunk_lines[r_i])):
  61.             char = chunk_lines[r_i][c_i]
  62.             if char in closes:
  63.                 offset = 1
  64.                 try:
  65.                     while matched[r_i][c_i - offset]:
  66.                         if offset > c_i:
  67.                             print('Offset greater than c_o')
  68.                         else:
  69.                             offset += 1
  70.                 except:
  71.                     print(r_i,c_i, offset)
  72.  
  73.                 if not matched_set(chunk_lines[r_i][c_i - offset], char):
  74.                     bad_chars.append(char)
  75.                     bad_lines.append(r_i)
  76.                     break
  77.                 elif matched_set(chunk_lines[r_i][c_i - offset], char):
  78.                     matched[r_i][c_i] = True
  79.                     matched[r_i][c_i - offset] = True
  80.  
  81.     if bad_only:
  82.         score = 0
  83.         for char in bad_chars:
  84.             score += char_score(char)
  85.         return score
  86.  
  87.     bad_lines.reverse()
  88.     for line in bad_lines:
  89.         chunk_lines.pop(line)
  90.         matched.pop(line)
  91.  
  92.  
  93.     com_string = [[] for line in chunk_lines]
  94.    
  95.     for r_i in range(len(chunk_lines)):
  96.         for c_i in range(len(chunk_lines[r_i])):
  97.             if not matched[r_i][c_i]:
  98.                 com_string[r_i].append(flip_char(chunk_lines[r_i][c_i]))
  99.         com_string[r_i].reverse()
  100.  
  101.     score = []
  102.    
  103.     for line in com_string:
  104.         score.append(line_score(line))
  105.  
  106.     score.sort()
  107.     half = (len(score) + 1) // 2
  108.    
  109.     return score[half - 1]
  110.    
  111. if __name__ == '__main__':
  112.  
  113.     assert syntax_score('test_input.txt', True) == 26397
  114.     print(syntax_score('input.txt', True))
  115.  
  116.     assert syntax_score('test_input.txt', False) == 288957
  117.     print(syntax_score('input.txt', False))
  118.  
Add Comment
Please, Sign In to add comment