Created
July 30, 2012 13:24
-
-
Save pjlsergeant/3206885 to your computer and use it in GitHub Desktop.
Divide by three without using numeric operators...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use strict; | |
| use warnings; | |
| no warnings 'numeric'; | |
| print "$_ -> " . div3( $_ ) . "\n" for map { $_ / 10 } 0 .. 10; | |
| print "$_ -> " . div3( $_ ) . "\n" for 0 .. 10; | |
| sub div3 { | |
| my $input = shift; | |
| # Turn it in to its digits, casting in to a string | |
| my @digits = split //, $input; | |
| # Create a 30-item list. This should be done outside the loop, obv | |
| my @lookup = map { [$_,0], [$_,1], [$_,2] } 0 .. 9; | |
| # You could do this more gracefully with reduce, but it's easier to | |
| # understand this way. This is the 'digit' we carry | |
| my $carry = ''; | |
| # We'll build up a string output here | |
| my $output = ''; | |
| # Have we passed a decmial? | |
| my $float = 0; | |
| # For every digit... | |
| while ( @digits ) { | |
| my $digit = shift( @digits ); | |
| # Pass the period through, noting that we're now in floating territory | |
| if ( $digit eq '.' ) { | |
| $float = 1; | |
| $output .= '.'; | |
| # Otherwise | |
| } else { | |
| # Concatenate the carry 'digit' and the current 'digit' | |
| $digit = $carry . $digit; | |
| # Lookup how that divides by three | |
| my ( $result, $remainder ) = @{ $lookup[ $digit ] }; | |
| # If the remainder is 0, we actually want a zero-length string | |
| $carry = $remainder || ''; | |
| # Unless it's a leading 0, add the number to our output | |
| $output .= $result if length( $output ) || $result; | |
| # If we have a carry but are all out of digits, round | |
| if ( $carry && ! @digits ) { | |
| unless ( $float ) { $output .= '.' } | |
| $output .= [1,4,7]->[$carry]; | |
| last; | |
| } | |
| } | |
| } | |
| return $output || 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment