patternjavaModerate
Project Euler 17: counting letters needed to write numbers
Viewed 0 times
neededcountingnumberswriteprojecteulerletters
Problem
The statement of the problem is :
If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.
This problem seemed simple at first, but got me really involved. So my implementation is pretty straightforward and really dirty.
```
public class Euler_17{
public static String[] digits = {"Error", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine"};
public static String[] tensArray = {"Error", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety"};
public static String[] elevenToNineteen = {"Error", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
public static String giveMeString(int num){
// Using StringBuilder to make up the number
StringBuilder theNumber = new StringBuilder();
// String value of the number so that I can
// extract specific numbers from it
String number = String.valueOf(num);
// Deals with three digit numbers
if(number.length()==3){
int units = Integer.parseInt(String.valueOf(number.charAt(2)));
int tens = Integer.parseInt(String.valueOf(number.charAt(1)));
int hundreds = Integer.parseInt(String.valueOf(number.charAt(0)));
if(tens == 0){
if(units == 0){
theNumber.append(digits[hundreds]);
theNumber.append("Hundred");
return theNumber.toString();
}
xHunderedAnd(theNumber, hundreds);
If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage.
This problem seemed simple at first, but got me really involved. So my implementation is pretty straightforward and really dirty.
```
public class Euler_17{
public static String[] digits = {"Error", "one", "two", "three", "four", "five", "six",
"seven", "eight", "nine"};
public static String[] tensArray = {"Error", "twenty", "thirty", "forty", "fifty",
"sixty", "seventy", "eighty", "ninety"};
public static String[] elevenToNineteen = {"Error", "eleven", "twelve", "thirteen", "fourteen",
"fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
public static String giveMeString(int num){
// Using StringBuilder to make up the number
StringBuilder theNumber = new StringBuilder();
// String value of the number so that I can
// extract specific numbers from it
String number = String.valueOf(num);
// Deals with three digit numbers
if(number.length()==3){
int units = Integer.parseInt(String.valueOf(number.charAt(2)));
int tens = Integer.parseInt(String.valueOf(number.charAt(1)));
int hundreds = Integer.parseInt(String.valueOf(number.charAt(0)));
if(tens == 0){
if(units == 0){
theNumber.append(digits[hundreds]);
theNumber.append("Hundred");
return theNumber.toString();
}
xHunderedAnd(theNumber, hundreds);
Solution
You don't quite seem to have realized this, but...
"One hundred and ..." means that what you can do is, for a 3 digit number - count the hundreds, as "One hundred" and "Two hundred", and then append what's left if the number passed in is not a multiple of hundred.
That way you deal with 2 digit numbers in only 1 place. As for how you'd go about it - just call
There's other tricks you could use, though. You know how long "OneTwoThree...NinetyNine" is. You also know it continues with "OneHundredOneHundredAndOneOneHundredAndTwo" or, basically, length of (1-99) + 99x ("OneHundredAnd") + 1 x ("OneHundred") gives you 1-199. From there on, it becomes simple addition and multiplication.
If you keep your old implementation, you can use that to verify that the maths based approach works.
"One hundred and ..." means that what you can do is, for a 3 digit number - count the hundreds, as "One hundred" and "Two hundred", and then append what's left if the number passed in is not a multiple of hundred.
That way you deal with 2 digit numbers in only 1 place. As for how you'd go about it - just call
giveMeString again, but with the remainder - so giveMeString(150) does "OneHundred" + "and" + giveMeString(50).There's other tricks you could use, though. You know how long "OneTwoThree...NinetyNine" is. You also know it continues with "OneHundredOneHundredAndOneOneHundredAndTwo" or, basically, length of (1-99) + 99x ("OneHundredAnd") + 1 x ("OneHundred") gives you 1-199. From there on, it becomes simple addition and multiplication.
If you keep your old implementation, you can use that to verify that the maths based approach works.
Context
StackExchange Code Review Q#119648, answer score: 10
Revisions (0)
No revisions yet.