Added 2022 (cpp)

This commit is contained in:
Karma Riuk
2023-08-02 11:50:10 +02:00
parent 11600f7ba9
commit 567c8487b5
106 changed files with 10153 additions and 0 deletions

33
2022/cpp/07/Makefile Normal file
View File

@ -0,0 +1,33 @@
PART := 1
CXXFLAGS := -Wall -O3 -DPART=$(PART)
OBJ_DIR = build
OBJ = answer.o
.PHONY = clean asdf sample1 sample2
asdf: result
@echo "------- RESULT -------"
@./result "input" | xclip -selection c
@xclip -selection c -o
check: test
./test
test: $(OBJ_DIR)/$(OBJ)
verbose: clean
$(eval CXXFLAGS += -DVERBOSE)
$(OBJ_DIR)/$(OBJ): $(OBJ_DIR)/%.o: %.hpp
$(OBJ_DIR)/%.o: %.cpp
@echo "Compiling $<..."
@mkdir -p $(@D)
gcc $(CXXFLAGS) -c -o $@ $<
result: $(OBJ_DIR)/$(OBJ)
clean:
-rm -f *.o
-rm -rf $(OBJ_DIR)/

145
2022/cpp/07/answer.cpp Normal file
View File

@ -0,0 +1,145 @@
// AOC - 2022 - 07
#include "answer.hpp"
#include <deque>
#include <fstream>
#include <iostream>
#include <sstream>
bool is_dir(std::string line) {
return line.substr(0, 3) == "dir";
}
bool is_command(std::string line) {
return line[0] == '$';
}
Dir* get_subdir(Dir* current_dir, const std::string& subdir_name) {
for (auto& dir : current_dir->dirs)
if (dir->name == subdir_name)
return dir;
std::cerr << "'" << subdir_name << "' not in " << current_dir->name
<< std::endl;
error("couldn't find subdir");
}
Dir* handle_command(
Dir* current_dir, std::string& cmd_line, std::ifstream& input) {
std::cout << "CWD: " << current_dir->name << std::endl;
std::cout << "Handling cmd: '" << cmd_line << "'" << std::endl;
std::stringstream cmd_stream(cmd_line);
std::string cmd, _;
cmd_stream >> _; // $
cmd_stream >> cmd;
std::string line;
Dir* reading_dir = current_dir;
if (cmd == "ls") {
if (!cmd_stream.eof()) {
std::string dir_name;
cmd_stream >> dir_name;
reading_dir = get_subdir(current_dir, dir_name);
}
while (std::getline(input, line) && !is_command(line)) {
if (is_dir(line)) {
std::string dir_name = line.substr(4);
std::cout << "Adding dir '" << dir_name << "' to "
<< current_dir->name << std::endl;
reading_dir->dirs.push_back(new Dir{reading_dir, dir_name});
} else {
uint size;
std::string file_name;
std::stringstream file_line_stream(line);
file_line_stream >> size;
file_line_stream >> file_name;
reading_dir->files.push_back({size, file_name});
}
}
std::cout << "After reading, the cwd looks like" << std::endl;
std::cout << *reading_dir << std::endl;
if (is_command(line))
return handle_command(current_dir, line, input);
else
return current_dir;
} else if (cmd == "cd") {
std::string new_dirname;
cmd_stream >> new_dirname;
std::cout << "cd-ing to " << new_dirname << std::endl;
if (new_dirname == "..") {
std::cout << "\t thus to " << current_dir->parent->name
<< std::endl;
return current_dir->parent;
} else
return get_subdir(current_dir, new_dirname);
} else {
std::cerr << "Invalid cmd: " << cmd << std::endl;
error("Invalid command");
}
}
Input get_input(const char* filename) {
std::ifstream stream(filename);
std::string str;
Dir* root = new Dir{nullptr, "/"};
getline(stream, str); // cd /
Dir* current_dir = root;
while (getline(stream, str))
current_dir = handle_command(current_dir, str, stream);
std::cout << "current" << std::endl;
std::cout << *current_dir << std::endl;
std::cout << "root" << std::endl;
std::cout << *root << std::endl;
return {*root};
}
#define CUTOFF_SIZE 100000
#define FILESYSTEM_SIZE 70000000
#define NEEDED_SIZE 30000000
std::string get_result(Input input) {
std::string ret;
#if PART == 1
std::vector<Dir*> queue;
queue.push_back(&input.root);
int i = 0;
uint res = 0;
while (i < queue.size()) {
std::cout << "ehhlo?" << std::endl;
Dir d = *queue[i++];
if (d.get_size() < CUTOFF_SIZE)
res += d.get_size();
for (auto& d : d.dirs)
queue.push_back(d);
for (auto& d : queue)
std::cout << *d << std::endl;
}
ret = std::to_string(res);
#else
uint space_to_free = input.root.get_size() - NEEDED_SIZE;
std::cout << space_to_free << std::endl;
std::vector<Dir*> queue;
queue.push_back(&input.root);
int i = 0;
uint min_above_needed = -1;
while (i < queue.size()) {
Dir d = *queue[i++];
if (d.get_size() < space_to_free)
continue;
else if (d.get_size() < min_above_needed)
min_above_needed = d.get_size();
for (auto& sub_dir : d.dirs)
queue.push_back(sub_dir);
for (auto& d : queue)
std::cout << d->name << std::endl;
}
ret = std::to_string(min_above_needed);
#endif
return ret;
}

