Student here. I'm practicing for coding interviews right now. In that context, how would you recommend I improve my code for this practice problem?
import java.util.*;
class Solution {
private static final int maxMagnitude = 3;
public String intToRoman(int num) {
assert 1 <= num && num <= 3999 : num;
StringBuilder sb = new StringBuilder();
int divisor = pow(10, maxMagnitude);
for (int i = maxMagnitude; i >= 0; i--) {
Magnitude syms = Magnitude.getByExponent(i);
sb.append(makeRomanNumeralDigit(num / divisor, syms.ONE_UNIT_SYMBOL, syms.FIVE_UNITS_SYMBOL, syms.TEN_UNITS_SYMBOL));
num %= divisor;
divisor = Math.max(divisor / 10, 1);
}
return sb.toString();
}
private static String makeRomanNumeralDigit(int val, char symOneUnit, char symFiveUnits, char symTenUnits) {
assert 0 <= val && val <= 10 : val;
StringBuilder sb = new StringBuilder();
switch (val) {
case 0:
break;
case 1:
sb.append(symOneUnit);
break;
case 2:
sb.append(symOneUnit).append(symOneUnit);
break;
case 3:
sb.append(symOneUnit).append(symOneUnit).append(symOneUnit);
break;
case 4:
sb.append(symOneUnit);
sb.append(symFiveUnits);
break;
case 5:
sb.append(symFiveUnits);
break;
case 6:
sb.append(symFiveUnits);
sb.append(symOneUnit);
break;
case 7:
sb.append(symFiveUnits);
sb.append(symOneUnit).append(symOneUnit);
break;
case 8:
sb.append(symFiveUnits);
sb.append(symOneUnit).append(symOneUnit).append(symOneUnit);
break;
case 9:
sb.append(symOneUnit);
sb.append(symTenUnits);
break;
case 10:
sb.append(symTenUnits);
break;
}
return sb.toString();
}
private static enum RomanNumeral {
ONE ('I'),
FIVE ('V'),
TEN ('X'),
FIFTY ('L'),
ONE_HUNDRED ('C'),
FIVE_HUNDRED ('D'),
ONE_THOUSAND ('M');
public final char SYMBOL;
private RomanNumeral(char symbol) {
this.SYMBOL = symbol;
}
}
private static enum Magnitude {
ONES (RomanNumeral.ONE.SYMBOL, RomanNumeral.FIVE.SYMBOL, RomanNumeral.TEN.SYMBOL),
TENS (RomanNumeral.TEN.SYMBOL, RomanNumeral.FIFTY.SYMBOL, RomanNumeral.ONE_HUNDRED.SYMBOL),
HUNDREDS (RomanNumeral.ONE_HUNDRED.SYMBOL, RomanNumeral.FIVE_HUNDRED.SYMBOL, RomanNumeral.ONE_THOUSAND.SYMBOL),
THOUSANDS (RomanNumeral.ONE_THOUSAND.SYMBOL, '\0', '\0');
public final char ONE_UNIT_SYMBOL;
public final char FIVE_UNITS_SYMBOL;
public final char TEN_UNITS_SYMBOL;
private Magnitude(char oneUnitSym, char fiveUnitsSym, char tenUnitsSym) {
this.ONE_UNIT_SYMBOL = oneUnitSym;
this.FIVE_UNITS_SYMBOL = fiveUnitsSym;
this.TEN_UNITS_SYMBOL = tenUnitsSym;
}
public static Magnitude getByExponent(int exponent) {
assert 0 <= exponent && exponent <= 3;
Magnitude magnitude = null;
switch (exponent) {
case 0:
magnitude = Magnitude.ONES;
break;
case 1:
magnitude = Magnitude.TENS;
break;
case 2:
magnitude = Magnitude.HUNDREDS;
break;
case 3:
magnitude = Magnitude.THOUSANDS;
break;
}
return magnitude;
}
}
private static int pow(int base, int exponent) {
assert base > 0 : base;
assert exponent >= 0 : exponent;
if (exponent == 0)
return 1;
int result = pow(base, exponent / 2);
result *= result;
if (exponent % 2 != 0)
result *= base;
return result;
}
}