HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Project Euler 17: counting letters needed to write numbers

Submitted by: @import:stackexchange-codereview··
0
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);

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 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.