80
2022/cpp/07/answer.hpp Normal file
View File

@ -0,0 +1,80 @@
#include "lib.hpp"
#include <string>
#ifndef VERBOSE
#define VERBOSE 0
#endif
#ifndef PART
#define PART 2
#endif
struct File {
uint size;
std::string name;
bool operator==(const File& rhs) const {
return this->name == rhs.name && this->size == rhs.size;
}
};
struct Dir {
Dir* parent;
std::string name;
std::vector<Dir*> dirs;
std::vector<File> files;
uint size = 0;
uint get_size() {
if (this->size > 0)
return this->size;
uint res = 0;
for (auto& f : this->files)
res += f.size;
for (auto& d : this->dirs)
res += d->get_size();
this->size = res;
return res;
}
bool operator==(const Dir& rhs) const {
return this->name == rhs.name && this->dirs == rhs.dirs &&
this->files == rhs.files;
}
};
struct Input {
Dir root;
bool operator==(const Input& rhs) const {
return this->root == rhs.root;
}
};
inline std::ostream& operator<<(std::ostream& os, File& file) {
os << "- " << file.name << " (file, size=" << file.size << ")" << std::endl;
return os;
}
inline std::ostream& operator<<(std::ostream& os, Dir& dir) {
os << "- " << dir.name << " (dir";
if (dir.parent)
os << ", parent=" << dir.parent->name;
os << ")" << std::endl;
for (auto& d : dir.dirs)
os << '\t' << *d;
for (auto& f : dir.files)
os << '\t' << f;
return os;
}
inline std::ostream& operator<<(std::ostream& os, Input& inp) {
os << inp.root;
return os;
}
Input get_input(const char*);
std::string get_result(Input);

BIN
2022/cpp/07/build/answer.o Normal file

Binary file not shown.

1101
2022/cpp/07/input Normal file

File diff suppressed because it is too large Load Diff

23
2022/cpp/07/lib.hpp Normal file
View File

@ -0,0 +1,23 @@
#include <iostream>
#include <ostream>
#include <vector>
template <class T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& list) {
unsigned long i = 0;
os << "[";
for (auto el : list) {
os << el;
if (i < list.size() - 1)
os << ", ";
i++;
}
os << "]";
return os;
}
inline void error(const char* msg) {
std::cerr << msg << std::endl;
exit(1);
}

BIN
2022/cpp/07/result Executable file

Binary file not shown.

23
2022/cpp/07/result.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "answer.hpp"
#include <iostream>
int main(int argc, char* argv[]) {
if (argc < 2)
error("Please specify the input file as first argument.");
#if !VERBOSE
std::cout.setstate(std::ios_base::failbit);
#endif
Input input = get_input(argv[1]);
std::string result = get_result(input);
#if !VERBOSE
std::cout.clear();
#endif
std::cout << result << std::endl;
return 0;
}

23
2022/cpp/07/sample1 Normal file
View File

@ -0,0 +1,23 @@
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

23
2022/cpp/07/sample2 Normal file
View File

@ -0,0 +1,23 @@
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k

BIN
2022/cpp/07/test Executable file

Binary file not shown.

25
2022/cpp/07/test.cpp Normal file
View File

@ -0,0 +1,25 @@
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "../doctest/doctest/doctest.h"
#include "answer.hpp"
#if PART == 1
TEST_CASE("Part 1") {
Input actual_input = get_input("sample1");
std::cout << "actual_input" << std::endl;
std::cout << actual_input << std::endl;
SUBCASE("Testing output is the one expected from AOC") {
CHECK(get_result(actual_input) == "95437");
}
}
#endif
#if PART == 2
TEST_CASE("Part 2") {
Input actual_input = get_input("sample2");
SUBCASE("Testing output is the one expected from AOC") {
CHECK(get_result(actual_input) == "24933642");
}
}
#endif