Quantcast
Channel: YGC » c++
Viewing all articles
Browse latest Browse all 18

project euler -- problem 74

$
0
0
The number 145 is well known for the property that the sum of the factorial of its digits is equal to 145:
    1! + 4! + 5! = 1 + 24 + 120 = 145

Perhaps less well known is 169, in that it produces the longest chain of numbers that link back to 169; it turns out that there are only three such loops that exist:
    169 → 363601 → 1454 → 169
    871 → 45361 → 871
    872 → 45362 → 872

It is not difficult to prove that EVERY starting number will eventually get stuck in a loop. For example,
    69 → 363600 → 1454 → 169 → 363601 (→ 1454)
    78 → 45360 → 871 → 45361 (→ 871)
    540 → 145 (→ 145)

Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number below one million is sixty terms.

How many chains, with a starting number below one million, contain exactly sixty non-repeating terms?

This problem is easy to implement and my implementation is almost brute-force, except using MAP to cache all the pair of number and the sum of the factorial of its digits.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include<iostream>
#include<map>
 
using namespace std;
const int N=1e6;
 
bool chain_of_length_60(int x);
int sum_digit_factorial(int x);
int fac(int i);
int factorial(int n);
 
int main() {
  int res=0;
  for (int i=70; i<N; i++) 
    if (chain_of_length_60(i))
      res++;
  cout << "Answer of Problem 74 is: " << res << endl;
  return 0;
}
 
bool chain_of_length_60(int x) {
  static map<int, int> mem;
  int sz = 61;
  int val, vals[sz];
  int length=1;
  bool flag = false;
  vals[0] = x;
  int y = x;
  for (int i=1; i <= sz; i++) {
    if (mem.find(y) == mem.end() ) {
      val = sum_digit_factorial(y);
      mem[y] = val;
    } else {
      val = mem[y];
    }
    y = val;
    for (int j=0; j<i; j++) {
      if (val == vals[j]) {
	flag = true;
	break;
      }
    }
    if (flag)
      break;
    vals[i] = val;
    length++;
  }
  return length == 60;
}
 
int sum_digit_factorial(int x) {
  int res = 0;
  while (x) {
    res += fac(x % 10);
    x = x / 10;
  }
  return res;
}
 
int fac(int i) {
  static int fac_mem[10];
  if (i < 0 || i > 9) 
    return NULL;
  if (!fac_mem[i]) {
    fac_mem[i] = factorial(i);
  }
  return fac_mem[i];
}
 
int factorial(int n) {
  if (n <= 1)
    return 1;
  else 
    n = n * factorial(n-1);
  return n;
}
> system.time(system("./pe74"))
Answer of Problem 74 is: 402
   user  system elapsed 
 67.832   0.108  67.980 

Related Posts


Viewing all articles
Browse latest Browse all 18

Trending Articles