Added 2022 (cpp)
This commit is contained in:
33
2022/cpp/07/Makefile
Normal file
33
2022/cpp/07/Makefile
Normal 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
145
2022/cpp/07/answer.cpp
Normal 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
80
2022/cpp/07/answer.hpp
Normal 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
BIN
2022/cpp/07/build/answer.o
Normal file
Binary file not shown.
1101
2022/cpp/07/input
Normal file
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
23
2022/cpp/07/lib.hpp
Normal 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
BIN
2022/cpp/07/result
Executable file
Binary file not shown.
23
2022/cpp/07/result.cpp
Normal file
23
2022/cpp/07/result.cpp
Normal 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
23
2022/cpp/07/sample1
Normal 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
23
2022/cpp/07/sample2
Normal 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
BIN
2022/cpp/07/test
Executable file
Binary file not shown.
25
2022/cpp/07/test.cpp
Normal file
25
2022/cpp/07/test.cpp
Normal 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
|
Reference in New Issue
Block a user