Rebased projecteuler folder, now includes all contest programming stuff
This commit is contained in:
154
projecteuler/061/main.cpp
Normal file
154
projecteuler/061/main.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are all figurate (polygonal) numbers and are generated by the following formulae:
|
||||
|
||||
Triangle P3,n=n(n+1)/2 1, 3, 6, 10, 15, ...
|
||||
Square P4,n=n2 1, 4, 9, 16, 25, ...
|
||||
Pentagonal P5,n=n(3n−1)/2 1, 5, 12, 22, 35, ...
|
||||
Hexagonal P6,n=n(2n−1) 1, 6, 15, 28, 45, ...
|
||||
Heptagonal P7,n=n(5n−3)/2 1, 7, 18, 34, 55, ...
|
||||
Octagonal P8,n=n(3n−2) 1, 8, 21, 40, 65, ...
|
||||
The ordered set of three 4-digit numbers: 8128, 2882, 8281, has three interesting properties.
|
||||
|
||||
The set is cyclic, in that the last two digits of each number is the first two digits of the next number (including the last number with the first).
|
||||
Each polygonal type: triangle (P3,127=8128), square (P4,91=8281), and pentagonal (P5,44=2882), is represented by a different number in the set.
|
||||
This is the only set of 4-digit numbers with this property.
|
||||
Find the sum of the only ordered set of six cyclic 4-digit numbers for which each polygonal type: triangle, square, pentagonal, hexagonal, heptagonal, and octagonal, is represented by a different number in the set.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
uint triangle(uint n){
|
||||
return n * (n + 1) / 2;
|
||||
}
|
||||
|
||||
uint square(uint n){
|
||||
return n * n;
|
||||
}
|
||||
|
||||
uint pentagonal(uint n){
|
||||
return n * (3 * n - 1) / 2;
|
||||
}
|
||||
|
||||
uint hexagonal(uint n){
|
||||
return n * (2 * n - 1);
|
||||
}
|
||||
|
||||
uint heptagonal(uint n){
|
||||
return n * (5 * n - 3) / 2;
|
||||
}
|
||||
|
||||
uint octogonal(uint n){
|
||||
return n * (3 * n - 2);
|
||||
}
|
||||
|
||||
bool validEnd(uint n){
|
||||
return n % 100 >= 10;
|
||||
}
|
||||
|
||||
std::set<unsigned int> results;
|
||||
const unsigned int Limit = 10000;
|
||||
std::vector<unsigned int> all(Limit, 0);
|
||||
uint finalMask = 0b111111000;
|
||||
|
||||
void fillVector(vector<uint> & toFill, const uint bitmask, uint (*calc)(uint n)){
|
||||
uint value = calc(0);
|
||||
|
||||
for(uint i = 0; value < 10000; ++i){
|
||||
if(value >= 1000 && validEnd(value)){
|
||||
toFill[value] |= bitmask & finalMask;
|
||||
}
|
||||
value = calc(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void search(vector<uint> & sequence, uint mask = 0){
|
||||
unsigned int from = 1000;
|
||||
unsigned int to = 10000;
|
||||
|
||||
if(!sequence.empty()){
|
||||
auto lowerTwoDigits = sequence.back() % 100;
|
||||
from = lowerTwoDigits * 100;
|
||||
to = from + 100;
|
||||
}
|
||||
|
||||
for(auto next = from; next < to; ++next){
|
||||
auto categories = all[next];
|
||||
if(categories == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isUnique = true;
|
||||
for(auto x : sequence){
|
||||
if(x == next){
|
||||
isUnique = false;
|
||||
break;
|
||||
}
|
||||
if(!isUnique){
|
||||
continue;
|
||||
}
|
||||
for(auto j = 3; j <=8; ++j){
|
||||
auto thisCategory = 1 << j;
|
||||
if((categories && thisCategory) == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
if((mask & thisCategory) != 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
auto nextMask = mask | thisCategory;
|
||||
if(nextMask == finalMask){
|
||||
auto first = sequence.front();
|
||||
|
||||
auto lowerTwoDigits = next % 100;
|
||||
auto upperTwoDigits = first / 100;
|
||||
|
||||
if(lowerTwoDigits == upperTwoDigits){
|
||||
auto sum = next;
|
||||
for(auto x : sequence){
|
||||
sum += x;
|
||||
}
|
||||
results.insert(sum);
|
||||
}
|
||||
}
|
||||
else{
|
||||
sequence.push_back(next);
|
||||
search(sequence, nextMask);
|
||||
sequence.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
cout << "Hello this is Patrick" << endl;
|
||||
auto start = chrono::high_resolution_clock::now();
|
||||
|
||||
// Finally learned what exactly it means when 1 << n, which is nice
|
||||
fillVector(all, 1 << 3, triangle);
|
||||
fillVector(all, 1 << 4, square);
|
||||
fillVector(all, 1 << 5, pentagonal);
|
||||
fillVector(all, 1 << 6, hexagonal);
|
||||
fillVector(all, 1 << 7, heptagonal);
|
||||
fillVector(all, 1 << 8, octogonal);
|
||||
|
||||
vector<uint> sequence;
|
||||
search(sequence);
|
||||
|
||||
for(auto x : results){
|
||||
cout << x << endl;
|
||||
}
|
||||
|
||||
auto duration = chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start);
|
||||
cout << (float)duration.count()/1000 << endl;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user