-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcollatz_conjecture.h
More file actions
84 lines (76 loc) · 2.73 KB
/
Copy pathcollatz_conjecture.h
File metadata and controls
84 lines (76 loc) · 2.73 KB
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
77
78
79
80
81
82
83
84
#ifndef CPP_ALGORITHM_COLLATZ_CONJECTURE_H
#define CPP_ALGORITHM_COLLATZ_CONJECTURE_H
#include <unordered_map>
#include <vector>
namespace CollatzConjecture
{
/**
* \brief Generate the Collatz sequence of a number.
* \details The Collatz conjecture is defined as follows:
* Take any natural number n. If n is even, divide it by 2 to get n / 2.
* If n is odd, multiply it by 3 and add 1 to obtain 3n + 1.
* \param number a positive integer
* \param hash_table a hash table to store the Collatz sequence of a number
* \return the Collatz sequence of a number
*/
std::vector<long long> GenerateCollatzSequence(
long long number,
std::unordered_map<long long, std::vector<long long>>& hash_table);
/**
* \brief Find the numbers satisfying the Collatz conjecture.
* \param number a positive integer
* \return a vector of numbers satisfying the Collatz conjecture
*/
std::vector<long long> FindNumbersSatisfyingCollatzConjecture(
long long number);
}
// ----------------------------------------------------------------------------
inline std::vector<long long> CollatzConjecture::GenerateCollatzSequence(
const long long number,
std::unordered_map<long long, std::vector<long long>>& hash_table)
{
if (number <= 0)
{
return {};
}
if (number == 1)
{
return {1};
}
if (hash_table.contains(number))
{
return hash_table[number];
}
std::vector<long long> sequence = {number};
// if number is even, then divide it by 2
if (number % 2 == 0)
{
std::vector<long long> sub_sequence = GenerateCollatzSequence(number / 2, hash_table);
sequence.insert(sequence.end(), sub_sequence.begin(), sub_sequence.end());
}
// if number is odd, then multiply it by 3 and add 1
else
{
std::vector<long long> sub_sequence = GenerateCollatzSequence(number * 3 + 1, hash_table);
sequence.insert(sequence.end(), sub_sequence.begin(), sub_sequence.end());
}
hash_table[number] = sequence;
return sequence;
}
// ----------------------------------------------------------------------------
inline std::vector<long long> CollatzConjecture::FindNumbersSatisfyingCollatzConjecture(
const long long number)
{
std::vector<long long> satisfied_numbers;
std::unordered_map<long long, std::vector<long long>> hash_table;
for (long long i = 1LL; i < number; ++i)
{
// if the Collatz sequence ends with 1, then satisfies the Collatz conjecture
if (std::vector<long long> sequence = GenerateCollatzSequence(i, hash_table); sequence.back() == 1)
{
satisfied_numbers.push_back(i);
}
}
return satisfied_numbers;
}
#endif