PE 80, solved by digit-by-digit calculation

This commit is contained in:
2022-05-06 15:58:38 +02:00
parent 679022c4cd
commit dd43fcc0c5

95
projecteuler/080/main.cpp Normal file
View File

@@ -0,0 +1,95 @@
#include <bits/stdc++.h>
#include "../bigint.h"
using namespace std;
// This function should only work on positive integer n
int rootDigitSum(unsigned int n, int decimals=99){
// Integer roots don't have decimals of course
int check = sqrt(n);
if(check * check == n){
return 0;
}
int result = check;
vector<int> digits;
while(n > 0){
int last = n % 10;
n /= 10;
digits.push_back(last);
}
// Initialize method
InfInt remainder;
if(digits.size() % 2 == 0){
remainder = 10 * digits.back();
digits.pop_back();
remainder += digits.back();
digits.pop_back();
} else{
remainder = digits.back();
digits.pop_back();
}
InfInt minus = remainder.intSqrt();
InfInt root = minus;
remainder -= minus * minus;
while(decimals != 0){
// cout << remainder << " " << root << endl;
remainder *= 100;
bool decimalPart = true;
if(!digits.empty()){
decimalPart = false;
remainder += digits.back() * 10;
digits.pop_back();
remainder += digits.back();
digits.pop_back();
}
for(int guess = 0; guess < 10; ++guess){
InfInt lower = (root * 20 + guess) * guess;
InfInt upper = (root * 20 + guess + 1) * (guess + 1);
if(lower <= remainder && remainder < upper){
remainder -= lower;
root = root * 10 + guess;
if(decimalPart) result += guess;
// cout << remainder << " " << root << " " << lower << " " << upper << endl;
break;
}
}
--decimals;
}
return result;
}
int main(){
cout << "Hello this is Patrick" << endl;
auto start = chrono::high_resolution_clock::now();
int result = 0;
for(int i = 1; i <= 100; ++i){
result += rootDigitSum(i);
}
cout << result << endl;
// cout << rootDigitSum(2) << endl;
auto duration = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start);
cout << (float)duration.count()/1000 << endl;
return 0;
}