Duncan's blog

October 2, 2014

Project Euler: problem 17 (PHP) – Number letter counts

Filed under: PHP,Project Euler — duncan @ 8:00 am

Eleven and a halfI previously blogged about this Project Euler puzzle 6 years ago, using ColdFusion.  This is my approach using PHP as a simple practical exercise for myself, and I’d appreciate any feedback on my PHP code.

Problem 17:

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.

Code:

<?php
$numbers = array();
$words = array();
$sum = 0;

$numbers[1] = "one";
$numbers[2] = "two";
$numbers[3] = "three";
$numbers[4] = "four";
$numbers[5] = "five";
$numbers[6] = "six";
$numbers[7] = "seven";
$numbers[8] = "eight";
$numbers[9] = "nine";
$numbers[10] = "ten";
$numbers[11] = "eleven";
$numbers[12] = "twelve";
$numbers[13] = "thirteen";
$numbers[14] = "fourteen";
$numbers[15] = "fifteen";
$numbers[16] = "sixteen";
$numbers[17] = "seventeen";
$numbers[18] = "eighteen";
$numbers[19] = "nineteen";
$numbers[20] = "twenty";
$numbers[30] = "thirty";
$numbers[40] = "forty";
$numbers[50] = "fifty";
$numbers[60] = "sixty";
$numbers[70] = "seventy";
$numbers[80] = "eighty";
$numbers[90] = "ninety";

for ($i = 1; $i <= 1000; $i++) {
	$numberAsString = "";
	
	// how many thousands?
	$thousands = (int)($i / 1000);
	$hundreds = (int)($i / 100);
	$tens = ((int)($i / 10)) % 10;
	$units = (int)($i % 10);
	
	if ($thousands > 0) {
		$numberAsString .= $numbers[$thousands] . " thousand";
	}
	
	if ($hundreds > 0 && $hundreds < 10) {
		$numberAsString .= $numbers[$hundreds] . " hundred";
		
		if (($tens > 0 && $tens < 10) || $units > 0) {
			$numberAsString .= " and ";
		}
	}
	
	if ($tens == 1) {
		$numberAsString .= $numbers[($tens*10) + $units];
	}
	
	if ($tens > 1 && $tens < 10) {
		$numberAsString .= $numbers[$tens*10] . " ";
	}
	
	if ($units > 0 && $tens != 1) {
		$numberAsString .= $numbers[$units];
	}
	
	// strip out the spaces
	array_push($words, preg_replace('/\s/', "", $numberAsString));
}

foreach ($words as $word) {
	$sum += strlen($word);
}

echo $sum;

So, PHP doesn’t seem to have an arithmetic operator for doing integer division, whereas in CFML you just do x \  y.  So instead I’m just doing normal division, then casting the result to an integer.  Alternatively I could probably have used the catchily-named gmp_div_q() function.

The only other point, PHP doesn’t seem to like the POSIX names like [:space:] for regular expressions, and the POSIX regex functions (ereg_replace) are deprecated.  So I simply use /s instead… just seems strange that POSIX isn’t implemented in PHP.

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: