Amazon Interview Question
Software Engineer / DevelopersCountry: United States
Interview Type: In-Person
public String intToRoman(int num) {
int numbers[] = new int[]{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String roman[] = new String[]{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"};
int index = 0, x = num;
StringBuilder result = new StringBuilder();
while(x != 0){
int count = x / numbers[index];
if(count > 0){
while(count > 0){
result.append(roman[index]);
count--;
}
x = x % numbers[index];
}
index++;
}
return result.toString();
}
To write up a method for converting integer to Roman numerals is relatively easy.
But I wasn't confident in how to design a class for it.
'Cause there didn't seem like much.
I just answered, "It does a simple conversion that we can make it static and put it in an utility class".
Any thoughts?
Not everyone is a big fan of statics. Especially cause of it getting in the way of unit testing.
I would put this simply this way.
public sealed class RomanNumeric
{
public RomanNumeric()
{
}
public string GetRomanNumeric(int x)
{
...
}
//In case of C#, a syntactic sugar for converting int to roman
public static implicit operator string (int x)
{
...
}
}
//Writing the function in Javascript ...
function romanize(num){
var romanDecimal ={M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1};
var i;
var roman = '';
for (i in romanDecimal){
while(num >= romanDecimal[i]){
roman = roman+i;
num = num - romanDecimal[i];
}
}
return roman;
}
for ( var i=1 ; i <=10 ; ++i )
{
document.getElementById("demo").innerHTML+= i+"\t"+romanize(i)+"<br/>";
}
Here's a "scalable" solution in Java. It's "scalable" as long as you don't mind tons of "M"s for very large numbers! :)
public static String intToRoman(int num){
/*
* Symbol I V X L C D M
* Value 1 5 10 50 100 500 1,000
*
* 1776 as MDCCLXXVI
* 1954 as MCMLIV
* 1990 as MCMXC
* 2014 as MMXIV
* 2018 as MMXVIII
*/
StringBuilder romans = new StringBuilder();
// Use LinkedHashMap to preserve entry order of HashMap *very important!*
LinkedHashMap<Integer, String> romanMapping = new LinkedHashMap<Integer, String>();
romanMapping.put(1000, "M");
romanMapping.put(500, "D");
romanMapping.put(100, "C");
romanMapping.put(50, "L");
romanMapping.put(10, "X");
romanMapping.put(5, "V");
romanMapping.put(1, "I");
// Iterate through the LinkedHashMap to build our Roman numeral string
for(Map.Entry<Integer, String> entry : romanMapping.entrySet()){
// Get the number of Roman numeral letters we'll need to correspond to the current num slot value
int curPowerCount = num / entry.getKey();
for(int i = curPowerCount; i > 0; i--){
romans.append(entry.getValue());
}
// number only needs remaining value for next iteration, so modulate!
num %= entry.getKey();
}
return romans.toString();
}
Since it is a design question, how about something like this.
interface Convertable {
public function convert(int)
}
public class RomanNumerals implements Convertable {
public function convert (int $) {
// implementation to convert integer to RomanNumerals
}
}
If we go with this pattern then we could extend this design for any kind of other numerals/integer. Please let me know your feedback. Thanks.
- mohsin May 26, 2018