This is just a procrastination project for me, rather than anything that I expect to be useful. Here's the deal: check whether a number is the same when rotated half a turn (180 degrees or pi radians, whichever you prefer). (At this point, it's more a string than a number, but let's keep things simple.)

I've taken a few minor liberties with what counts as what when rotated; it's pretty easy to see that an upside-down 6 is a 9 (and vice versa), and that 1 and 8 are basically the same thing when rotated (despite the serifs on the 1 and any size difference your font might have on the 8's loops), but the 2<->5 thing is more of a judgement call.

Anyways, here's my implementation. It's a brute-force thing, lacking in both elegance and hack value. Can you come up with something cleverer? (This smells like a good problem to golf.)

#!/usr/bin/perl -w use strict; my %rotated = ( 0 => 0, 1 => 1, 2 => 2, 3 => undef, 4 => undef, 5 => 5, 6 => 9, 7 => undef, 8 => 8, 9 => 6 ); sub is_rotateable { my ($n) = @_; my @num = split '', $n; my @mun = reverse @num; foreach (0..$#num) { my $d = $num[$_]; return 0 if $rotated{$d} != $mun[$_]; } return 1; } for (@ARGV) { print "$_ is rotateable\n" if &is_rotateable($_); }

Edit: Yes, zeros are digits too. (D'oh!) Thanks Zaxo. Hmm... just offhand, I don't think this would be terribly interesting with, say, Roman numerals.

Edit: Duh. Thanks claree0... reading the replies to this post has been fun, but not exactly great for my ego. :-)

--
F o x t r o t U n i f o r m
Found a typo in this node? /msg me
% man 3 strfry

Replies are listed 'Best First'.
Re: (Challenge) Rotateable numbers
by BrowserUk (Patriarch) on Sep 16, 2004 at 02:05 UTC

    534

    sub is_rotatable{ #23456789 123456789 123456789 123456789 123456789 1234 (local$_=$_[0])=~y/0125689347/0152968/;reverse eq$_[0] }

    I transposed two digits in posting above.

    P:\test>type junk.pl sub is_rotatable{ #23456789 123456789 123456789 123456789 123456789 1234 (local$_=$_[0])=~y/0125689347/0152986/;reverse eq$_[0] } printf "%s %s rotatable\n", $_, is_rotatable( $_ ) ? 'is' : 'not' for 33, 131, 141, 171, 25696925, 101, 88; P:\test>junk 33 not rotatable 131 not rotatable 141 not rotatable 171 not rotatable 25696925 is rotatable 101 is rotatable 88 is rotatable

    48

    P:\test>type junk.pl sub is_rotatable{ #23456789 123456789 123456789 123456789 12345678 (local$_=$_[0])=~y/2569347/5296/;reverse eq$_[0] } printf "%s %s rotatable\n", $_, is_rotatable( $_ ) ? 'is' : 'not' for 33, 131, 141, 171, 25696925, 101, 88; P:\test>junk 33 not rotatable 131 not rotatable 141 not rotatable 171 not rotatable 25696925 is rotatable 101 is rotatable 88 is rotatable

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: (Challenge) Rotateable numbers
by tachyon (Chancellor) on Sep 16, 2004 at 08:00 UTC

    37

    sub is_rotatable{ #234567890123456789012345678901234567 $_=$_[0];y/2569347/5296/;pop==reverse }

    cheers

    tachyon

      The reason tachyon's version doesn't work is not because of removing the 347, but because he golfed away the localisation of $_.

      P:\test>type junk.pl sub is_rotatable{ #234567890123456789012345678901234567 $_=$_[0];y/2569347/5296/;pop==reverse } printf "%s %s rotatable\n", $_, is_rotatable( $_ ) ? 'is' : 'not' for 33, 131, 141, 171, 25696925, 101, 88; P:\test>junk Modification of a read-only value attempted at P:\test\junk.pl line 3.

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail
      "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

        As noted at Re^3: (Challenge) Rotateable numbers the tr does not remove the digits 347 it replaces them with the digit 6. Not that it matters either way. Localisation does not matter either unless you happen to use $_ in your loop test case.....Nice algorithm BTW.

        cheers

        tachyon

      No good. 33 isn't rotatable, but yours reports it as being so. (You can't strip the 347 out and compare the rest for rotatability.)

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested

        Given that it does not report 33 as rotatable I don't see your point. Also the digits 347 are not stripped, they are replaced with the digit 6, see the man for tr. It would not actually matter if they were stripped or replaced the original value will not be equal to the reversed value.

        sub is_rotatable{ #234567890123456789012345678901234567 $_=$_[0];y/2569347/5296/;pop==reverse } for my $i(3,33,131,141,171,25696925,101,88) { printf "%s %s rotatable\n", $i, is_rotatable( $i ) ? 'is' : 'not' } __DATA__ 3 not rotatable 33 not rotatable 131 not rotatable 141 not rotatable 171 not rotatable 25696925 is rotatable 101 is rotatable 88 is rotatable

        cheers

        tachyon

Re: (Challenge) Rotateable numbers
by belg4mit (Prior) on Sep 16, 2004 at 01:15 UTC
    sub is_rotateable{ local $_ = shift; # Shave two # y/23467/5XX9X/; # return 0 if /X/; y/26/59/; return 0 if /[347]/; @_ = split//; while( @_ > 1 ){ return 0 unless shift == pop; } return 1; }
    UPDATE: FYI That's 122 including the sub, 102 without. OP was 281 less the whitespace though some easy shavings existed such as s/=>/,/g.

    --
    I'm not belgian but I play one on TV.

Re: (Challenge) Rotateable numbers
by dragonchild (Archbishop) on Sep 16, 2004 at 01:44 UTC
    49 characters.
    sub r{ local$_=$@=pop;y/2569/5296/;$@!~/[347]/&&$@==reverse }

    Update: 46 characters:

    sub r{ y/2569/5296/for$@=pop;$@!~/[347]/&&$@==reverse }

    Update: 43 characters:

    sub r{ y/2569/5296/for$@=pop;!/[347]/&&$@==reverse } # A slightly different take ... sub r2{ y/2569/5296/for$@=pop;!(/[347]/|$@-reverse) }

    Update: 42 characters ... I'm not so certain about this one, but it passes my tests. *shrugs* It looks like it should work because I'm bit-anding SV_yes and SV_no values, which should DWIM in that context.

    sub r{ y/2569/5296/for$@=pop;!/[347]/&$@==reverse } sub r{ y/2569/5296/for$@=pop;!y/347//&$@==reverse }

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

      Could you please include the appropriate magic incantation? I believe that's standard golf procedure (even though the strokes don't count).

      --
      I'm not belgian but I play one on TV.

Re: (Challenge) Rotateable numbers
by claree0 (Hermit) on Sep 22, 2004 at 07:09 UTC
    Um, surely 2=>2 and 5=>5
      22222222 55555555 22222222 55555555 22 55 22 55 22222222 55555555 22222222 55555555 22 55 22 55 22222222 55555555 22222222 55555555
      Now turn your monitor upside down, and see if the 2 is made of 2's or 5's. (Update: I am trying to demonstrate claree0's point, not refute it.)