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 '15 at 3:43
  • \$\begingroup\$ I would include a table of characters and their horizontal and vertical reflections. \$\endgroup\$ – GamrCorps Oct 30 '15 at 3:51
  • \$\begingroup\$ @ThomasKwa Correction: "ambigram," not "anagram." To everyone: I've corrected some stuff. Should be good? \$\endgroup\$ – Mama Fun Roll Oct 30 '15 at 4:21
  • \$\begingroup\$ To qualify for the bonus, what exactly does the submission have to return? \$\endgroup\$ – Dennis Oct 30 '15 at 5:08
  • \$\begingroup\$ What is "totem"? \$\endgroup\$ – Peter Taylor Oct 30 '15 at 6:40

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\$ – FryAmTheEggman Oct 30 '15 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 '15 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\$ – FryAmTheEggman Oct 30 '15 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 '15 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\$ – Morgan Thrapp Oct 30 '15 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, privacy policy and cookie policy

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