|  | 
|  | 1 | +import type { Point } from '@/aoc/point/types.js' | 
|  | 2 | + | 
|  | 3 | +/** | 
|  | 4 | + * Counts the determinant of a 2x2 coefficient matrix. Currently only works with a 2x2 number matrix. | 
|  | 5 | + * TO-DO: Support N-size matrices. | 
|  | 6 | + * @param {number[][]} matrix - 2D number matrix input | 
|  | 7 | + * @returns {number} Determinant of a 2x2 matrix | 
|  | 8 | + */ | 
|  | 9 | +export const getDeterminant = (matrix: number[][]): number => { | 
|  | 10 | +  const eq1 = matrix[0] as number[] | 
|  | 11 | +  const eq2 = matrix[1] as number[] | 
|  | 12 | + | 
|  | 13 | +  return ((eq1[0] as number) * (eq2[1] as number)) - | 
|  | 14 | +    ((eq1[1] as number) * (eq2[0] as number)) | 
|  | 15 | +} | 
|  | 16 | + | 
|  | 17 | +/** | 
|  | 18 | + * Builds a coefficient matrix by replacing column values with the constants. | 
|  | 19 | + * Currently only works with a 2x2 number matrix. TO-DO: Support N-size matrices. | 
|  | 20 | + * @param {number[][]} matrix - 2D number matrix input | 
|  | 21 | + * @param {number} column - Matrix column index to replace with constants. Index starts at `0`. | 
|  | 22 | + * @returns {number[][]} Coefficient matrix | 
|  | 23 | + */ | 
|  | 24 | +export const coefficientMatrix = ( | 
|  | 25 | +  matrix: number[][], | 
|  | 26 | +  column: number = 0 | 
|  | 27 | +): number[][] => { | 
|  | 28 | +  const maxCol = 2 | 
|  | 29 | + | 
|  | 30 | +  return matrix.reduce((list: number[][], row, y) => { | 
|  | 31 | +    const items = row.reduce((sublist: number[], item, x) => { | 
|  | 32 | +      if (x === column) { | 
|  | 33 | +        sublist.push(matrix[y]![maxCol] as number) | 
|  | 34 | +      } else if (x !== maxCol) { | 
|  | 35 | +        sublist.push(item) | 
|  | 36 | +      } | 
|  | 37 | +      return sublist | 
|  | 38 | +    }, []) | 
|  | 39 | +    return [...list, items] | 
|  | 40 | +  }, []) | 
|  | 41 | +} | 
|  | 42 | + | 
|  | 43 | +/** | 
|  | 44 | + * Calculates the number of needed (x,y) button A "and" B presses to reach the prize | 
|  | 45 | + * by solving the 2 equations using Cramer's Rule. | 
|  | 46 | + * https://www.youtube.com/watch?v=RdLo-9jh2EM. Currently only works with a 2x2 number matrix. | 
|  | 47 | + * @param {number[][]} matrix - 2D number matrix input | 
|  | 48 | + * @returns {Point} Object containing the number of `x` and `y` button presses | 
|  | 49 | + */ | 
|  | 50 | +export const solveEquation = (matrix: number[][]): Point => { | 
|  | 51 | +  const determinant = getDeterminant(matrix) | 
|  | 52 | + | 
|  | 53 | +  const xCoefficient = coefficientMatrix(matrix, 0) | 
|  | 54 | +  const yCoefficient = coefficientMatrix(matrix, 1) | 
|  | 55 | + | 
|  | 56 | +  const xD = getDeterminant(xCoefficient) | 
|  | 57 | +  const yD = getDeterminant(yCoefficient) | 
|  | 58 | + | 
|  | 59 | +  const x = xD / determinant | 
|  | 60 | +  const y = yD / determinant | 
|  | 61 | + | 
|  | 62 | +  return { x, y } | 
|  | 63 | +} | 
0 commit comments