-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0514.FreedomTrial.cpp
More file actions
66 lines (59 loc) · 2.09 KB
/
Copy path0514.FreedomTrial.cpp
File metadata and controls
66 lines (59 loc) · 2.09 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
class Solution {
public:
const uint32_t closestCW(const string& string, const uint32_t index, const char target) {
// Find closest clockwise.
const uint32_t modMax = string.size();
for (uint32_t i = 0; i < modMax; i++)
if (string[(index + i) % modMax] == target)
return i;
// Not found,, shouldn't happen so we ignore and enjoy a bad result.
return 0;
}
const uint32_t closestCCW(const string& string, const uint32_t index, const char target) {
// Find closest counter-clockwise.
const uint32_t modMax = string.size();
for (uint32_t i = 0; i < string.size(); i++)
if (string[(index + modMax - i) % modMax] == target)
return i;
// Not found,, shouldn't happen so we ignore and enjoy a bad result.
return 0;
}
const uint32_t getSteps(
map<uint64_t, uint32_t>& cache,
const string& ring, const uint32_t ringIndex,
const string& key, const uint32_t keyIndex
) {
// End of key check.
if (keyIndex == key.size()) return 0;
// Check cache.
const uint64_t cacheLookupValue = ((uint64_t)ringIndex << 32) | keyIndex;
auto it = cache.find(cacheLookupValue);
if (it != cache.end()) return it->second;
uint32_t score = INT_MAX;
// Get character distances.
const uint32_t
leftDistance = closestCCW(ring, ringIndex, key[keyIndex]),
rightDistance = closestCW(ring, ringIndex, key[keyIndex]);
// Get indices.
const uint32_t
leftIndex = (ringIndex + ring.size() - leftDistance) % ring.size(),
rightIndex = (ringIndex + rightDistance) % ring.size();
// Branch left.
const uint32_t leftSteps = getSteps(cache, ring, leftIndex, key, keyIndex + 1);
if (leftIndex == rightIndex) {
// Combined branch score.
score = min(leftDistance, rightDistance) + leftSteps + 1;
} else {
// Branch right.
const uint32_t rightSteps = getSteps(cache, ring, rightIndex, key, keyIndex + 1);
score = min(leftDistance + leftSteps, rightDistance + rightSteps) + 1;
}
// Cache result.
cache.emplace(cacheLookupValue, score);
return score;
}
int findRotateSteps(string ring, string key) {
map<uint64_t, uint32_t> cache;
return getSteps(cache, ring, 0, key, 0);
}
};