Do you remember my mat properly grouped by colors?

My mat properly grouped by colors

Yesterday I was looking at it and realized that some letters fit inside others. Example: a letter P fits in the place where the letter R goes. So here's a simple challenge: given two letters, return a truthy value if any one of the letters fits inside the other (directly or rotated, but not flipped), or a falsey value if they don't. That is, if the input is [P,R] or [R,P], you must return truthy because in both cases one letter fits inside the other. If you get [L,U] you must return falsey as neither fit inside the other.


  • The input must be two alphanumeric characters in the range [0-9A-Z], as there are also numbers in the mat, in any form you need (two separate chars as two inputs, a list with two chars, a string with the 2 chars, whatever).
  • The output must be consistent (the truthy and falsey values must be always the same).
  • Following is the table of fittings (note that a letter always fits in its proper place, just in case you get something like [Y,Y] as input):

    char fits inside chars
       C             G,O
       F             B,E,P,R
       G             O
       I             0,1,7,B,D,E,F,H,K,L,M,N,O,P,R,T,V,W,X,Z
       L             E
       M             W
       P             R
       S             O
       V             A
       W             M
       0             O
       1             B,E,L
       3             O
       6             9,O
       8             O
       9             6,O

I solemnly swear that I have tested every fitting in my kid's mat. (Dries his sweat from his forehead.)

This is , so may the shortest code for each language win!

Some test cases

input  output
[C,G]  truthy (C fits inside G)
[G,C]  truthy (C fits inside G)
[F,R]  truthy (F fits inside R)
[M,W]  truthy (both fit inside the other)
[O,S]  truthy (S fits inside O)
[T,T]  truthy (T fits in its place)
[E,V]  falsey (no fit found)
[P,L]  falsey

Sandbox post. Please, forgive me if you spot more fittings that I missed. Many thanks to Οurous for helping me with the fittings list.

  • 1
    \$\begingroup\$ kolmogorov-complexity. \$\endgroup\$
    Commented Dec 20, 2017 at 8:23
  • 1
    \$\begingroup\$ 1 doesn't fit in F? \$\endgroup\$
    Commented Dec 20, 2017 at 8:44
  • \$\begingroup\$ @user202729 no, because you need to flip the 1 to fit it in the F but that's not allowed in my mat. :-) \$\endgroup\$
    – Charlie
    Commented Dec 20, 2017 at 8:48
  • 4
    \$\begingroup\$ Illustration ASCII-art graph (of course fit-in is transitive) \$\endgroup\$
    Commented Dec 20, 2017 at 8:58
  • 1
    \$\begingroup\$ @Οurous it was in this other question when it already had two answers... Besides, the challenge already has many cases to test, more cases won't add anything to it (I think the most creative part is that the two inputs are interchangeable as you have to check both fittings). \$\endgroup\$
    – Charlie
    Commented Dec 20, 2017 at 12:04

10 Answers 10


Python 2, 135 130 129 bytes

-1 byte thanks to Lynn

lambda s:cmp(*s)%2*s[::cmp(*s)|1]in'OIH TIE XI7 RF O8 OGC LI0 O3 O96 VA O6 KI PI WI L1 WMI O0 RIB NI1 FE SOC VID ZIFB1 PF LE1 RP'

Try it online!

Python 3, 143 bytes

lambda*i:any({*i}&{a,c}=={*i}for a,b in zip('CFGILMPSVW013689','GO BEPR O 017BDEFHKLMNOPRTVWXZ E W R O A M O BEL O 9O O 6O'.split())for c in b)

Try it online!


Retina, 93 92 bytes



Try it online! Edit: Saved 1 byte thanks to @ovs.

  • \$\begingroup\$ Does this work for 92 bytes? \$\endgroup\$
    – ovs
    Commented Dec 20, 2017 at 17:56

Clean, 276 226 bytes

Vaguely golfed-ish. Will polish tomorrow.

import StdEnv
i a b=isMember b a
f _ _=False
?a b=a==b||f a b||f b a

Try it online!


Haskell, 149 145 bytes


Try it online!


Javascript 155 153 151 149 bytes

I think this works on all cases, 1/0 for true/false.



c, // input 1
f, // input 2
q=1 // variable used to execute F twice
                              // array of strings where [0] is input 1 and [>0] are the fittings
.some(                        // any element of the array meets:
(v=>v[0]==c&v.includes(f)))|  // input 1 equals [0] and input 2  exists in the lookup string OR
c==f|                         // input 1 equals input 2 OR
(q?F(f,c,0):0)                // input 2 fits inside input 1

let F=(c,f,q=1)=>"CGO,FBEPR,GO,I017BDEFHKLMNOPRTVWXZ,LE,MW,PR,SO,VA,WM,0O,1BEL,3O,69O,8O,96O".split`,`.some((v=>v[0]==c&v.includes(f)))|c==f|(q?F(f,c,0):0);
let tests = [
  ["C","G"],  //truthy (C fits inside G)
  ["G","C"],  //truthy (C fits inside G)
  ["F","R"],  //truthy (F fits inside R)
  ["M","W"],  //truthy (both fit inside the other)
  ["O","S"],  //truthy (S fits inside O)
  ["T","T"],  //truthy (T fits in its place)
  ["E","V"],  //falsey (no fit found)
  ["P","L"]   //falsey
tests.forEach((v)=>{console.log("F('"+v[0]+"','"+v[1]+"') = " + F(v[0],v[1]))});


  • saved 2 bytes thanks to kamoroso94
  • saved 2 bytes thanks to Chris M
  • saved 2 bytes by changing lookup method to .some()
  • \$\begingroup\$ Does this return true if c fits f or f fits c? It seems that you only check one case. \$\endgroup\$
    – Charlie
    Commented Dec 20, 2017 at 10:48
  • \$\begingroup\$ Code fixed to return true if f fits c \$\endgroup\$
    – Brian H.
    Commented Dec 20, 2017 at 11:26
  • \$\begingroup\$ I'm not too good explaining, if anybody wants to make it clearer feel free to suggest an edit \$\endgroup\$
    – Brian H.
    Commented Dec 20, 2017 at 11:29
  • \$\begingroup\$ You can use includes(f) instead of indexOf(f)>=0 to save 2 bytes. \$\endgroup\$
    – kamoroso94
    Commented Dec 20, 2017 at 23:58
  • \$\begingroup\$ awesome, didn't even know that was a thing :D \$\endgroup\$
    – Brian H.
    Commented Dec 21, 2017 at 9:24

Julia 0.6, 139 bytes

(a,b)->(a==b)|any(map(x->all(in.((a,b),x))|all(in.((b,a),x)),zip("OCFILMPV16",split("CGS0368 G BEPR 017BDEFHKLMNOPRTVWXZ E W R A BEL 9"))))

Try it online!

Saved some bytes by grouping the chars that fit into 'O'. But testing the reversed input uses too much code...


  • zip(☐) zips corresponding single letters from "OCFILMPV16" & a string of matching letters.
  • .in(☐) is applied elementwise, e.g. (in(a,'O'),in(b,"OCFILMPV16"))
  • all(.in(☐)) Both must be found...
  • | for either a,b or b,a...
  • any(map(☐)) for at least one element of the zipped list.

Kotlin, 147 139 bytes

fun p(s:String)=setOf(s,s.reversed()).any{it.matches(Regex("(.)\\1|F[BEPR]|I[017BDEFHKLMNOPRTVWXZ]|1[BEL]|69|CG|LE|MW|PR|VA|O[CG69038S]"))}

Try it online!

The example on Try It Online includes test cases for every positive combination and a few negative ones.

I haven't optimized the reg.ex. too much, so it might be longer than necessary

EDIT: saved a few bytes on reg.ex.


C (gcc), 211 bytes

A first attempt. Very straight-forward.

i;char*c="CFGILMPSVW013689",*x[]={"GO","BEPR","O","017BDEFHKLMNOPRTVWXZ","E","W","R","O","A","M","O","BEL","O","9O","O","6O"};h(a,b){return(i=strchr(c,a)-c)>=0&&strchr(x[i],b);}f(a,b){return a==b|h(a,b)|h(b,a);}

Try it online!


PHP, 204 bytes

-147 bytes because I cam back to remove 2 bytes only to find that my code had a few bugs and unused variables! My code is now much shorter.

<?php $a=fgets(STDIN);for($w=0;$w<2;$w++){if(strpos(explode(',','GO,BEPR,O,017BDEFHKLMNOPRTVWXZ,E,W,R,O,A,M,O,BEL,O,9O,O,6O')[strpos(CFGILMPSVW013689,$a[0])],$a[1])!==false){echo"t";break;}$a=strrev($a);}

Try it online!


Ruby, 140 bytes

->c,t{x='CFGILMPSVW013689'.chars.zip('GO BEPR O 017BDEFHKLMNOPRTVWXZ E W R O A M O BEL O 9O O 6O'.split).to_h;p x.key?(c)&&x[c].include?(t)}

Pretty much the same as the python 3 answer, but with a different execution.


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.