205 lines
4.2 KiB
C++
205 lines
4.2 KiB
C++
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
#include <sstream>
|
||
|
#include <vector>
|
||
|
#include <tuple>
|
||
|
#include <set>
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
#define DBG(str) do { std::cout << str << std::endl; } while( false )
|
||
|
#else
|
||
|
#define DBG(str) do { } while ( false )
|
||
|
#endif
|
||
|
|
||
|
vector<vector<int>> parseGames(const char *path) {
|
||
|
vector<vector<int>> games;
|
||
|
|
||
|
ifstream input(path);
|
||
|
string line1;
|
||
|
string line2;
|
||
|
string line3;
|
||
|
|
||
|
while(getline(input, line1)) {
|
||
|
if (line1 == "") continue;
|
||
|
|
||
|
vector<int> game;
|
||
|
getline(input, line2);
|
||
|
getline(input, line3);
|
||
|
|
||
|
stringstream ss1;
|
||
|
stringstream ss2;
|
||
|
stringstream ss3;
|
||
|
ss1 << line1;
|
||
|
ss2 << line2;
|
||
|
ss3 << line3;
|
||
|
|
||
|
int a;
|
||
|
|
||
|
// button A
|
||
|
char c = 1;
|
||
|
while(c && c != '+') {
|
||
|
ss1 >> c;
|
||
|
}
|
||
|
ss1 >> a;
|
||
|
game.push_back(a);
|
||
|
|
||
|
c = 1;
|
||
|
while(c && c != '+') {
|
||
|
ss1 >> c;
|
||
|
}
|
||
|
ss1 >> a;
|
||
|
game.push_back(a);
|
||
|
|
||
|
// button B
|
||
|
c = 1;
|
||
|
while(c && c != '+') {
|
||
|
ss2 >> c;
|
||
|
}
|
||
|
ss2 >> a;
|
||
|
game.push_back(a);
|
||
|
|
||
|
c = 1;
|
||
|
while(c && c != '+') {
|
||
|
ss2 >> c;
|
||
|
}
|
||
|
ss2 >> a;
|
||
|
game.push_back(a);
|
||
|
|
||
|
// prize
|
||
|
c = 1;
|
||
|
while(c && c != '=') {
|
||
|
ss3 >> c;
|
||
|
}
|
||
|
ss3 >> a;
|
||
|
game.push_back(a);
|
||
|
|
||
|
c = 1;
|
||
|
while(c && c != '=') {
|
||
|
ss3 >> c;
|
||
|
}
|
||
|
ss3 >> a;
|
||
|
game.push_back(a);
|
||
|
|
||
|
games.push_back(game);
|
||
|
}
|
||
|
|
||
|
return games;
|
||
|
}
|
||
|
|
||
|
// long cheapest = __LONG_MAX__;
|
||
|
|
||
|
// bool playGame(vector<int> game, int as, int bs, int curr_x, int curr_y) {
|
||
|
// int a_x = game[0];
|
||
|
// int a_y = game[1];
|
||
|
// int b_x = game[2];
|
||
|
// int b_y = game[3];
|
||
|
// int prize_x = game[4];
|
||
|
// int prize_y = game[5];
|
||
|
|
||
|
// bool found_result = false;
|
||
|
|
||
|
// cout << "curr_x=" << curr_x << " curr_y=" << curr_y << " as=" << as << " bs=" << bs << endl;
|
||
|
|
||
|
// // base case
|
||
|
// if (curr_x == prize_x && curr_y == prize_y) {
|
||
|
// if (as * 3 + bs < cheapest) cheapest = as * 3 + bs;
|
||
|
// return true;
|
||
|
// }
|
||
|
// if (curr_x > prize_x || curr_y > prize_y || as > 100 || bs > 100) return false;
|
||
|
|
||
|
// // try A
|
||
|
// if (playGame(game, as + 1, bs, curr_x + a_x, curr_y + a_y)) found_result = true;
|
||
|
|
||
|
|
||
|
// // try B
|
||
|
// if (playGame(game, as, bs + 1, curr_x + b_x, curr_y + b_y)) found_result = true;
|
||
|
|
||
|
// return found_result;
|
||
|
// }
|
||
|
|
||
|
// void printGames(vector<vector<int>> games) {
|
||
|
// for (auto game : games) {
|
||
|
// cout << "Button A: X+" << game[0] << ", Y+" << game[1] << endl;
|
||
|
// cout << "Button B: X+" << game[2] << ", Y+" << game[3] << endl;
|
||
|
// cout << "Prize: X=" << game[4] << ", Y=" << game[5] << endl;
|
||
|
// cout << endl;
|
||
|
// }
|
||
|
// }
|
||
|
|
||
|
unsigned long long playGame(vector<int> game, bool part2 = false) {
|
||
|
int a_x = game[0];
|
||
|
int a_y = game[1];
|
||
|
int b_x = game[2];
|
||
|
int b_y = game[3];
|
||
|
unsigned long long prize_x = game[4];
|
||
|
unsigned long long prize_y = game[5];
|
||
|
|
||
|
if (!part2) {
|
||
|
for (long bs = 0; bs < 100; bs++) {
|
||
|
for (long as = 0; as < 100; as++) {
|
||
|
if (as * a_x + bs * b_x == prize_x && as * a_y + bs * b_y == prize_y) {
|
||
|
return 3 * as + bs;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (part2) {
|
||
|
prize_x += 10000000000000l;
|
||
|
prize_y += 10000000000000l;
|
||
|
|
||
|
|
||
|
long numeratorX = prize_x*b_y - prize_y*b_x;
|
||
|
long denominatorX = a_x*b_y - a_y*b_x;
|
||
|
|
||
|
long numeratorY = prize_x*a_y - prize_y*a_x;
|
||
|
long denominatorY = a_y*b_x - a_x*b_y;
|
||
|
|
||
|
long a = numeratorX / denominatorX;
|
||
|
long b = numeratorY / denominatorY;
|
||
|
|
||
|
if (a * a_x + b * b_x != prize_x || a * a_y + b * b_y != prize_y) return 0;
|
||
|
return a * 3 + b;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int part1(const char *path) {
|
||
|
vector<vector<int>> games = parseGames(path);
|
||
|
// printGames(games);
|
||
|
|
||
|
int tokens = 0;
|
||
|
|
||
|
for (auto game : games) {
|
||
|
tokens += playGame(game);
|
||
|
}
|
||
|
|
||
|
return tokens;
|
||
|
}
|
||
|
|
||
|
unsigned long long part2(const char *path) {
|
||
|
vector<vector<int>> games = parseGames(path);
|
||
|
|
||
|
unsigned long long tokens = 0;
|
||
|
|
||
|
for (auto game : games) {
|
||
|
tokens += playGame(game, true);
|
||
|
}
|
||
|
|
||
|
return tokens;
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[]) {
|
||
|
int example1 = part1("example");
|
||
|
cout << "example1: " << example1 << endl;
|
||
|
int input1 = part1("input");
|
||
|
cout << "input1: " << input1 << endl;
|
||
|
|
||
|
unsigned long long example2 = part2("example");
|
||
|
cout << "example2: " << example2 << endl;
|
||
|
unsigned long long input2 = part2("input");
|
||
|
cout << "input2: " << input2 << endl;
|
||
|
return 0;
|
||
|
}
|