Advertisement
hhoppe

Advent of code 2024 day 22 numpy fully vectorized

Dec 22nd, 2024 (edited)
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.35 KB | None | 0 0
  1. def day22c(s, *, part2=False, window_size=4, base=19):
  2.   vec = np.array(s.splitlines(), int)
  3.   n_inputs = len(vec)
  4.  
  5.   secret = np.empty((n_inputs, 2001), int)
  6.   for i in range(2001):
  7.     secret[:, i] = vec
  8.     vec = ((vec << 6) ^ vec) & 0xFFFFFF
  9.     vec = ((vec >> 5) ^ vec) & 0xFFFFFF
  10.     vec = ((vec << 11) ^ vec) & 0xFFFFFF
  11.  
  12.   if not part2:
  13.     return secret[:, -1].sum()
  14.  
  15.   digit = secret % 10
  16.   diffs2 = np.diff(digit, axis=1) + 9
  17.   score = digit[:, 4:]
  18.  
  19.   # Create sliding windows along axis 1; shape=[n_inputs, 1997, 4].
  20.   windows = np.lib.stride_tricks.sliding_window_view(diffs2, window_shape=window_size, axis=1)
  21.  
  22.   # Flatten each window into a scalar.
  23.   windows_flat = np.einsum('ijk,k->ij', windows, base ** np.arange(4))
  24.  
  25.   # Create a mask identifying all the first occurrences in each row.
  26.   index = np.argsort(windows_flat, axis=1, kind='stable')
  27.   sorted_windows = np.take_along_axis(windows_flat, index, axis=1)
  28.   is_different = np.diff(sorted_windows, axis=1, prepend=-1) != 0
  29.   mask = np.empty_like(windows_flat, bool)
  30.   np.put_along_axis(mask, index, is_different, axis=1)
  31.  
  32.   # Accumulate values into the totals array.
  33.   rows, cols = mask.nonzero()
  34.   flat_indices = windows_flat[rows, cols]
  35.   values = score[rows, cols]
  36.  
  37.   totals = np.zeros(base**4, int)
  38.   np.add.at(totals, flat_indices, values)
  39.   return totals.max()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement