Advertisement
illuminati229

AoC Day 17

Dec 17th, 2021
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.76 KB | None | 0 0
  1. from numpy import ceil, sqrt
  2.  
  3. def read_target(file_path):
  4.  
  5.     with open(file_path) as fin:
  6.         line = fin.readline().strip()[15:]
  7.     x_r, y_r = [(int(part.split('..')[0]), int(part.split('..')[1]))  for part in line.split(', y=')]
  8.     return range(x_r[0], x_r[1] + 1), range(y_r[0], y_r[1] + 1)
  9.  
  10. def hit_target(v_x, v_y, x_r, y_r):
  11.     # This only works for positive x target ranges
  12.    
  13.     if min(x_r) < 0:
  14.         raise Exception('x target range is negative')
  15.    
  16.     x = 0
  17.     y = 0
  18.  
  19.     while x < max(x_r) and y > min(y_r):
  20.         x += v_x
  21.         y += v_y
  22.         if v_x > 0:
  23.             v_x -= 1
  24.         v_y -= 1
  25.        
  26.         if x in x_r and y in y_r:
  27.             return True
  28.  
  29.     return False
  30.        
  31.  
  32. def part1(file_path):
  33.     # This only works for y target ranges that are completely negative
  34.    
  35.     x_r, y_r = read_target(file_path)
  36.  
  37.     if max(y_r) > 0:
  38.         raise Exception('y target range is positive.')
  39.  
  40.     n = abs(min(y_r)) - 1
  41.  
  42.     return (n * (n + 1)) // 2
  43.  
  44. def part2(file_path):
  45.     # This only works for y target ranges that are completely negative
  46.  
  47.     x_r, y_r = read_target(file_path)
  48.  
  49.     if max(y_r) > 0:
  50.         raise Exception('y target range is positive.')
  51.  
  52.     v_x_min = int(ceil((-1 + sqrt(1 - 4 * (-2 * min(x_r)))) / 2))
  53.  
  54.     v_x_r = range(v_x_min,max(x_r)+ 1)
  55.  
  56.     v_y_r = range(min(y_r), abs(min(y_r)))
  57.  
  58.     hit_count = 0
  59.  
  60.     for v_x in v_x_r:
  61.         for v_y in v_y_r:
  62.             if hit_target(v_x, v_y, x_r, y_r):
  63.                 hit_count += 1
  64.  
  65.     return hit_count
  66.    
  67.  
  68.  
  69. def main():
  70.  
  71.     assert part1('test_input.txt') == 45
  72.     print(part1('input.txt'))
  73.  
  74.     assert part2('test_input.txt') == 112
  75.     print(part2('input.txt'))
  76.  
  77.  
  78. if __name__ == '__main__':
  79.     main()
  80.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement