In this pixelated font of uppercase letters of the alphabet, all the characters are 5 units wide and 5 tall.
███ ████ ███ ████ █████ █████ ████ █ █ █████ █ █ █ █ █ █
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ ██ ██
█████ ████ █ █ █ ████ ████ █ ██ █████ █ █ ███ █ █ █ █
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ ████ ███ ████ █████ █ ████ █ █ █████ ███ █ █ █████ █ █
█ █ ███ ████ ███ ████ ████ █████ █ █ █ █ █ █ █ █ █ █ █████
██ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ █ █ █ ████ █ █ ████ ███ █ █ █ █ █ █ █ █ █ █ █
█ ██ █ █ █ █ ██ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ ███ █ ████ █ █ ████ █ ███ █ █ █ █ █ █ █████
There is also 1 unit of space between letters and between lines, as can be seen. So each letter can take up to 6×6 units of space.
Suppose that instead of using the full block character (█
) to directly form the shapes of the letters, we wanted to use other letters in the same font. This involves increasing the dimensions of the text 6-fold so that letters made of full-blocks can be used as full-block replacements in the larger text.
If that didn't make sense hopefully this example will. Here is an A made of B's using the pixelated font:
████ ████ ████
█ █ █ █ █ █
████ ████ ████
█ █ █ █ █ █
████ ████ ████
████ ████
█ █ █ █
████ ████
█ █ █ █
████ ████
████ ████ ████ ████ ████
█ █ █ █ █ █ █ █ █ █
████ ████ ████ ████ ████
█ █ █ █ █ █ █ █ █ █
████ ████ ████ ████ ████
████ ████
█ █ █ █
████ ████
█ █ █ █
████ ████
████ ████
█ █ █ █
████ ████
█ █ █ █
████ ████
The B's are made of full blocks and the A is made of B's. Notice that the B's still have one unit between them horizontally and vertically.
We can extend this idea by using words instead of just letters. Here is "WATER" made of "FIRE":
█████ █████ ████ █████ █████ █████ ████ █████ █████ █████ ████ █████ █████ █████ ████ █████ █████ █████ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
████ █ ████ ████ ████ █ ████ ████ ████ █ ████ ████ ████ █ ████ ████ ████ █ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █████ █ █ █████ █ █████ █ █ █████ █ █████ █ █ █████ █ █████ █ █ █████ █ █████ █ █
█████ █████ ████ █████ █████ █████ ████ █████
█ █ █ █ █ █ █ █ █ █
████ █ ████ ████ ████ █ ████ ████
█ █ █ █ █ █ █ █ █ █
█ █████ █ █ █████ █ █████ █ █ █████
█████ █████ ████ █████ █████ █████ ████ █████ █████ █████ ████ █████ █████ █████ ████ █████ █████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
████ █ ████ ████ ████ █ ████ ████ ████ █ ████ ████ ████ █ ████ ████ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █████ █ █ █████ █ █████ █ █ █████ █ █████ █ █ █████ █ █████ █ █ █████ █
█████ █████ ████ █████ █████ █████ ████ █████ █████
█ █ █ █ █ █ █ █ █ █ █
████ █ ████ ████ ████ █ ████ ████ ████
█ █ █ █ █ █ █ █ █ █ █
█ █████ █ █ █████ █ █████ █ █ █████ █
█████ █████ ████ █████ █████ █████ ████ █████ █████ █████ ████ █████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █
████ █ ████ ████ ████ █ ████ ████ ████ █ ████ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █████ █ █ █████ █ █████ █ █ █████ █ █████ █ █ █████
Notice how "FIRE" appears repeatedly on each line, and always in order, no matter how much space is between the letters. Three of the rightmost instances of "FIRE" were cut off early because of how "WATER"'s letters are shaped.
This idea can be expanded even further, by using these words made of words to make words made of words made of words, or even words made of words made of words made of words. There is no limit theoretically.
Another example would put this post over the 30k character limit, but you can see what is meant by "words made of words made of words" by running this nifty Stack Snippet. Just leave the parameters at their defaults and press "Go!". You should see the word "DOG" made of the word "CAT" made of the word "MOUSE".
alphabet = {A:[[0,1,1,1,0,0],[1,0,0,0,1,0],[1,1,1,1,1,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[0,0,0,0,0,0]],C:[[0,1,1,1,0,0],[1,0,0,0,1,0],[1,0,0,0,0,0],[1,0,0,0,1,0],[0,1,1,1,0,0],[0,0,0,0,0,0]],B:[[1,1,1,1,0,0],[1,0,0,0,1,0],[1,1,1,1,0,0],[1,0,0,0,1,0],[1,1,1,1,0,0],[0,0,0,0,0,0]],E:[[1,1,1,1,1,0],[1,0,0,0,0,0],[1,1,1,1,0,0],[1,0,0,0,0,0],[1,1,1,1,1,0],[0,0,0,0,0,0]],D:[[1,1,1,1,0,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[1,1,1,1,0,0],[0,0,0,0,0,0]],G:[[0,1,1,1,1,0],[1,0,0,0,0,0],[1,0,0,1,1,0],[1,0,0,0,1,0],[0,1,1,1,1,0],[0,0,0,0,0,0]],F:[[1,1,1,1,1,0],[1,0,0,0,0,0],[1,1,1,1,0,0],[1,0,0,0,0,0],[1,0,0,0,0,0],[0,0,0,0,0,0]],I:[[1,1,1,1,1,0],[0,0,1,0,0,0],[0,0,1,0,0,0],[0,0,1,0,0,0],[1,1,1,1,1,0],[0,0,0,0,0,0]],H:[[1,0,0,0,1,0],[1,0,0,0,1,0],[1,1,1,1,1,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[0,0,0,0,0,0]],K:[[1,0,0,0,1,0],[1,0,0,1,0,0],[1,1,1,0,0,0],[1,0,0,1,0,0],[1,0,0,0,1,0],[0,0,0,0,0,0]],J:[[0,0,0,0,1,0],[0,0,0,0,1,0],[0,0,0,0,1,0],[1,0,0,0,1,0],[0,1,1,1,0,0],[0,0,0,0,0,0]],M:[[1,0,0,0,1,0],[1,1,0,1,1,0],[1,0,1,0,1,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[0,0,0,0,0,0]],L:[[1,0,0,0,0,0],[1,0,0,0,0,0],[1,0,0,0,0,0],[1,0,0,0,0,0],[1,1,1,1,1,0],[0,0,0,0,0,0]],O:[[0,1,1,1,0,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[0,1,1,1,0,0],[0,0,0,0,0,0]],N:[[1,0,0,0,1,0],[1,1,0,0,1,0],[1,0,1,0,1,0],[1,0,0,1,1,0],[1,0,0,0,1,0],[0,0,0,0,0,0]],Q:[[0,1,1,1,0,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[1,0,0,1,1,0],[0,1,1,1,1,0],[0,0,0,0,0,0]],P:[[1,1,1,1,0,0],[1,0,0,0,1,0],[1,1,1,1,0,0],[1,0,0,0,0,0],[1,0,0,0,0,0],[0,0,0,0,0,0]],S:[[0,1,1,1,1,0],[1,0,0,0,0,0],[0,1,1,1,0,0],[0,0,0,0,1,0],[1,1,1,1,0,0],[0,0,0,0,0,0]],R:[[1,1,1,1,0,0],[1,0,0,0,1,0],[1,1,1,1,0,0],[1,0,0,1,0,0],[1,0,0,0,1,0],[0,0,0,0,0,0]],U:[[1,0,0,0,1,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[1,0,0,0,1,0],[0,1,1,1,0,0],[0,0,0,0,0,0]],T:[[1,1,1,1,1,0],[0,0,1,0,0,0],[0,0,1,0,0,0],[0,0,1,0,0,0],[0,0,1,0,0,0],[0,0,0,0,0,0]],W:[[1,0,0,0,1,0],[1,0,0,0,1,0],[1,0,1,0,1,0],[1,0,1,0,1,0],[0,1,0,1,0,0],[0,0,0,0,0,0]],V:[[1,0,0,0,1,0],[1,0,0,0,1,0],[0,1,0,1,0,0],[0,1,0,1,0,0],[0,0,1,0,0,0],[0,0,0,0,0,0]],Y:[[1,0,0,0,1,0],[0,1,0,1,0,0],[0,0,1,0,0,0],[0,0,1,0,0,0],[0,0,1,0,0,0],[0,0,0,0,0,0]],X:[[1,0,0,0,1,0],[0,1,0,1,0,0],[0,0,1,0,0,0],[0,1,0,1,0,0],[1,0,0,0,1,0],[0,0,0,0,0,0]],Z:[[1,1,1,1,1,0],[0,0,0,1,0,0],[0,0,1,0,0,0],[0,1,0,0,0,0],[1,1,1,1,1,0],[0,0,0,0,0,0]]}
empty = ['\xA0', '.']
full = ['\u2588', 'X']
w = 6
h = 6
function makeGrid(height, width) {
var grid = new Array(height)
for(var y = 0; y < height; y++) {
grid[y] = new Array(width)
}
return grid
}
function unfoldGrid(grid) {
var newGrid = makeGrid(h * grid.length, w * grid[0].length)
for (var y = 0; y < newGrid.length; y++) {
for (var x = 0; x < newGrid[0].length; x++) {
var yf = Math.floor(y / h), xf = Math.floor(x / w)
if (grid[yf][xf] != 0) {
newGrid[y][x] = grid[yf][xf][y % h][x % w]
} else {
newGrid[y][x] = 0
}
}
}
return newGrid
}
function makeWords(words, empty, full) {
var grid = makeGrid(1, words[0].length)
for (var i = 0; i < words[0].length; i++) {
grid[0][i] = alphabet[words[0][i]]
}
console.log(grid.length)
console.log(grid[0].length)
grid = unfoldGrid(grid)
console.log(grid.length)
console.log(grid[0].length)
for(var i = 1; i < words.length; i++) {
for (var y = 0; y < grid.length; y++) {
var offset = 0
for (var x = 0; x < grid[0].length; x++) {
if (grid[y][x]) {
grid[y][x] = alphabet[words[i][offset++ % words[i].length]]
}
}
}
grid = unfoldGrid(grid)
}
var output = ''
var height = Math.pow(h, words.length) - (Math.pow(h, words.length) - 1) / (h - 1)
var width = words[0].length * Math.pow(w, words.length) - (Math.pow(w, words.length) - 1) / (w - 1)
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
output += grid[y][x] ? full : empty
}
if (y + 1 != height) {
output += '\r\n'
}
}
return output
}
function go() {
plain = document.getElementById('plain').checked ? 1 : 0
document.getElementById('canvas').value = makeWords(document.getElementById('words').value.split(' '), empty[plain], full[plain])
resize()
}
function resize() {
document.getElementById('canvas').style.fontSize = document.getElementById('size').value
}
function zoom(magnify) {
canvas = document.getElementById('canvas')
match = canvas.style.fontSize.match(/^(\d+(?:\.\d+)?)(.*)$/)
if (match !== null) {
number = parseFloat(match[1])
unit = match[2]
canvas.style.fontSize = document.getElementById('size').value = (number + (magnify ? 0.1 : -0.1)) + unit
}
}
#canvas {
font-family: Consolas, "Courier New", sans-serif;
white-space: nowrap; overflow: auto;
width: 6in;
height: 3in;
}
<p>Words: <input type='text' id='words' value='DOG CAT MOUSE'> <button type='button' onclick='go()'>Go!</button> Plain ASCII <input type='checkbox' id='plain'></p>
<p>Font Size: <input type='text' id='size' value='0.4mm'> <button type='button' onclick='resize()'>Resize</button> <button type='button' onclick='zoom(1)'>+</button> <button type='button' onclick='zoom(0)'>-</button> (use any unit: in, cm, mm, em, pt, px)</p>
<textarea id='canvas'></textarea>
Typing any space separated list of words containing only capital letters in the textbox will produce the first word made of the second word made of the third, made of the fourth, made of ... etc.
WARNING: Entering more than 4 or even 3 words will produce A LOT of text and take a LONG time. It may crash your browser/computer/car.
Challenge
The goal of this challenge is to mirror what the Stack Snippet does in the fewest number of characters.
You must write a program that takes in a space separated string of words containing only capital letters, and outputs the first word "made of" the second "made of" the third and so on, using the pixelated font given above.
The "Plain ASCII" checkbox and the font size features of the snippet do not need to be supported in your program. Mirroring the transformation from lists of words to words made of words is the main point and only requirement.
Details
Input should come from stdin, the command line, or you may just write a function that takes a string.
You may assume the input is always valid, i.e. a string of words made of capital letters, separated by exactly one space, with no leading or trailing spaces.
Output should go to stdout (or similar alternative) or to a file with the name of your choice.
The output should consist entirely of empty-space characters, full-space characters, and newlines.
- The empty/full-space characters should either be space and full block (
,
█
) respectively, or period and X (.
,X
) respectively.
- The empty/full-space characters should either be space and full block (
The output should not contain any leading columns containing only empty-space characters, though any combination of trailing empty-space characters on any lines is allowed.
So this is allowed:
X...X.XXXXX.. X...X.X X.X.X.XXXX.... X.X.X.X.. .X.X..XXXXX..
But this isn't:
.X...X.XXXXX.. .X...X.X .X.X.X.XXXX.... .X.X.X.X.. ..X.X..XXXXX..
There should be no leading or trailing rows containing only empty-space characters. A single trailing newline is optionally allowed.
Here is a more string-friendly version of the font:
.XXX.
X...X
XXXXX
X...X
X...X
XXXX.
X...X
XXXX.
X...X
XXXX.
.XXX.
X...X
X....
X...X
.XXX.
XXXX.
X...X
X...X
X...X
XXXX.
XXXXX
X....
XXXX.
X....
XXXXX
XXXXX
X....
XXXX.
X....
X....
.XXXX
X....
X..XX
X...X
.XXXX
X...X
X...X
XXXXX
X...X
X...X
XXXXX
..X..
..X..
..X..
XXXXX
....X
....X
....X
X...X
.XXX.
X...X
X..X.
XXX..
X..X.
X...X
X....
X....
X....
X....
XXXXX
X...X
XX.XX
X.X.X
X...X
X...X
X...X
XX..X
X.X.X
X..XX
X...X
.XXX.
X...X
X...X
X...X
.XXX.
XXXX.
X...X
XXXX.
X....
X....
.XXX.
X...X
X...X
X..XX
.XXXX
XXXX.
X...X
XXXX.
X..X.
X...X
.XXXX
X....
.XXX.
....X
XXXX.
XXXXX
..X..
..X..
..X..
..X..
X...X
X...X
X...X
X...X
.XXX.
X...X
X...X
.X.X.
.X.X.
..X..
X...X
X...X
X.X.X
X.X.X
.X.X.
X...X
.X.X.
..X..
.X.X.
X...X
X...X
.X.X.
..X..
..X..
..X..
XXXXX
...X.
..X..
.X...
XXXXX
Scoring
This is code-golf so the shortest submission in bytes wins. Any instance of a full block (█
) can be counted as 1 byte instead of 3 so submissions that use X
don't have an advantage.
javascript:
into the URL bar and pasting it) to make the ASCII art here much, much easier to read:$('#question pre').css('line-height',1)
. Result: i.stack.imgur.com/XmB8C.png \$\endgroup\$$('#question pre, .answer pre').css('line-height',1)
\$\endgroup\$