Code Golf: Letter-Ception

JavaScript (ES8), 281 bytes

Takes input as (letter)(N). Returns a string.

c=>n=>(g=y=>y--?''.padEnd(w).replace(/./g,(_,x)=>(h=d=>~~(d/=5)?(P=parseInt)('hhvhefhfhfu111ufhhhfv1f1v11f1vehp1ehhvhhv444vehgggh979hv1111hhlrhhpljhehhhe11fhfuphheh9fhffge1u4444vehhhh4ahhhalhhhha4ah444ahv248v'[y/d%5+5*P(c,36)-50|0],36)>>x/d%5&1?h(d):' ':c)(w))+`
`+g(y):'')(w=5**n)

Try it online!

How?

Font encoding

The letters are \$5\times5\$, which means that each row can be encoded as a 5-digit binary value, i.e. \$0\$ to \$31\$ in decimal. These values can conveniently be stored as a single digit in Base36.

The pattern that is stored is mirrored both horizontally and vertically.

Example for 'F':

#####     ....#     00001      1     '1'
#....     ....#     00001      1     '1'
####. --> .#### --> 01111 --> 15 --> 'f' --> '11f1v'
#....     ....#     00001      1     '1'
#....     #####     11111     31     'v'

The whole font is stored as a single string of \$26\times5 = 130\$ characters.

To test the 'pixel' at \$(x,y)\$ for the \$n^{\text{th}}\$ letter, we do:

parseInt('hhvhefhfh...'[y + 5 * n], 36) >> x & 1

Main algorithm

Given \$n\$, we define \$w=5^n\$, which is the width of the final output.

For \$0\le x<w\$ and \$0\le y<w\$, we want to know if the output pixel at \$(x,y)\$ is set or not. We use the recursive function \$h\$, which tests the letter pixel located at:

$$\left(\left\lfloor\frac{x}{5^k}\right\rfloor\bmod 5,\left\lfloor\frac{y}{5^k}\right\rfloor\bmod 5\right)$$

for all \$k\$ in \$[0 \dots n-1]\$.

The function returns a space as soon as a blank pixel is detected at some depth, or the character corresponding to the input letter if all iterations are successful.


R, 348 bytes

function(K,N){if(N)for(i in 1:N)T=T%x%matrix(c(15269425,32045630,16269839,32032318,33061407,33061392,15224366,18415153,32641183,1082926,18444881,17318431,18732593,18667121,15255086,32045584,15255151,32045649,16267326,32641156,18400814,18400580,18400938,18157905,18157700,32575775)[utf8ToInt(K)-64]%/%2^(24:0)%%2,5,5)
write(c(" ",K)[T+1],1,5^N,,"")}

Try it online!

Uses an encoding nearly identical to Ouros'; however, it does not reverse the bits, instead opting to use them directly.

It then creates a 5x5 matrix of bits and builds the Kronecker Power matrix to generate the necessary pattern, writing the results to stdout.


Clean, 436 372 bytes

Significantly shorter with new IO format.

import StdEnv,StdLib
t=transpose
f=flatten
$0c=[[c]]
$n c=f[t(f[t($(n-1)if(isOdd({#18415150,16301615,31491134,16303663,32554047,1096767,15262766,18415153,32641183,15254032,18128177,32539681,18405233,18667121,15255086,1097263,32294446,18136623,16267326,4329631,15255089,4539953,11191857,18157905,4329809,32575775}.[toInt(max'A'c)-65]>>p))c' ')\\p<-[i..i+4]])\\i<-[0,5..20]]

Try it online!

Compresses the letter patterns into the bits of integer literals to save ~700 bytes. For example, A:

  1. Flatten [[' AAA '],['A A'],['AAAAA'],['A A'],['A A']]
  2. Reverse [' AAA A AAAAAAA AA A']
  3. Turn ['A AA AAAAAAA A AAA '] into binary ('A' = 1, ' ' = 0)
  4. Turn 0b1000110001111111000101110 into decimal
  5. Get 18415150