82 lines
1.5 KiB
C++
82 lines
1.5 KiB
C++
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
#include <set>
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
|
||
|
int score(char c)
|
||
|
{
|
||
|
if(c >= 'a' && c <= 'z')
|
||
|
return (c - 'a') + 1;
|
||
|
return (c - 'A') + 1 + 26;
|
||
|
}
|
||
|
|
||
|
int main()
|
||
|
{
|
||
|
std::ifstream ifs("data.txt");
|
||
|
if(!ifs.is_open())
|
||
|
{
|
||
|
std::cerr << "Missing data.txt." << std::endl;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
unsigned long total = 0;
|
||
|
unsigned long total_pt2 = 0;
|
||
|
|
||
|
for(std::string line; std::getline(ifs, line); )
|
||
|
{
|
||
|
if(line == "")
|
||
|
continue;
|
||
|
|
||
|
const size_t half = line.size() / 2;
|
||
|
std::string right = line.substr(half);
|
||
|
for(int i = 0; i < half; ++i)
|
||
|
{
|
||
|
if(right.contains(line[i]))
|
||
|
{
|
||
|
total += score(line[i]);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Part 2:
|
||
|
static std::vector<std::string> lines;
|
||
|
lines.push_back(line);
|
||
|
if(lines.size() == 3)
|
||
|
{
|
||
|
// get all letters it could be from first line
|
||
|
std::set<char> options;
|
||
|
for(const char c : lines[0])
|
||
|
options.insert(c);
|
||
|
|
||
|
// remove if not a duplicate
|
||
|
std::set<char> to_remove;
|
||
|
for(auto i = 1; i < 3; ++i) // remaining two lines
|
||
|
{
|
||
|
for(const char c : options)
|
||
|
if(!lines[i].contains(c))
|
||
|
to_remove.insert(c);
|
||
|
for(const char c : to_remove)
|
||
|
options.erase(c);
|
||
|
}
|
||
|
|
||
|
if(options.size() != 1)
|
||
|
{
|
||
|
std::cerr << "Error: More than one remaining option: ";
|
||
|
for(const char c : options)
|
||
|
std::cout << c << ",";
|
||
|
exit(-1);
|
||
|
}
|
||
|
|
||
|
total_pt2 += score(*(options.begin()));
|
||
|
|
||
|
lines.clear(); // reset
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::cout << " Total: " << total << std::endl;
|
||
|
std::cout << "PT2 Total: " << total_pt2 << std::endl;
|
||
|
|
||
|
return 0;
|
||
|
}
|