3
// First letter is unique after previous entries have been handled:4
static final String[] UNIQUES =6
"zero", "wto", "geiht", "xsi", "htree",7
"seven", "rfou", "one", "vfie", "inne"10
// Values corresponding to order of uniqueness checks:11
static final int[] VALS = new int[] {0, 2, 8, 6, 3, 7, 4, 1, 5, 9};13
// Maps for checking uniqueness more conveniently:14
static final Map<Integer, List<Integer>> ORDERED_FREQ_MAP;15
static final Map<Integer, Integer> ORDERED_DIGIT_MAP;18
// Initialize our ordered frequency map: 0-25 key to 0-25 values finishing the word:19
final LinkedHashMap<Integer, List<Integer>> orderedFreqMap = new LinkedHashMap<>();20
// Also initialize a digit lookup map, e.g. 'g' becomes 6 maps to 8 for ei[g]ht:21
final LinkedHashMap<Integer, Integer> orderedDigitMap = new LinkedHashMap<>();22
for (int i = 0; i < 10; ++i) {23
final char unique = UNIQUES[i].charAt(0);24
final int ui = convert(unique);25
orderedFreqMap.put(ui, converting(UNIQUES[i].substring(1).toCharArray()));26
orderedDigitMap.put(ui, VALS[i]);28
// Let's make sure we aren't tempted to modify these since they're static.29
ORDERED_FREQ_MAP = Collections.unmodifiableMap(orderedFreqMap);30
ORDERED_DIGIT_MAP = Collections.unmodifiableMap(orderedDigitMap);33
public String originalDigits(String s) {34
// count frequencies of each letter in s:35
final int[] freqs = new int[26];36
for (int i = 0; i < s.length(); ++i) {37
freqs[convert(s.charAt(i))]++;39
// Crate an array to store digit strings in order, e.g. '00000', '11, '2222222', etc.40
final String[] strings = new String[10];41
// Iterate through uniqueness checks in order:42
for (Map.Entry<Integer, List<Integer>> entry : ORDERED_FREQ_MAP.entrySet()) {43
final int index = entry.getKey(); // unique letter in 0-25 form45
ORDERED_DIGIT_MAP.get(index); // corresponding digit, e.g. 8 for 'g', 0 for 'z', etc.47
freqs[index]; // frequency of unique letter = frequency of corresponding digit49
// update frequencies to remove the digit's word count times:50
freqs[index] -= count;51
for (int idx : entry.getValue()) {54
// now create the digit string for the unique digit: the digit count times:55
strings[value] = String.valueOf(value).repeat(count);57
// count 0 - empty strring for this digit61
// append the digit strings in order62
final StringBuilder sb = new StringBuilder();63
for (String str : strings) {70
// Converts a character array into a list of 0-25 frequency values.71
private static final List<Integer> converting(char... carr) {72
final List<Integer> list = new ArrayList<>();73
for (char ch : carr) {74
list.add(convert(ch)); // converts each to 0-2576
return Collections.unmodifiableList(list);79
// Converts a-z to 0-26. Bitwise AND with 31 gives a=1, z=26, so then subtract one.80
private static final Integer convert(char ch) {81
return (ch & 0x1f) - 1; // a->0, z->25