Numbers with Rotational Symmetry

27

1

Given an integer, output a truthy value if it is the same upside-down (rotated 180°) or a falsy value otherwise.

0, 1, and 8 have rotational symmetry. 6 becomes 9 and vice versa.

Sequence of numbers producing truthy results: OEIS A000787

0, 1, 8, 11, 69, 88, 96, 101, 111, 181, 609, 619, 689, 808, 818, 888, 906, 916, 986, 1001, 1111, 1691, 1881, 1961, 6009, 6119, 6699, 6889, 6969, 8008, 8118, 8698, 8888, 8968, 9006, 9116, 9696, 9886, 9966, 10001, 10101, 10801, 11011, 11111, 11811, 16091, ...

This question is inspired by my own reputation at the time of posting: 6009.

mbomb007

Posted 2016-04-15T19:31:47.397

Reputation: 21 944

This looks like a dupe of Print rotation-safe numbers.

– xnor – 2016-04-15T20:56:05.980

2@xnor They're not the same at all. That question involves whether the number would become another valid number upon rotation (and append a period to keep it distinct), not whether it is the same number. I looked into that question before posting mine. – mbomb007 – 2016-04-15T21:18:49.533

@mbomb007 My mistake. I reopened. – xnor – 2016-04-15T21:21:23.367

May we take the input as a string? – xnor – 2016-04-15T21:26:26.797

@xnor If the language has numeric types, it should use them, for function parameters, for example. But if, in Python for example, you take raw_input, the user entered an integer, which would become a string behind the scenes. That's fine. – mbomb007 – 2016-04-15T21:32:42.673

Answers

6

05AB1E, 22 16 15 14 bytes

Code:

Â23457ð«-69‡Q

Try it online!


Previous code:

Â69‡Q¹¹„vd•ÃQ*

To figure out if the string is rotational symmetric, we just need to transliterate 69 with 96, reverse the string and check if they are equal. The other thing we need to know is if the number only contains the digits 0, 1, 8, 6 and 9. So that's exactly what we are going to do:

                     # Bifurcate the input, which pushes input and input[::-1]
 69Â                  # Bifurcate 69, which pushes 69 and 96.
    ‡                 # Transliterate 69 with 96 in the input, e.g. 1299 becomes 1266.
     Q                # Check for equality.
      ¹¹              # Push input again twice.
        „vd•          # Compressed version for 10869.

The „vd• part actually converts the string vd from base 190 to base 10. You can try this out here.

            Ã        # Keep the characters of the second string in the first string.
                       667788 would become 6688 (since 7 is not in 10869).
             Q       # Check for equality.
              *      # Multiply the top two numbers, which actually does an AND function.

Uses CP-1252 encoding. Try it online!

Adnan

Posted 2016-04-15T19:31:47.397

Reputation: 41 965

10

Python 2, 50 bytes

lambda n:`n`==`map('01xxxx9x86'.find,`n`)`[-2::-3]

The method '01xxxx9x86'.find takes a digit character to it's upside-down number, with any unflippable digit giving -1. This function is mapped to the reversed number string, producing a list of digits.

This is converted to a string with the [1::3] trick, except it's reversed instead by doing [-2::-3] (thanks to Dennis for this, saving 4 bytes), and compared to the original number string. Any -1's from unflippable digits will misalign the conversion, making it fail.


56 bytes:

lambda n:`n`[::-1]==`n`.translate('01xxxx9x86______'*16)

Checks if the number string reversed is the same as it with the upside-down replacements. Digits that can't be flipped are replaced with 'x' to always give the wrong answer.

The replacement is done with translate on a string of 256 chars, replacing the corresponding ASCII values. Only the 10 values 48 to 57 matter, but I padded to length 16 to make the total length be 256. I wonder if there's a shorter way.

Some other approaches (lengths 59, 60, 60):

lambda n:set(zip(`n`,`n`[::-1]))<=set(zip('01896','01869'))
r=lambda s:set(zip(s,s[::-1]));lambda n:r(`n`)<=r('9018106')
lambda n:all(a+b in'001188969'for a,b in zip(`n`,`n`[::-1]))

xnor

Posted 2016-04-15T19:31:47.397

Reputation: 115 687

Maybe this will help: http://codegolf.stackexchange.com/a/48994/34718

– mbomb007 – 2016-04-15T21:41:02.953

6

Ruby, 54 46 bytes

 ->a{(b=a.to_s).tr('1-9','1w-z9x86').reverse==b}

I don't know, is anonymous functions like that allowed or not

Basically same idea as Python2 answer. If input is not integer, act bad (i.e. aba gives true)

m0003r

Posted 2016-04-15T19:31:47.397

Reputation: 61

1Welcome to Programming Puzzles and Code Golf! Nice first answer :D Anonymous functions are allowed in any context where normal named functions are allowed. – cat – 2016-04-16T00:08:50.033

What even is a “function” by our standards? – cat – 2016-04-16T00:10:58.463

4

