Benjamin Kraft 9 months ago
commit 3d18c831b2
  1. 6
      .gitignore
  2. 18
      CMakeLists.txt
  3. 33
      README.md
  4. 17
      fill.py
  5. 9
      pre.cpp
  6. 10
      pre.h
  7. 40
      src/Day.h
  8. 9
      src/days/01/Day01.cpp
  9. 10
      src/days/01/Day01.h
  10. 9
      src/days/02/Day02.cpp
  11. 10
      src/days/02/Day02.h
  12. 9
      src/days/03/Day03.cpp
  13. 10
      src/days/03/Day03.h
  14. 9
      src/days/04/Day04.cpp
  15. 10
      src/days/04/Day04.h
  16. 9
      src/days/05/Day05.cpp
  17. 10
      src/days/05/Day05.h
  18. 9
      src/days/06/Day06.cpp
  19. 10
      src/days/06/Day06.h
  20. 9
      src/days/07/Day07.cpp
  21. 10
      src/days/07/Day07.h
  22. 9
      src/days/08/Day08.cpp
  23. 10
      src/days/08/Day08.h
  24. 9
      src/days/09/Day09.cpp
  25. 10
      src/days/09/Day09.h
  26. 9
      src/days/10/Day10.cpp
  27. 10
      src/days/10/Day10.h
  28. 9
      src/days/11/Day11.cpp
  29. 10
      src/days/11/Day11.h
  30. 9
      src/days/12/Day12.cpp
  31. 10
      src/days/12/Day12.h
  32. 9
      src/days/13/Day13.cpp
  33. 10
      src/days/13/Day13.h
  34. 9
      src/days/14/Day14.cpp
  35. 10
      src/days/14/Day14.h
  36. 9
      src/days/15/Day15.cpp
  37. 10
      src/days/15/Day15.h
  38. 9
      src/days/16/Day16.cpp
  39. 10
      src/days/16/Day16.h
  40. 9
      src/days/17/Day17.cpp
  41. 10
      src/days/17/Day17.h
  42. 9
      src/days/18/Day18.cpp
  43. 10
      src/days/18/Day18.h
  44. 9
      src/days/19/Day19.cpp
  45. 10
      src/days/19/Day19.h
  46. 9
      src/days/20/Day20.cpp
  47. 10
      src/days/20/Day20.h
  48. 9
      src/days/21/Day21.cpp
  49. 10
      src/days/21/Day21.h
  50. 9
      src/days/22/Day22.cpp
  51. 10
      src/days/22/Day22.h
  52. 9
      src/days/23/Day23.cpp
  53. 10
      src/days/23/Day23.h
  54. 9
      src/days/24/Day24.cpp
  55. 10
      src/days/24/Day24.h
  56. 9
      src/days/25/Day25.cpp
  57. 10
      src/days/25/Day25.h
  58. 57
      src/days/days.h
  59. 96
      src/main.cpp
  60. 42
      src/util.h

6
.gitignore vendored

@ -0,0 +1,6 @@
/cmake-build-debug/
session
/input/
/xtensor/
/xtl/
.idea

