Code for the Advent of Code event
aoc
advent-of-code
1# frozen_string_literal: true
2
3module Utils
4 class << self
5 def crt(mods, remainders)
6 max = mods.inject(:*) # product of all moduli
7 series = remainders.zip(mods).map { |r, m| (r * max * invmod(max / m, m) / m) }
8 series.inject(:+) % max
9 end
10
11 private
12
13 def extended_gcd(a, b)
14 last_remainder, remainder = a.abs, b.abs
15 x, last_x, y, last_y = 0, 1, 1, 0
16 while remainder != 0
17 last_remainder, (quotient, remainder) = remainder, last_remainder.divmod(remainder)
18 x, last_x = last_x - (quotient * x), x
19 y, last_y = last_y - (quotient * y), y
20 end
21 [last_remainder, last_x * (a < 0 ? -1 : 1)]
22 end
23
24 def invmod(e, et)
25 g, x = extended_gcd(e, et)
26 raise 'Multiplicative inverse modulo does not exist!' if g != 1
27 x % et
28 end
29 end
30end
31
32module Enumerable
33 def mean
34 sum.to_f / size
35 end
36
37 def median
38 return self[size / 2] if size.odd?
39 (self[(size / 2) - 1] + self[size / 2]) / 2.0
40 end
41end