This commit is contained in:
zv0n 2021-12-17 09:47:05 +01:00
parent 6301b1f90c
commit ac58465ce2
3 changed files with 144 additions and 0 deletions

22
17/CMakeLists.txt Normal file
View File

@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
enable_language(CXX)
project(AoC17)
if(APPLE)
include_directories(/usr/local/include)
link_directories(/usr/local/lib)
endif()
if(WIN32)
add_executable(${CMAKE_PROJECT_NAME} WIN32)
else()
add_executable(${CMAKE_PROJECT_NAME})
endif()
target_sources(${CMAKE_PROJECT_NAME}
PRIVATE main.cpp
)

1
17/input Normal file
View File

@ -0,0 +1 @@
target area: x=209..238, y=-86..-59

121
17/main.cpp Normal file
View File

@ -0,0 +1,121 @@
#include <algorithm>
#include <deque>
#include <fstream>
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using Area = std::pair<std::pair<long, long>, std::pair<long, long>>;
Area getTargetArea(const std::string &file_name) {
Area area{};
std::ifstream file(file_name);
std::string str;
std::getline(file, str);
std::stringstream ss(str);
std::string tmp;
char tmp_char;
long x1, x2, y1, y2;
ss >> tmp;
ss >> tmp;
ss >> tmp_char;
ss >> tmp_char;
ss >> x1;
ss >> tmp_char;
ss >> tmp_char;
ss >> x2;
ss >> tmp_char;
ss >> tmp_char;
ss >> tmp_char;
ss >> y1;
ss >> tmp_char;
ss >> tmp_char;
ss >> y2;
if (x1 < x2) {
area.first = { x1, x2 };
} else {
area.first = { x2, x1 };
}
if (y1 < y2) {
area.second = { y1, y2 };
} else {
area.second = { y2, y1 };
}
return area;
}
uint64_t sumUntilN(uint64_t n) {
return (n * (n + 1)) / 2;
}
long getMaxYSpeed(long lowest_area_y) {
return abs(lowest_area_y) - 1;
}
uint64_t part1(const Area &area) {
return sumUntilN(getMaxYSpeed(area.second.first));
}
bool willEverReach(long min_x, long max_x, long min_y, long max_y,
long initial_x, long initial_y) {
std::pair<long, long> pos = { 0, 0 };
while (true) {
pos.first += initial_x;
pos.second += initial_y;
if (pos.first >= min_x && pos.first <= max_x && pos.second <= min_y &&
pos.second >= max_y) {
return true;
}
if (initial_x == 0 && pos.first < min_x) {
break;
}
if (pos.first > max_x) {
break;
}
if (pos.second < max_y) {
break;
}
if (initial_x > 0) {
initial_x--;
}
initial_y--;
}
return false;
}
uint64_t part2(Area &area) {
uint64_t valid_trajectory = 0;
auto max_dist_y = abs(area.second.first);
auto max_dist_x = area.first.second;
for (long y = getMaxYSpeed(area.second.first); y >= area.second.first;
y--) {
for (long x = 0; x <= area.first.second; x++) {
if (willEverReach(area.first.first, area.first.second,
area.second.second, area.second.first, x, y)) {
valid_trajectory++;
}
}
}
return valid_trajectory;
}
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << "You must provide input file!" << std::endl;
return 1;
}
auto area = getTargetArea(argv[1]);
std::cout << "The highest possible y is \033[91;1m" << part1(area)
<< "\033[0m." << std::endl;
std::cout << "There are \033[91;1m" << part2(area)
<< "\033[0m possible trajectories." << std::endl;
return 0;
}