Benjamin wrote:Wait what? Where's the multi language support?
Change the words in the array.
While I agree that the static approach makes thing a bit easier on the other end, In your version it sort of clumped everything back into one-ish function, and it seems like that defeats the purpose of putting it into a class.
VladSun wrote:...It seemed to be very elegant but it failed on several tests...
Just to lazily save me the trouble of testing it, are you saying that the one you gave works or not?
VladSun wrote:I think that passing the value to be converted to the constructor is the wrong step to make in this case
Just for fun, here's the patch. (works if there are two new lines before beginning of class)
[text]16c16,17
< public function __construct($int, $commas=true) {
---
> public function read($int, $commas=true) {
> $this->text = '';
29a31
> return $this->text;
80,84d81
<
< // Pass result up
< public function read() {
< return $this->text;
< }[/text]
For the more boring types (or those on *sneer* Windows and don't have patch), here's the whole thing.
Code: Select all
class WordedNumber {
private $number;
private $text;
private $w_ones = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
private $w_tens = array(null, null, 'twenty', 'thirty', 'fourty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninty');
private $w_teens = array('ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'ninteen');
private $w_name = array('', ' thousand', ' million', ' billion', ' trillion', ' quadrillion');
private $comma_index = 0;
private $name_index = false;
private $digits = 0;
private $comma_enabled;
// Parent processor
public function read($int, $commas=true) {
$this->text = '';
if (intval($int) == 0) {
$this->text = $this->w_ones[0];
return;
}
$this->formatInput($int);
$this->setNamePos();
$this->comma_enabled = $commas;
foreach ($this->number as $chunk) {
$chunk = array_pad($chunk, 3, 0);
$tens = $this->getTens($chunk);
$hundreds = $this->getHundreds($chunk[2]);
$this->text .= $hundreds . $tens;
}
return $this->text;
}
// Process first two digits
private function getTens($int) {
$have_comma = ($this->comma_index > 1 && $this->comma_enabled ? ', ' : ' ');
$len = count($int);
$name = prev($this->w_name);
$result = '';
if ($int[1] == 1) {
$teen_num = $this->w_teens[$int[0]];
$result = $teen_num . $name . $have_comma;
$this->comma_index++;
$this->name_index = true;
} elseif ($int[0] > 0 || $int[1] > 0) {
$one_digit = $this->w_ones[$int[0]];
$ten_digit = $this->w_tens[$int[1]];
$have_dash = $ten_digit && $one_digit ? '-' : '';
$result = $ten_digit . $have_dash . $one_digit . $name . $have_comma;
$this->comma_index++;
$this->name_index = true;
}
return $result;
}
// Process hundred's place
private function getHundreds($int) {
$result = '';
if ($int > 0) {
$one_digit = $this->w_ones[$int];
$num_name = ($this->name_index ? '' : prev($this->w_name));
$have_comma = ($this->comma_index > 1 && !$this->name_index && $this->comma_enabled ? ', ' : ' ');
$result = $one_digit . ' hundred' . $num_name . $have_comma;
$this->comma_index++;
}
return $result;
}
// Get input ready for processing
private function formatInput($int) {
$this->number = array_map('intval', array_reverse(str_split(strval($int))));
$this->digits = count($this->number);
$this->number = array_reverse(array_chunk($this->number, 3));
}
// Set initial index position for number names
private function setNamePos() {
for ($i = 0; $i < count($this->number); $i++) {
next($this->w_name);
}
}
}