127 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#include <algorithm>
 | 
						|
#include <fstream>
 | 
						|
#include <iostream>
 | 
						|
#include <map>
 | 
						|
#include <set>
 | 
						|
#include <sstream>
 | 
						|
#include <string>
 | 
						|
#include <vector>
 | 
						|
 | 
						|
int main()
 | 
						|
{
 | 
						|
	const std::string filename = "data.txt";
 | 
						|
	std::ifstream ifs(filename);
 | 
						|
	if(!ifs.is_open())
 | 
						|
	{
 | 
						|
		std::cerr << "Missing " << filename << "." << std::endl;
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	unsigned long total = 0;
 | 
						|
	unsigned long total_pt2 = 0;
 | 
						|
 | 
						|
	std::map<std::string, std::string> values =
 | 
						|
	{
 | 
						|
		{ "0", "0" },
 | 
						|
		{ "1", "1" },
 | 
						|
		{ "2", "2" },
 | 
						|
		{ "3", "3" },
 | 
						|
		{ "4", "4" },
 | 
						|
		{ "5", "5" },
 | 
						|
		{ "6", "6" },
 | 
						|
		{ "7", "7" },
 | 
						|
		{ "8", "8" },
 | 
						|
		{ "9", "9" },
 | 
						|
//		{ "zero", 0 },
 | 
						|
		{ "one", "1" },
 | 
						|
		{ "two", "2" },
 | 
						|
		{ "three", "3" },
 | 
						|
		{ "four", "4" },
 | 
						|
		{ "five", "5" },
 | 
						|
		{ "six", "6" },
 | 
						|
		{ "seven", "7" },
 | 
						|
		{ "eight", "8" },
 | 
						|
		{ "nine", "9" }
 | 
						|
	};
 | 
						|
 | 
						|
	auto GetDigit = [&](const std::string &line, int i, bool ascending, std::string &result) {
 | 
						|
		std::vector<std::string> tests;
 | 
						|
		if(ascending)
 | 
						|
		{
 | 
						|
			tests.push_back(line.substr(i, 1)); // single digits
 | 
						|
			if(i < line.size() - 2)
 | 
						|
				tests.push_back(line.substr(i, 3)); // three-letter words
 | 
						|
			if(i < line.size() - 3)
 | 
						|
				tests.push_back(line.substr(i, 4)); // four-letter words
 | 
						|
			if(i < line.size() - 4)
 | 
						|
				tests.push_back(line.substr(i, 5)); // five-letter words
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			if(i < line.size() - 4)
 | 
						|
				tests.push_back(line.substr(i, 5)); // five-letter words
 | 
						|
			if(i < line.size() - 3)
 | 
						|
				tests.push_back(line.substr(i, 4)); // four-letter words
 | 
						|
			if(i < line.size() - 2)
 | 
						|
				tests.push_back(line.substr(i, 3)); // three-letter words
 | 
						|
			tests.push_back(line.substr(i, 1)); // single digits
 | 
						|
		}
 | 
						|
 | 
						|
		for(auto test : tests)
 | 
						|
		{
 | 
						|
			if(values.contains(test))
 | 
						|
			{
 | 
						|
				result = values.at(test);
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return false;
 | 
						|
	};
 | 
						|
 | 
						|
	for(std::string line; std::getline(ifs, line); )
 | 
						|
	{
 | 
						|
		if(line == "")
 | 
						|
			continue;
 | 
						|
 | 
						|
		std::string first = "";
 | 
						|
		std::string last = "";
 | 
						|
 | 
						|
		// first
 | 
						|
		for(auto i = 0; i < line.size(); ++i)
 | 
						|
		{
 | 
						|
			std::string result;
 | 
						|
			if(GetDigit(line, i, true, result))
 | 
						|
			{
 | 
						|
				first = result;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if(first == "")
 | 
						|
			std::cerr << "Missing digit in line: " << line << std::endl;
 | 
						|
 | 
						|
		// last
 | 
						|
		for(auto i = 0; i < line.size(); ++i)
 | 
						|
		{
 | 
						|
			std::string result;
 | 
						|
			if(GetDigit(line, line.size() - i - 1, false, result))
 | 
						|
			{
 | 
						|
				last = result;
 | 
						|
				break;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		if(last == "")
 | 
						|
			std::cerr << "Missing digit in line: " << line << std::endl;
 | 
						|
 | 
						|
		std::string val = first + last;
 | 
						|
		int val_int = std::atoi(val.c_str());
 | 
						|
		std::cout << val_int << std::endl;
 | 
						|
		total_pt2 += val_int;
 | 
						|
	}
 | 
						|
 | 
						|
	std::cout << "    Total: " <<     total << std::endl;
 | 
						|
	std::cout << "PT2 Total: " << total_pt2 << std::endl;
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 |