Skip to content

Instantly share code, notes, and snippets.

@b-abctech
Created May 13, 2013 10:10
Show Gist options
  • Save b-abctech/5567343 to your computer and use it in GitHub Desktop.
Save b-abctech/5567343 to your computer and use it in GitHub Desktop.
Can't locate object method "ROMANS_TO_NUMBERS" via package "RomanConverter" at line 93
package RomanConverter;
use Moose;
use POSIX qw(floor);
use String::Util qw(trim);
use v5.10;
has 'NUMBERS_TO_ROMANS' => (
is => 'bare' ,
isa => 'Tree' ,
weak_ref => 1 ,
handles => {
1 => 'I' ,
5 => 'V' ,
10 => 'X' ,
50 => 'L' ,
100 => 'C' ,
500 => 'D' ,
1000 => 'M'
}
);
has 'ROMANS_TO_NUMBERS' => (
is => 'bare' ,
isa => 'Tree' ,
weak_ref => 1 ,
handles => {
'I' => 1 ,
'V' => 5 ,
'X' => 10 ,
'L' => 50 ,
'C' => 100 ,
'D' => 500 ,
'M' => 1000
}
);
my %ROMAN_NUMBERS_REVERT = ( 'I' => 1 ,
'V' => 5 ,
'X' => 10 ,
'L' => 50 ,
'C' => 100 ,
'D' => 500 ,
'M' => 1000
);
my %ROMAN_CHECK_SUBSTRACT = (
1 => 0 ,
5 => 4 ,
10 => 9 ,
50 => 40 ,
100 => 90 ,
500 => 400 ,
1000 => 900
);
sub convert {
my ($self, $input_num) = @_;
if($self->_is_valid_number($input_num)) {
return undef;
}
my $roman_result = "";
foreach my $digit (sort{$b <=> $a} keys %{$self->NUMBERS_TO_ROMANS}){
if($input_num >= $digit) {
my $digit_count = floor($input_num / $digit);
$roman_result.= ${$self->NUMBERS_TO_ROMANS}{$digit} x $digit_count;
$input_num = $input_num % $digit;
}
if($input_num >= $ROMAN_CHECK_SUBSTRACT{$digit} && $digit > 1) {
$roman_result.= ${$self->NUMBERS_TO_ROMANS}{$digit-$ROMAN_CHECK_SUBSTRACT{$digit}}.${$self->NUMBERS_TO_ROMANS}{$digit};
$input_num-= $ROMAN_CHECK_SUBSTRACT{$digit};
}
}
return $roman_result;
}
sub revert {
my ($self, $input_roman) = @_;
$input_roman = trim($input_roman);
if($self->_is_valid_roman($input_roman)){
return undef;
}
my @char_array = split(//, $input_roman);
my $number_result = 0;
for (my $i = 0 ; $i < @char_array ; ) {
say "compare between ".${$self->ROMANS_TO_NUMBERS}{$char_array[$i]}." and ".${$self->ROMANS_TO_NUMBERS}{$char_array[$i+1]};
if($i == @char_array-1 || ${$self->ROMANS_TO_NUMBERS}{$char_array[$i]}>=${$self->ROMANS_TO_NUMBERS}{$char_array[$i+1]}){
$number_result += $ROMAN_NUMBERS_REVERT{$char_array[$i]};
$i++;
} else {
$number_result += $ROMAN_NUMBERS_REVERT{$char_array[$i+1]} - $ROMAN_NUMBERS_REVERT{$char_array[$i]};
$i+=2;
}
}
return $number_result;
}
sub _is_valid_number {
my ($self, $number) = @_;
if($number <= 0 || $number > 3000 || $number =~ /\D/ ) {
return 1;
}
}
sub _is_valid_roman {
my ($self, $number) = @_;
if(length($number)==0|| !($number =~ /\A [IVXLCDM]+ \z/ix)) {
return 1;
}
}
1;
no Moose;
__PACKAGE__->meta->make_immutable;
__END__
=head1 NAME
KataRomanConverter - Numbers Roman Convertion Module
=head1 SYNOPSIS
use RomanConverter;
my $converter = RomanConverter->new();
$converter->convert(1990);
$converter->revert("MCMXC");
=head1 DESCRIPTION
Module for converting numbers to roman or revert it back
=head2 Methods
=over 12
=item C<new>
Returns a new RomanConverter object.
=item C<convert>
Parameters
- numbers to convert
Return
- number roman after converting
=item C<revert>
Parameters
- number roman to revert
Return
- number after converting
=item C<_is_valid_number>
- if the number input it's invalid format
invalid case
1. the number is exceed 3000
2. the number is lq to 0
3. the number contain invalid formats eg. decimal format,any others signs, or is not a numbers
Parameters
- numbers to convert
Return
- 1 if it's invalid number format
=item C<_is_valid_roman>
- if the roman number it's invalid format
1. it contains any more than IVXLCDM letters in the string
2. it contains nothing or it's a empty string
Parameter
- roman number to convert
Return
- 1 if it's invalid roman number format
=back
=head1 AUTHOR
B - abc-tech :)
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment