First challenge!

What is an ambigram?

Ambigrams are word(s) that read the same word(s) or another word given a certain transformation and possibly stylistic alterations.


enter image description here

That's an example of a rotational ambigram; it reads the same word, even when flipped around.

The Challenge

You are to create a function, program, etc. that can detect whether a given input (consisting of only a-zA-Z chars) is a natural symmetric ambigram (an ambigram that reads the same word without significant artistic alteration given a transformation). You can compete in one or more of the following categories:


Examples: I, O, ae, AV, pod

Transformation table (both ways)

a  e/D
b  q
d  p/P
h  y
l  l
m  w
n  u/U
o  o/O/G/Q
s  s/S
t  t
x  x/X
z  z/Z
A  v/V
B  E
D  G
H  H
I  I
M  W
N  N

Output truesy or falsy value.

Reflectional (Vertical Line)

Examples: wow, mom, HOH

Chars to match

b/d i j l m n o p/q s/z t u v w x y A B/E G/D H I M O Q S/Z T U V W X Y

Output truthy or falsy value.

Reflectional (Horizontal Line)

Examples: XOD, KEK, BED

Chars to match

a l o t x B C D E H I K O X

Output truthy or falsy value.



x  n  O
o  u  H
x  M  I

Chars to match

A H I M O T U V W X Y i l m n o t u v w x y

Output truthy or falsy value.

Any (bonus of -50%)

This code should either output the type(s) of ambigram(s) that the input could possibly be (if the input is an ambigram) or a falsy value (if the input is not an ambigram).

Code rules

  • Standard loopholes are disallowed.
  • Input is case-sensitive. This means that AV would count, but aV would not count as a rotational ambigram.
  • An input of zero length is considered to be a natural symmetric ambigram.
  • Make sure to write your header as: # Division, Language, Byte-Count.
  • This is code-golf! You know what that means.
  • 6
    \$\begingroup\$ Consolas is a Microsoft font and not present on all devices. Please include a list of all rotational and reflectional characters in your specification. \$\endgroup\$
    – Dennis
    Oct 30, 2015 at 3:43
  • \$\begingroup\$ I would include a table of characters and their horizontal and vertical reflections. \$\endgroup\$
    – GamrCorps
    Oct 30, 2015 at 3:51
  • \$\begingroup\$ @ThomasKwa Correction: "ambigram," not "anagram." To everyone: I've corrected some stuff. Should be good? \$\endgroup\$ Oct 30, 2015 at 4:21
  • \$\begingroup\$ To qualify for the bonus, what exactly does the submission have to return? \$\endgroup\$
    – Dennis
    Oct 30, 2015 at 5:08
  • \$\begingroup\$ What is "totem"? \$\endgroup\$ Oct 30, 2015 at 6:40

2 Answers 2


Python 2, 258 bytes (622 567 543 516-50%)

Here's my attempt at an answer.

R=dict(zip(list('abdhlmnostxzABDHIMN'),'eD q pP y l w uU oOGQ sS t xX zZ vV E G H I W N'.split()))
for i,j in R.items():
 for c in j:R[c]=R.get(c,'')+i
for i,j in W.items():
 for c in j:W[c]=W.get(c,'')+i
for i in range(len(s)):
 r&=(c in R and l in R[c])
 v&=c in V or(c in W and l in W[c])
 h&=(c in H)+(l in H)>1
 t&=c in T
print 'R'*r+'V'*v+'H'*h+'T'*t

Prints the possible types of ambigrams, or 0 if no ambigrams are possible.

RVHT for rotational, vertical, horizontal and totem respectively.

  • \$\begingroup\$ Should be able to do not (x and y) -> (x)+(y)>1 where x and y are boolean statements. You should also be able to define dictionaries like: R=dict(a='ed',b='q'...). I believe the empty string should count as a falsy value so you can drop the or 0. \$\endgroup\$ Oct 30, 2015 at 14:20
  • \$\begingroup\$ @FryAmTheEggman Thanks! Though it seems should be (x)+(y)<2 or else it's just an and \$\endgroup\$
    – TFeld
    Oct 30, 2015 at 14:34
  • \$\begingroup\$ You're right, and I did some more golfing, but I've just noticed that I think your calculation for vertical reflection is incorrect. I think you need to use a dictionary again, and for example it should match bod I think (I will ask OP though) \$\endgroup\$ Oct 30, 2015 at 15:48
  • \$\begingroup\$ save 34 chars: R=dict(zip(list('abdhlmnostxzABDHIMN'),'eD q pP y l w uU oOGQ sS t xX zZ vV E G H I W N'.split())) \$\endgroup\$
    – Sparr
    Oct 30, 2015 at 15:52
  • \$\begingroup\$ You can save 6 bytes by removing the spaces in H = 'lotxBCDEHIKOX' and the next two lines, and 4 more by removing spaces between if and (. \$\endgroup\$ Oct 30, 2015 at 16:32

All, Ruby, 289 - 50% = 144.5 bytes

i=gets.chop;s=i.tr('ijlmnotuvwxyAHIMOQTUVWXY','').tr'bpsBGS','dqzEDZ';t=i.tr'eDqpPylwuUOGQStXZvVEGHIWN','aabddhlmnnooostxzAABDHIMN';o=(i.tr('alotxBCDEHIKOX','')=='' ? 'V':'')+(s==s.reverse ? 'H':'')+(i.tr('AHIMOUVWXYilmnotuvwxy','')=='' ? 'T':'')+(t==t.reverse ? 'R':'');puts o=='' ? 1<0:o

This seems too long...


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.