-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRomanNumeralsEncoder.java
More file actions
104 lines (72 loc) · 2.62 KB
/
Copy pathRomanNumeralsEncoder.java
File metadata and controls
104 lines (72 loc) · 2.62 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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package kyu6;
import java.util.Map;
import java.util.TreeMap;
public class RomanNumeralsEncoder {
public RomanNumeralsEncoder() {
}
private final Map<Integer, String> valueSymbolMap = new TreeMap<>(Map.of(
1, "I",
5, "V",
10, "X",
50, "L",
100, "C",
500, "D",
1000, "M")).descendingMap();
public String solution(int n) {
final StringBuilder sb = new StringBuilder();
solutionAux(n, sb);
return sb.toString();
}
private void solutionAux(int n, StringBuilder sb) {
if (n == 0) {
return;
}
final int numberToTransform = getNumberToTransform(n);
int approxNumber = findApproxNumber(numberToTransform);
int previousValue = findPreviousValue(approxNumber);
if ((numberToTransform % approxNumber == 0 && approxNumber * 3 >= numberToTransform) || (approxNumber != 1 && approxNumber + previousValue * 3 >= numberToTransform) || (approxNumber == 1 && previousValue * 3 >= numberToTransform)) {
sb.append(valueSymbolMap.get(approxNumber));
int j = numberToTransform - approxNumber;
while (j > 0) {
if (j % approxNumber == 0) {
sb.append(valueSymbolMap.get(approxNumber));
j -= approxNumber;
} else {
sb.append(valueSymbolMap.get(previousValue));
j -= previousValue;
}
}
} else {
int nextValue = findNextValue(approxNumber);
if (nextValue - approxNumber == numberToTransform) {
sb.append(valueSymbolMap.get(approxNumber));
} else {
sb.append(valueSymbolMap.get(previousValue));
}
sb.append(valueSymbolMap.get(nextValue));
}
solutionAux(n - numberToTransform, sb);
}
private int findApproxNumber(int n) {
return valueSymbolMap.keySet()
.stream()
.filter(k -> n >= k)
.findFirst()
.get();
}
private int getNumberToTransform(int n) {
int i = 1;
while (n % i != n) {
i *= 10;
}
return n - (n % (i / 10));
}
private int findPreviousValue(int n) {
return valueSymbolMap.containsKey(n / 2) ? n / 2 :
valueSymbolMap.containsKey(n / 5) ? n / 5 : n;
}
private int findNextValue(int n) {
return valueSymbolMap.containsKey(n * 2) ? n * 2 :
valueSymbolMap.containsKey(n * 5) ? n * 5 : n;
}
}