/*
三角数, 四角数, 五角数, 六角数, 七角数, 八角数が全て表れる6つの巡回する4桁の数からなる
唯一の順序集合の和を求めよ.
*/
#include <stdio.h>
#define BEGINTRI 45
#define ENDTRI 140
#define BEGINSQU 32
#define ENDSQU 99
#define BEGINPEN 26
#define ENDPEN 81
#define BEGINHEX 23
#define ENDHEX 70
#define BEGINHEP 21
#define ENDHEP 63
#define BEGINOCT 19
#define ENDOCT 58
int list[6][100][100];
int root;
int triangular(int n) {
return n * (n + 1) / 2;
}
int square(int n) {
return n * n;
}
int pentagonal(int n) {
return n * (3 * n - 1) / 2;
}
int hexagonal(int n) {
return n * (2 * n - 1);
}
int heptagonal(int n) {
return n * (5 * n - 3) / 2;
}
int octagonal(int n) {
return n * (3 * n - 2);
}
void makeList(void) {
int i;
int twoUpperIdx[100] = { 0 };
int num;
int twoUpper;
for( i = BEGINSQU; i <= ENDSQU; i++ ) {
num = square(i);
if( num % 100 < 10 ) continue;
twoUpper = num / 100;
list[1][twoUpper][twoUpperIdx[twoUpper]] = num;
twoUpperIdx[twoUpper]++;
}
for( i = 0; i < 100; i++ ) twoUpperIdx[i] = 0;
for( i = BEGINPEN; i <= ENDPEN; i++ ) {
num = pentagonal(i);
if( num % 100 < 10 ) continue;
twoUpper = num / 100;
list[2][twoUpper][twoUpperIdx[twoUpper]] = num;
twoUpperIdx[twoUpper]++;
}
for( i = 0; i < 100; i++ ) twoUpperIdx[i] = 0;
for( i = BEGINHEX; i <= ENDHEX; i++ ) {
num = hexagonal(i);
if( num % 100 < 10 ) continue;
twoUpper = num / 100;
list[3][twoUpper][twoUpperIdx[twoUpper]] = num;
twoUpperIdx[twoUpper]++;
}
for( i = 0; i < 100; i++ ) twoUpperIdx[i] = 0;
for( i = BEGINHEP; i <= ENDHEP; i++ ) {
num = heptagonal(i);
if( num % 100 < 10 ) continue;
twoUpper = num / 100;
list[4][twoUpper][twoUpperIdx[twoUpper]] = num;
twoUpperIdx[twoUpper]++;
}
for( i = 0; i < 100; i++ ) twoUpperIdx[i] = 0;
for( i = BEGINOCT; i <= ENDOCT; i++ ) {
num = octagonal(i);
if( num % 100 < 10 ) continue;
twoUpper = num / 100;
list[5][twoUpper][twoUpperIdx[twoUpper]] = num;
twoUpperIdx[twoUpper]++;
}
return;
}
int rec(int num, int check) {
int i, j;
int rep;
if( check == 0x3f ) {
if( num % 100 == root / 100 ) {
return num;
} else {
return -1;
}
}
for( i = 0; i <= 5; i++ ) {
if( 1 << i & check ) continue;
for( j = 0; list[i][num % 100][j] != 0; j++ ) {
rep = rec(list[i][num % 100][j], check | 1 << i);
if( rep != -1 ) return rep + num;
}
}
return -1;
}
void problem61(void) {
int i;
int num;
int rep;
makeList();
for( i = BEGINTRI; i <= ENDTRI; i++ ) {
num = triangular(i);
root = num;
rep = rec(num, 1);
if( rep != -1 ) {
printf("%d\n", rep);
}
}
return;
}
int main(void) {
problem61();
return 0;
}