JavaScript (ES6), 56 bytes

n=>n==[...''+n].reverse().map(c=>'0100009086'[c]).join``

Neil

Posted 2016-04-15T19:31:47.397

Reputation: 95 035

What does the ... in the array do? – ericw31415 – 2016-04-21T20:35:59.210

@ericw31415 In this case it turns the string into an array of characters. More generally, you can provide anything iterable and it will iterate it and include the elements in the array. – Neil – 2016-04-21T22:44:45.617

So [...''+n] is essentially the same thing as n.split("")? Where can I read more about this? – ericw31415 – 2016-04-21T22:47:13.843

@ericw31415 Yes, in this case I use it as a shorthand for split\``. See A more powerful array literal

– Neil – 2016-04-21T22:52:03.790

2

Perl, 29 26 bytes

Includes +1 for -p

Run with the input on STDIN:

rotation.pl <<< 69

rotation.pl:

#!/usr/bin/perl -p
$_=reverse==y/962-7/69a/r

Ton Hospel

Posted 2016-04-15T19:31:47.397

Reputation: 14 114

2

Jelly, 16 15 bytes

,ȷ9+90860¤Dị/⁼Ṛ

Try it online!

How it works

,ȷ9+90860¤Dị/⁼Ṛ  Main link. Argument: n (integer)

         ¤       Evaluate the three links to the left as a niladic chain:
 ȷ9              Yield 1000000000.
    90860        Yield 90860.
   +             Add to yield 1000090860.
,                Pair; yield [n, 1000090860].
          D      Convert both integers to base 10.
           ị/    Reduce by index, i.e., for each digit of n, retrieve the element
                 of [1, 0, 0, 0, 0, 9, 0, 8, 6, 0] at that index (1-based).
              Ṛ  Yield the digits of n in reversed order.
             ⁼   Test for equality.

Dennis

Posted 2016-04-15T19:31:47.397

Reputation: 196 637

This answer is tied with another at 15 bytes, but the other answer was posted first. Can you shave off 1 byte? – mbomb007 – 2016-04-18T14:50:46.923

I've tried quite hard; I don't think I can. However, our default tie breaker is first answer to achieve the winning score, and I think I got to 15 first.

– Dennis – 2016-04-18T15:06:11.453

2

Retina, 57 49 bytes

8 bytes saved thanks to @Martin Büttner.

+`^(([018])(.*)\2|9(.*)6|6(.*)9)$
$3$4$5
^[018]?$
  • Apply reduction as such: 1610880191 -> 61088019 -> 108801 -> 0880 -> 88 -> (empty).
  • Returns 1 if only 0, 1, 8, or (empty) is left.
  • Returns 0 otherwise.

Try it online!

Leaky Nun

Posted 2016-04-15T19:31:47.397

Reputation: 45 011

2

Retina, 40 38 33 bytes

$
;$_
T`92-7`69`;.+
+`(.);\1
;
^;

Try it online!

Explanation

This uses a completely different approach from the other Retina answer. Instead of removing all symmetric parts, we simply perform the transformation of reversing the string and swapping 6 and 9s and then compare for equality. To make sure that no non-symmetric digits appear we also turn them into 9s in one half.

$
;$_

We duplicate the input by matching the end of the string and inserting ; followed by the entire input.

T`92-7`69`;.+

This performs a character transliteration only on the second half by matching it with ;.+. The two transliteration sets expand to:

9234567
6999999

Because 2-7 denotes a range and the target set is padded with the last character to match the length of the source set. Hence, the stage swaps 6 and 9 and also turns all of 23457 into 9s.

+`(.);\1
;

Repeatedly (+) remove a pair of identical characters around the ;. This will either continue until only the ; is left or until the two characters around the ; are no longer identical, which would mean that the strings aren't the reverse of each other.

^;

Check whether the first character is ; and print 0 or 1 accordingly.

Martin Ender

Posted 2016-04-15T19:31:47.397

Reputation: 184 808

Lever, very lever. – CalculatorFeline – 2016-04-17T01:29:36.773

2

sh, 40 33 bytes

[ `rev<<<$1|tr 6923457 96` = $1 ]

Input via command line argument, output via exit code. Generate all testcases:

for i in `seq 0 10000`
do
  if [ `rev<<<$i|tr 6923457 96` = $i ]
  then
    echo $i
  fi
done

Rainer P.

Posted 2016-04-15T19:31:47.397

Reputation: 2 457

2

TSQL, 122 bytes

I am new to code golf, so not quite sure how to count the characters. Counting it as 1 here since the number used in this case is 8

This will return 1 when the reversed value match and nothing when it doesn't match:

SELECT 1FROM(values(8))x(x)WHERE(x)NOT like'%[23457]%'and REPLACE(REPLACE(x,6,4),9,6)=REVERSE(REPLACE(REPLACE(x,9,4),9,6))

Human readable:

SELECT 1
FROM
  (values(808))x(x)
WHERE(x)
  NOT like'%[23457]%'
  and REPLACE(REPLACE(x,6,4),9,6)=REVERSE(REPLACE(REPLACE(x,9,4),9,6))

t-clausen.dk

Posted 2016-04-15T19:31:47.397

Reputation: 2 874

1

GNU sed, 84 bytes

(including +1 for -r flag)

:
s/^6(.*)9$/\1/
s/^9(.*)6$/\1/
s/^([081])(.*)\1$/\2/
t
s/^[081]$//
s/.+/0/
s/^$/1/

If the line ends with a rotation of its beginning character, trim both ends by one. Repeat until there's no match. Account for a single symmetric character, then if anything remains, the input was not symmetric, and we return false; otherwise return true.

Toby Speight

Posted 2016-04-15T19:31:47.397

Reputation: 5 058

1

Pyth - 21 bytes

&!-z+`180K`69qzX_z_KK

Test Suite.

Maltysen

Posted 2016-04-15T19:31:47.397

Reputation: 25 023

X_zK does the same job as X_z_KK. 3rd parameter is optional. – Jakube – 2016-04-15T21:04:02.120

1

Pyth, 17 bytes

!-FmC_B`d,QC\

