Does a letter fit inside the other?

Do you remember 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.

Rules

• 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.

• – user202729 Dec 20 '17 at 8:23
• 1 doesn't fit in F? – user202729 Dec 20 '17 at 8:44
• @user202729 no, because you need to flip the 1 to fit it in the F but that's not allowed in my mat. :-) – Charlie Dec 20 '17 at 8:48
• Illustration ASCII-art graph (of course fit-in is transitive) – user202729 Dec 20 '17 at 8:58
• @Ο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). – Charlie Dec 20 '17 at 12:04

Python 2, 135130 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

O.
(.)\1|1[BEL]|69|AV|CG|BF|EF|EL|FP|FR|[017BDEFH]I|I[KLMNOPRTVWXZ]|MW|PR|OS|[03689CG]O

^$ Try it online! Edit: Saved 1 byte thanks to @ovs. • Does this work for 92 bytes? – ovs Dec 20 '17 at 17:56 Clean, 276 226 bytes Vaguely golfed-ish. Will polish tomorrow. import StdEnv i a b=isMember b a t=True f'C'b=i['GO']b f'F'b=i['BEPR']b f'O'b=i['GS03689']b f'I'b=i['017BDEFHKLMNOPRTVWXZ']b f'L''E'=t f'P''R'=t f'V''A'=t f'M''W'=t f'1'b=i['BEL']b f'6''9'=t f _ _=False ?a b=a==b||f a b||f b a  Try it online! Haskell, 149 145 bytes []!_=0>1 (a:b:c)!t=(a,b)==t||(b,a)==t||c!t f x y=x==y||"0I0O1B1E1I1L3O696O7I8O9OAVBFBICGCODIEFEIELFIFPFRGOHIIKILIMINIOIPIRITIVIWIXIZMWOSPR"!(x,y)  Try it online! Javascript 155 153 151 149 bytes I think this works on all cases, 1/0 for true/false. (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)  Explanation: F=( c, // input 1 f, // input 2 q=1 // variable used to execute F twice )=>( "CGO,FBEPR,GO,I017BDEFHKLMNOPRTVWXZ,LE,MW,PR,SO,VA,WM,0O,1BEL,3O,69O,8O,96O".split, // 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]))}); Changelog: • saved 2 bytes thanks to kamoroso94 • saved 2 bytes thanks to Chris M • saved 2 bytes by changing lookup method to .some() • Does this return true if c fits f or f fits c? It seems that you only check one case. – Charlie Dec 20 '17 at 10:48 • Code fixed to return true if f fits c – Brian H. Dec 20 '17 at 11:26 • I'm not too good explaining, if anybody wants to make it clearer feel free to suggest an edit – Brian H. Dec 20 '17 at 11:29 • You can use includes(f) instead of indexOf(f)>=0 to save 2 bytes. – kamoroso94 Dec 20 '17 at 23:58 • awesome, didn't even know that was a thing :D – Brian H. Dec 21 '17 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... Explanation: • 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.