day_13
Parsing
First, we need to split the lines into blocks describing each claw machine. We can do this by splitting the input by the empty line. Next, we need to parse each block. This is easily done by
- assuming that each block has three lines
- some regex.
Checking for solvability
To decide whether a claw machine can be solved, we need to find out whether the vector of the prize can be formed by any linear combination of the vectors described by button A and B (And whether the sum of the linear factors is less than 100).
Finding the optimal path
Finally, to find the optimal path (linear combination), we can take the list of all possible combinations and sort it by assigning scores to each linear combination:
- Three times the linear factor of A + the linear factor of B The linear combination with the lowest score is our optimal path.
k * ax + l * bx = x k * ay + l * by = y ( ax bx ) times (k) = (x) ( ay by ) (l) (y) x * by -y * bx = k * axby - ayby) y * ax - x * ay = l * (axby - aybx)
Types
A claw machine consist of three tuples of integers:
- The x and y movement of button A
- The x and y movement of button B
- The x and y coordinates of the prize
pub type ClawMachine {
ClawMachine(a: Position, b: Position, prize: Position)
}
Constructors
-
ClawMachine(a: Position, b: Position, prize: Position)
Functions
pub fn add_to_position(
position: Position,
value: Int,
) -> Position
pub fn parse_block(
block: List(String),
prize_offset: Int,
) -> Result(ClawMachine, Nil)
Parse a block containing three lines (‘Button A:’, ‘Button B:’ & Prize:)
pub fn parse_button(line: String) -> Result(Position, Nil)
Parse a line containing button information
pub fn parse_input(
lines: List(String),
result: List(Result(ClawMachine, Nil)),
prize_offset: Int,
) -> List(Result(ClawMachine, Nil))
Parse lines of text into a list of ClawMachines
pub fn parse_prize(
line: String,
prize_offset: Int,
) -> Result(Position, Nil)
Parse a line containing Prize information
pub fn solve_machine(machine: ClawMachine) -> Int
Solve the linear equation given by a_count * (a.x, a.y) + b_count * (b.x, b.y) = (prize.x, prize.y)
After solving, double check whether the solutions fit or wheter there’s a rounding error.
Then, return the score of the solution as speficied. (3 * a_count + b_count
)
pub fn strings_to_position(
raw_x: String,
raw_y: String,
) -> Result(Position, Nil)
Parse two strings into a positon