Test it in the Pyth Compiler.

How it works

!-FmC_B`d,QC\  (implicit) Store the input in Q.

            \  Yield the Unicode character with code point 1068901.
           C    Compute its code point.
         ,Q     Pair the input and 1068901.
   m            Map; for each d in [Q, 1068901]:
       `d         Yield the string representation of d.
     _B           Yield the pair of `d` and `d` reversed.
    C             Zip. For the second string, this gives
                  ['11', '00', '69', '88', '96', '00', '11'].
 -F             Fold by difference, i.e., removes all pairs in the second list
                from the first list.
!               Logically negate the result, returning True iff the list is empty.

Dennis

Posted 2016-04-15T19:31:47.397

Reputation: 196 637

1

Visual Basic for Applications, 150 111 bytes

Usable in console or as an UDF.

Function c(b)
c=(Not b Like"*[!01869]*")And b=Replace(Replace(Replace(StrReverse(b),9,7),6,9),7,6)
End Function

Improved by taking advantage of implicit type conversions and by doing three steps swapping instead of two steps on each side of the equation. Count includes Function and End Function statements.

dnep

Posted 2016-04-15T19:31:47.397

Reputation: 301

1

C, 82 bytes

char*s="0100009086";f(x){int y=0,z=x;for(;x;x/=10)y=y*10+s[x%10]-'0';return z==y;}

Expanded

char *s = "0100009086";
int f(int x)
{
    int y=0, z=x;
    for(; x; x/=10)
        y = y*10 + s[x%10]-'0';
    return z==y;
}

Explanation

We reverse the digits of x using modulo-10 arithmetic, replacing 6 and 9 by their reflections as we go. We replace the rotationally-asymmetric digits by zeros (note that we can handle symmetric fives and/or twos by simply changing the replacement table s). If the new number is equal to the original (saved in 'z'), then it is rotationally symmetric.

Test program

#include <stdio.h>
int main()
{
    int i;
    for(i=0;  i <= 16091; ++i)
        if (f(i))
            printf("%d\n", i);
}

This prints the list of symmetric numbers given in the question.

Toby Speight

Posted 2016-04-15T19:31:47.397

Reputation: 5 058

0

MATL, 25 21 22 bytes

j69801VmAGtP69VtPXE=vA

Try it Online!

Explanation

j       % Explicitly grab input as string
69801   % Number literal
V       % Convert to a string
mA      % Check if all input chars are members of this list
G       % Explicitly grab the input
tP      % Duplicate and flip it
69      % Number literal
V       % Convert to string ('69')
tP      % Duplicate and flip it ('96')
XE      % Replace all '6' with '9', and '9' with '6'
=       % Check that this substituted string is equal to the original
v       % Vertically concatenate all items on the stack
A       % Ensure everything is true
        % Implicitly print boolean result

Suever

Posted 2016-04-15T19:31:47.397

Reputation: 10 257

0

Seriously, 23 bytes

,$;`"01xxxx9x86"í`MRεj=

Try it online!

This is essentially a port of xnor's Python 2 solution.

Explanation:

,$;`"01xxxx9x86"í`MRεj=
,$;                      push two copies of str(input)
   `"01xxxx9x86"í`M      map: get each digit's rotated digit (or x if not rotatable)
                   Rεj   reverse and join on empty string to make a string
                      =  compare equality with original input

Mego

Posted 2016-04-15T19:31:47.397

Reputation: 32 998

0

Kotlin, 69 bytes

This takes the number, converts it to a string, rotates it, and then compares it with the original as a string for equality. Non-rotatable digits are simply converted to 0

{i->"$i".map{"0100009086"[it-'0']}.joinToString("").reversed()=="$i"}

Test it Here!

TheNumberOne

Posted 2016-04-15T19:31:47.397

Reputation: 10 855