@ -0,0 +1,18 @@
cmake_minimum_required(VERSION 3.20)
project(AdventOfCode2023)
set(CMAKE_CXX_STANDARD 23)
if (WIN32)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
endif()
file(GLOB_RECURSE SRC_FILES src/**.cpp)
add_executable(AdventOfCode2023 ${SRC_FILES})
include(FetchContent)
FetchContent_Declare(cpr GIT_REPOSITORY https://github.com/libcpr/cpr.git GIT_TAG 100cf2050be7619430a615cd0d580b33c62fde6b)
FetchContent_MakeAvailable(cpr)
target_link_libraries(AdventOfCode2023 cpr::cpr)

@ -0,0 +1,33 @@
## Advent Of Code 2022 C++ Solutions
#### Build with CMakeLists.txt
#### Run:
Place a file called "session" with your session key cookie from https://adventofcode.com/ inside the Working Directory.
Expects runtime arguments as days, for example:
"5 9 1" executes Days 5, 9, 1 in this order.
#### Test Inputs
Add argument "T" after each Day to use XX_testInput.txt rather than XX_input.txt
For Test-Inputs, it tries to fetch the content of the first code-Tag. You can control this by adding the index of the desired code-Tag.
Example:
"3T 6T1 9"
- Day 3 with content from inside the first code-Tag
- Day 6 with content from inside the second code-Tag
- Day 9 with regular input
#### Get index with Browser Dev Tools:
Select the correct code-Tag in the inspector, then paste this into the console:
<code>
Array.from(document.getElementsByTagName("code")).indexOf($0)
</code>

@ -0,0 +1,17 @@
import os
preH = open("pre.h", "r").read()
preCpp = open("pre.cpp", "r").read()
for dayNum in range(1, 26):
pad = f'{dayNum:02}'
dirName = f"src/days/{pad}"
try:
os.mkdir(dirName)
except OSError:
pass
with open(f"{dirName}/Day{pad}.h", "w") as file:
file.write(preH.replace("XX", pad))
with open(f"{dirName}/Day{pad}.cpp", "w") as file:
file.write(preCpp.replace("XX", pad))

@ -0,0 +1,9 @@
#include "DayXX.h"
Result DayXX::Task1() {
return Day::Task1();
}
Result DayXX::Task2() {
return Day::Task2();
}

10
pre.h

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class DayXX : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,40 @@
#pragma once
#include <chrono>
#include "util.h"
using namespace std::chrono;
typedef string Result;
typedef std::vector<string> Input;
class Day {
protected:
Input input;
virtual Result Task1() { return ""; }
virtual Result Task2() { return ""; }
public:
int run(Input &_input) {
input = _input;
auto start = high_resolution_clock::now();
cout << "Task 1" << endl;
Result result1 = Task1();
auto stop1 = high_resolution_clock::now();
auto dur1 = duration_cast<microseconds>(stop1 - start);
cout << "Result: " << result1 << endl;
cout << "Duration: " << double(dur1.count()) / 1000. << "ms" << endl;
cout << "Task 2" << endl;
Result result2 = Task2();
auto stop2 = high_resolution_clock::now();
auto dur2 = duration_cast<microseconds>(stop2 - stop1);
cout << "Result: " << result2 << endl;
cout << "Duration: " << double(dur2.count()) / 1000. << "ms" << endl << endl;
return 0;
}
};

@ -0,0 +1,9 @@
#include "Day01.h"
Result Day01::Task1() {
return Day::Task1();
}
Result Day01::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day01 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day02.h"
Result Day02::Task1() {
return Day::Task1();
}
Result Day02::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day02 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day03.h"
Result Day03::Task1() {
return Day::Task1();
}
Result Day03::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day03 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day04.h"
Result Day04::Task1() {
return Day::Task1();
}
Result Day04::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day04 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day05.h"
Result Day05::Task1() {
return Day::Task1();
}
Result Day05::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day05 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day06.h"
Result Day06::Task1() {
return Day::Task1();
}
Result Day06::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day06 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day07.h"
Result Day07::Task1() {
return Day::Task1();
}
Result Day07::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day07 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day08.h"
Result Day08::Task1() {
return Day::Task1();
}
Result Day08::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day08 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day09.h"
Result Day09::Task1() {
return Day::Task1();
}
Result Day09::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day09 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day10.h"
Result Day10::Task1() {
return Day::Task1();
}
Result Day10::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day10 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day11.h"
Result Day11::Task1() {
return Day::Task1();
}
Result Day11::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day11 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day12.h"
Result Day12::Task1() {
return Day::Task1();
}
Result Day12::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day12 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day13.h"
Result Day13::Task1() {
return Day::Task1();
}
Result Day13::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day13 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day14.h"
Result Day14::Task1() {
return Day::Task1();
}
Result Day14::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day14 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day15.h"
Result Day15::Task1() {
return Day::Task1();
}
Result Day15::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day15 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day16.h"
Result Day16::Task1() {
return Day::Task1();
}
Result Day16::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day16 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day17.h"
Result Day17::Task1() {
return Day::Task1();
}
Result Day17::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day17 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day18.h"
Result Day18::Task1() {
return Day::Task1();
}
Result Day18::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day18 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day19.h"
Result Day19::Task1() {
return Day::Task1();
}
Result Day19::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day19 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day20.h"
Result Day20::Task1() {
return Day::Task1();
}
Result Day20::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day20 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day21.h"
Result Day21::Task1() {
return Day::Task1();
}
Result Day21::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day21 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day22.h"
Result Day22::Task1() {
return Day::Task1();
}
Result Day22::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day22 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day23.h"
Result Day23::Task1() {
return Day::Task1();
}
Result Day23::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day23 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day24.h"
Result Day24::Task1() {
return Day::Task1();
}
Result Day24::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day24 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,9 @@
#include "Day25.h"
Result Day25::Task1() {
return Day::Task1();
}
Result Day25::Task2() {
return Day::Task2();
}

@ -0,0 +1,10 @@
#pragma once
#include "../../Day.h"
class Day25 : public Day {
protected:
Result Task1() override;
Result Task2() override;
};

@ -0,0 +1,57 @@
#pragma once
#include "01/Day01.h"
#include "02/Day02.h"
#include "03/Day03.h"
#include "04/Day04.h"
#include "05/Day05.h"
#include "06/Day06.h"
#include "07/Day07.h"
#include "08/Day08.h"
#include "09/Day09.h"
#include "10/Day10.h"
#include "11/Day11.h"
#include "12/Day12.h"
#include "13/Day13.h"
#include "14/Day14.h"
#include "15/Day15.h"
#include "16/Day16.h"
#include "17/Day17.h"
#include "18/Day18.h"
#include "19/Day19.h"
#include "20/Day20.h"
#include "21/Day21.h"
#include "22/Day22.h"
#include "23/Day23.h"
#include "24/Day24.h"
#include "25/Day25.h"
std::vector<Day *> getAllDays() {
return {
new Day01(),
new Day02(),
new Day03(),
new Day04(),
new Day05(),
new Day06(),
new Day07(),
new Day08(),
new Day09(),
new Day10(),
new Day11(),
new Day12(),
new Day13(),
new Day14(),
new Day15(),
new Day16(),
new Day17(),
new Day18(),
new Day19(),
new Day20(),
new Day21(),
new Day22(),
new Day23(),
new Day24(),
new Day25()
};
}

@ -0,0 +1,96 @@
#include <filesystem>
#include <cpr/cpr.h>
#include "days/days.h"
Input getInput(int day, string key, bool useTestInput, int testFetchIndex) {
Input input;
char dayStrPadded[3];
sprintf(dayStrPadded, "%02u", day);
string postfix = useTestInput ? "_testInput.txt" : "_input.txt";
string localFilePath = "input/" + string(dayStrPadded) + postfix;
if (!std::filesystem::exists({localFilePath})) {
string dayStr = std::to_string(day);
string url = "https://adventofcode.com/2022/day/" + dayStr;
auto cookies = cpr::Cookies{{"session", key}};
if (!useTestInput){
if (key.empty()){
cout << "Session key Cookie is missing, cannot fetch Input" << endl;
return input;
}
url += "/input";
cout << "Input does not exist. Fetching from " + url << endl;
std::ofstream file(localFilePath);
file << cpr::Get(cpr::Url{url}, cookies).text;
file.close();
} else {
cout << "Test Input does not exist. Fetching from " + url << " from <code>-Tag with index " << testFetchIndex << endl;
std::ofstream file(localFilePath);
string res = cpr::Get(cpr::Url{url}).text;
size_t i1 = findAll(res, "<code>")[testFetchIndex];
size_t i2 = findAll(res, "</code>")[testFetchIndex];
string codeContent = res.substr(i1 + 6, i2 - (i1 + 6));
removeAll(codeContent, "<em>");
removeAll(codeContent, "</em>");
file << codeContent;
file.close();
}
}
std::ifstream file(localFilePath);
string line;
while (std::getline(file, line))
input.push_back(line);
file.close();
return input;
}
string getSessionKey() {
string key;
std::ifstream file("session");
if (!file.good())
return "";
file >> key;
file.close();
return key;
}
void parseArgument(const string& arg, int &dayNum, bool &useTestInput, int &testFetchIndex){
size_t tIndex = arg.find('T');
if (tIndex == string::npos) {
dayNum = stoi(arg);
return;
}
dayNum = stoi(arg.substr(0, tIndex));
useTestInput = true;
testFetchIndex = tIndex + 1 < arg.size() ? stoi(arg.substr(tIndex + 1)) : 0;
}
int main(int argc, char *argv[]) {
auto key = getSessionKey();
auto days = getAllDays();
std::filesystem::create_directory("input");
for (int i = 1; i < argc; i++) {
string arg = argv[i];
bool useTestInput = false;
int testFetchIndex;
int dayNum;
parseArgument(arg, dayNum, useTestInput, testFetchIndex);
cout << "Running day " << dayNum << endl;
Input input = getInput(dayNum, key, useTestInput, testFetchIndex);
Day *day = days[dayNum - 1];
int code = day->run(input);
if (code != 0)
return code;
}
days.clear();
return 0;
}

@ -0,0 +1,42 @@
#pragma once
#include <vector>
#include <numeric>
#include <string>
#include <tuple>
#include <iostream>
#include <set>
#include <unordered_set>
#include <map>
#include <list>
#include <queue>
typedef uint64_t uint64;
typedef int64_t int64;
using std::stoi, std::to_string;
using std::cout, std::endl;
using std::string, std::vector, std::pair, std::map;
using std::list, std::set, std::unordered_set;
using std::priority_queue;
inline vector<size_t> findAll(const string& data, const string& toSearch){
vector<size_t> indices;
size_t pos = data.find(toSearch);
while (pos != string::npos){
indices.push_back(pos);
pos = data.find(toSearch, pos + toSearch.size());
}
return indices;
}
inline void removeAll(string& data, const string& toRemove) {
vector<size_t> indices = findAll(data, toRemove);
std::sort(indices.rbegin(), indices.rend());
for (size_t &i : indices)
data.erase(i, toRemove.size());
}
Loading…
Cancel
Save