Initial commit

This commit is contained in:
2021-12-01 20:31:53 +00:00
commit 2f44ccc3a7
106 changed files with 9333 additions and 0 deletions

149
2020/puzzle-18-02.cc Normal file
View File

@@ -0,0 +1,149 @@
#include <algorithm>
#include <array>
#include <cassert>
#include <iostream>
#include <list>
#include <map>
#include <regex>
#include <set>
#include <string>
#include <tuple>
enum class Token : char {
Eof,
Number,
LParens = '(',
RParens = ')',
Add = '+',
Multiply = '*'
};
using Value = unsigned long;
struct Parser {
Parser(std::string const &s) : expr_(s), pos_(0) { skip_whitespace(); }
Value evaluate() { return multop(); }
private:
Value addop() {
auto value = primary();
do {
if (peek() == Token::Add) {
chew(Token::Add);
value += primary();
} else {
return value;
}
} while (true);
}
Value multop() {
auto value = addop();
do {
if (peek() == Token::Multiply) {
chew(Token::Multiply);
value *= addop();
} else {
return value;
}
} while (true);
}
Value primary() {
if (peek() == Token::LParens) {
chew(Token::LParens);
Value value = evaluate();
chew(Token::RParens);
return value;
} else if (peek() == Token::Number) {
return chew_number();
} else {
std::cout << "expr_ = " << expr_ << "\n";
std::cout << "pos_ = " << pos_ << "\n";
std::cout << "End = " << expr_.substr(pos_) << "\n";
assert(false);
}
}
Token peek() {
if (pos_ == expr_.size()) {
return Token::Eof;
}
switch (expr_[pos_]) {
case '(':
return Token::LParens;
case ')':
return Token::RParens;
case '+':
return Token::Add;
case '*':
return Token::Multiply;
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return Token::Number;
default:
std::cout << "expr_ = " << expr_ << "\n";
std::cout << "pos_ = " << pos_ << "\n";
std::cout << "End = " << expr_.substr(pos_) << "\n";
assert(false);
}
}
void chew(Token tok) {
assert(peek() == tok);
switch (tok) {
case Token::LParens:
case Token::RParens:
case Token::Add:
case Token::Multiply:
++pos_;
skip_whitespace();
break;
default:
assert(false);
}
}
void skip_whitespace() {
while (pos_ < expr_.size() && expr_[pos_] == ' ') {
++pos_;
}
}
Value chew_number() {
assert(peek() == Token::Number);
std::size_t len = 0;
Value value = std::stoul(expr_.substr(pos_), &len);
pos_ += len;
skip_whitespace();
return value;
}
std::string expr_;
std::string::size_type pos_;
};
int main(void) {
std::string line;
Value result = 0;
while (std::getline(std::cin, line)) {
Parser p(line);
Value r = p.evaluate();
std::cout << line << " = " << r << "\n";
result += r;
}
std::cout << "Sum: " << result << "\n";
return 0;
}