# Visualizing Words

Given a word consisting of lowercase letters only, do the following:

1. For each letter, get the prime factorization of its position in the alphabet.
2. For each prime factor, p, draw a diamond of side length p and stick the letter in the middle of the diamond.
3. The biggest diamond is in the middle, subsequent smaller diamonds (from biggest to smallest) alternate between going to the bottom or top.

Note: For the letter a use a side-length of 1.

Example: cat

• c: 3 = 3
• a: 1 = 1
• t: 20 = 5*2*2

The diagram:

                 .
. .
. t .
. .
.
.
. .
.           .   .
. .         .     .
.   .   .   .       .
.  c  . .a. .    t    .
.   .   .   .       .
. .         .     .
.           .   .
. .
.
.
. .
. t .
. .
.


Example: dog

• d: 4 = 2*2
• o: 15 = 5*3
• g: 7 = 7

Diagram:

                         .
. .
.           .   .
. .         .     .
.   .       .       .
.     .     .     .         .
. .   .       .   .           .
. d . .    o    . .      g      .
. .   .       .   .           .
.     .     .     .         .
.      .   .       .       .
. .      . .         .     .
. d .      .           .   .
. .       .            . .
.       . .            .
.   .
.  o  .
.   .
. .
.


-20% bonus if your program outputs to a text file called "[your-word].txt". Then input a real word (or phrase, made lowercase with no spaces) that is at least 20 letters long and no one else has chosen yet, and paste the output between a <pre> and a </pre> in your answer.

• Your examples seem to use diamonds of size p+1 dots... Dec 30, 2015 at 23:08
• @Jaykul Good question. The side length is determined by the number of spaces between the dots. Dec 30, 2015 at 23:09

# Funciton, non-competitive, 29199 bytes

I enjoyed this challenge because it highlighted the sore lack of some very useful library functions. I will include all of those functions here (and in the byte count) because I wrote them after this challenge was posted.

Full source in a single file

# Explanation

As always, get a better rendering by executing javascript:(function(){\$('pre,code').css({lineHeight:5/4});})() in your browser console.

## ① ɹ⇄ Reverse

As you may or may not know, Funciton comes with a library full of functions for lists, which are values encoded in a single humongous integer, as well as a separate library for lazy-evaluated sequences, which use lambda expressions (anonymous functions) in order to be lazy. Of course there’s also a library for string handling functions.

For this challenge, I needed a function to reverse a string, and a function to reverse a lazy-evaluated sequence. Surprisingly, I only had one for lists — exactly the one I didn’t need. So here are the reverse functions for lazy sequences (ɹ) and for strings (⇄):

              ╓───╖             ╔════╗ ┌────╖        ╓───╖
║ ɹ ║             ║ 21 ╟─┤ >> ╟──┐     ║ ⇄ ║
╙─┬─╜             ╚════╝ ╘═╤══╝  │     ╙─┬─╜      ┌──┐
┌─────┴─────┐                ┌─┴─╖   ├───────┴────────┤  │
┌─┴─╖ ┌───╖   │                │ ⇄ ║   │   ╔════╗ ┌───╖ │  │
┌─┤   ╟─┤ ɹ ╟─┐ │                ╘═╤═╝   │   ║ −1 ╟─┤ ≠ ╟─┴┐ │
│ └─┬─╜ ╘═══╝ │ │                ┌─┴─╖ ┌─┴─╖ ╚════╝ ╘═╤═╝  │ │
│   │   ┌───╖ │ │                │ ‼ ╟─┤ ? ╟──────────┤    │ │
│   └───┤ ʬ ╟─┘ │                ╘═╤═╝ ╘═╤═╝  ╔═══╗ ┌─┴─╖  │ │
│       ╘═╤═╝   │                ┌─┴─╖ ╔═══╗  ║ 0 ╟─┤ ≠ ╟──┘ │
│ ╔═══╗ ┌─┴─╖   │              ┌─┤ ʃ ╟─╢ 1 ║  ╚═╤═╝ ╘═══╝    │
└─╢ 0 ╟─┤ ? ╟───┘              │ ╘═╤═╝ ╚═══╝    │            │
╚═══╝ ╘═╤═╝                  │   └────────────┘            │
│                    └─────────────────────────────┘


The lazy-sequences one uses ʬ, which is “append an element to the end of a lazy sequence”. The string one uses ʃ (substring) and ‼ (string concatenate).

## ② Ṗ Primes

Although I could have done prime factorization by just trying to divide n by all factors in order, I decided I wanted a library function that generates prime numbers. The following function takes an integer n and implements the Sieve of Eratosthenes to generate all prime numbers up to n. It does this as a lazy sequence, so it’ll generate only as many primes as you actually evaluate.

                                       ╓───╖
║ Ṗ ║
╔═══╗ ╙─┬─╜
║ 0 ║ ┌─┴─╖
╚═╤═╝ │ ♭ ║
╔═══╗ ┌──┴─╖ ╘═╤═╝
║ 2 ╟─┤ Ṗp ╟───┘
╚═══╝ ╘══╤═╝
┌──────────────┐               │
│              ├─────────────────────────────────────────┐
│            ┌─┴─╖                                       │
│          ┌─┤ · ╟────────────────────────────┐   ╓┬───╖ │
│          │ ╘═╤═╝                            ├───╫┘Ṗp ╟─┤
│          │   │           ╔═══╗ ┌────╖     ┌─┴─╖ ╙─┬──╜ │
│          │   │           ║ 1 ╟─┤ >> ╟─────┤ · ╟───┴─┐  │
│          │   │  ┌───╖    ╚═══╝ ╘══╤═╝     ╘═╤═╝     │  │
│          │ ┌─┴──┤ ♯ ╟─────┐    ┌──┴─╖ ┌───╖ │       │  │
│          │ │    ╘═══╝ ┌─┐ │ ┌──┤ Ṗp ╟─┤ ♭ ╟─┴─┐     │  │
│          │ │          ├─┘ └─┤  ╘══╤═╝ ╘═══╝ ┌─┘     │  │
│          │ │        ╔═╧═╕ ┌─┴─╖ ┌─┴─╖     ┌─┴─╖     │  │
│          │ └────────╢   ├─┤ · ╟─┤ ? ╟─────┤ · ╟─┐   │  │
│          │ ┌───╖    ╚═╤═╛ ╘═╤═╝ ╘═╤═╝     ╘═╤═╝ │   │  │
│        ┌─┴─┤ ♭ ╟─┐ ┌──┴─╖   │   ┌─┴─╖       │   │   │  │
│        │   ╘═══╝ └─┤ Ṗp ╟───┘ ┌─┤ ? ╟───────┘   │   │  │
│ ┌───╖  │  ╔════╗   ╘══╤═╝     │ ╘═╤═╝           │   │  │
┌─┴─┤ ÷ ╟──┘  ║ −1 ║   ┌──┴─╖   ╔═╧═╗ │            ┌┴┐  │  │
│   ╘═╤═╝     ╚══╤═╝ ┌─┤ >> ╟─┐ ║ 0 ║              └┬┘  │  │
│   ┌─┴─╖ ┌────╖ │   │ ╘════╝ │ ╚═══╝               │   │  │
│   │ × ╟─┤ << ╟─┘ ┌─┴─┐    ╔═╧═╗                   │   │  │
│   ╘═╤═╝ ╘══╤═╝  ┌┴┐ ┌┴┐   ║ 1 ╟───────────────────┴─┐ │  │
└─────┘     ┌┴┐   └┬┘ └┬┘   ╚═══╝                     ├─┘  │
└┬┘    │   └──────────────────────────────┘    │
┌─┴─╖ ┌─┴──╖                                    │
│ ÷ ╟─┤ << ╟─┐                                  │
╘═╤═╝ ╘════╝ ├──────────────────────────────────┘
┌┴┐         │
└┬┘         │
╔════╗ ┌─┴──╖       │
║ −1 ╟─┤ << ╟───────┘
╚════╝ ╘════╝


The helper function, Ṗp, takes:

• A running counter which just keeps decrementing until it reaches 0.

• The sieve, which has a bit set for each number that is already known to be not-prime. Initially, the least significant bit represents the number 2, but we shift this right with each iteration.

• A number n which indicates what number is represented by the sieve’s lowest bit; this is incremented with every iteration.

At each iteration, if the sieve’s lowest bit is 0, we’ve found a prime n. We then use the formula I already described in Fill the rows, columns, and diagonals of an NxN grid to set every n-th bit in the sieve before moving to the next iteration.

## ③ Ḟ Prime factorization

                             ╓───╖
║ Ḟ ║
╙─┬─╜
┌───────┴──────┐
│ ┌───╖ ┌────╖ │
└─┤ Ṗ ╟─┤ Ḟp ╟─┘
╘═══╝ ╘═╤══╝
│
┌────────────────────────────────────────────┐
│                                     ╓┬───╖ │
┌───────┴─┐     ┌───────────────────────┐   ┌─╫┘Ḟp ╟─┘
│ ╔═══╗ ┌─┴─╖ ┌─┴─╖ ┌───┐ ┌────╖      ┌─┴─╖ │ ╙────╜
│ ║ 0 ╟─┤   ╟─┤ · ╟─┘┌┐ └─┤ Ḟp ╟──┐ ┌─┤ · ╟─┴──┐
│ ╚═══╝ └─┬─╜ ╘═╤═╝  └┤   ╘═╤══╝  ├─┘ ╘═╤═╝    │
│       ┌─┴─┐ ┌─┴─╖ ╔═╧═╕ ┌─┴─╖ ┌─┴─╖ ┌─┴──╖ ┌─┴─╖
│       │   └─┤ · ╟─╢   ├─┤ ? ╟─┤ · ╟─┤ ÷% ╟─┤ · ╟─┐
│       │     ╘═╤═╝ ╚═╤═╛ ╘═╤═╝ ╘═╤═╝ ╘═╤══╝ ╘═╤═╝ │
│       │    ┌──┴─╖   │   ┌─┴─╖ ┌─┴─╖   └──────┘   │
│       │    │ Ḟp ╟───┘ ┌─┤ ? ╟─┤ ≤ ║              │
│     ┌─┴─╖  ╘══╤═╝     │ ╘═╤═╝ ╘═╤═╝              │
└─────┤ · ╟─────┘     ╔═╧═╗ │   ╔═╧═╗              │
╘═╤═╝           ║ 0 ║     ║ 2 ║              │
│             ╚═══╝     ╚═══╝              │
└──────────────────────────────────────────┘


This is fairly straight-forward. Just iterate through the primes up to n and see which ones divide n. If one does divide n, remember to carry on with the same prime so that we return it multiple times if it divides n multiple times. This returns the empty sequence for any number less than 2.

## ④ ◇◆ Generate a diamond

This function generates a single diamond given a character and a radius. It only uses the character to place it in the center of the diamond.

                                   ┌───╖
┌─────────────────────┤ ♯ ╟───────────┬─────────┐
│ ┌───╖ ╔═══╗   ┌───┐ ╘═══╝           │         │
└─┤ ♫ ╟─╢ 0 ║   │ ┌─┴─╖               │         │
╘═╤═╝ ╚═══╝   │ │ ʭ ╟───┐           │         │
┌─┴─╖   ┌─────┘ ╘═╤═╝   │           │         │
│ ɱ ╟───┤ ┌───╖ ┌─┴─╖ ╔═══╗   ╓───╖ │         │
╘═╤═╝   └─┤ ɹ ╟─┤ ʓ ╟─╢ 1 ║ ┌─╢ ◇ ╟─┤         │
│ ╔═══╗ ╘═══╝ ╘═══╝ ╚═══╝ │ ╙───╜ │         │
│ ║ 0 ║                   │     ┌─┴─╖       │
│ ╚═╤═╝                   │     │ ♭ ║       │
╔═╧═╕ │   ╔════╗            │     ╘═╤═╝       │
┌───╢   ├─┘ ┌─╢ 21 ║          ┌─┴─╖   ┌─┴─╖     ┌─┴─┐
│   ╚═╤═╛   │ ╚════╝ ┌────────┤ · ╟───┤ · ╟─┐ ┌─┴─╖ │
│   ┌─┴─╖ ┌─┴──╖ ┌───┘        ╘═╤═╝   ╘═╤═╝ ├─┤ = ║ │
│ ┌─┤ ‼ ╟─┤ >> ║ │              │     ┌─┴─╖ │ ╘═╤═╝ │
│ │ ╘═══╝ ╘═╤══╝ │              │   ┌─┤ ? ╟─┘   │   │
│ │   ┌───╖ │ ┌──┘              │   │ ╘═╤═╝     │   │
│ └─┬─┤ ⇄ ╟─┘ │     ┌─────┐     │   │ ┌─┴─╖     │   │
│   │ ╘═══╝ ┌─┴─╖ ┌─┴─╖ ┌─┴─╖ ┌─┴─╖ └─┤ · ╟──┬──┘   │
│   └───────┤ · ╟─┤ ? ╟─┤ · ╟─┤ ‼ ║   ╘═╤═╝  │      │
│           ╘═╤═╝ ╘═╤═╝ ╘═╤═╝ ╘═╤═╝   ┌─┴─╖  │      │
│             └─────┘     └─┬───┘ ┌───┤ … ║  │      │
│               ┌─────┐     │     │   ╘═╤═╝  │      │
│            ╔══╧═╗ ┌─┴─╖ ┌─┴─╖ ┌─┴─╖ ╔═╧══╗ │      │
│            ║ 32 ║ │ … ╟─┤ ‼ ╟─┤ ‼ ║ ║ 32 ║ │      │
│            ╚════╝ ╘═╤═╝ ╘═══╝ ╘═╤═╝ ╚════╝ │      │
│                   ┌─┴─╖       ╔═╧══╗       │      │
│               ┌───┤ − ╟───┬─┐ ║ 46 ║       │      │
│             ┌─┴─╖ ╘═══╝   │ │ ╚════╝       │      │
└─────────────┤ · ╟─────────┘ └──────────────┘      │
╘═╤═╝                                 │
└───────────────────────────────────┘


This makes heavy use of lazy sequences. Here’s how it works:

• Generate the sequence of integers from 0 to r (inclusive).

• For each such integer α, generate a string consisting of (rα) spaces (…), followed by a dot, followed by α spaces — unless α = r, in which case generate one fewer space and append the letter. We now have the top-left quarter of the diamond.

• To each of these strings, append another copy of the same string, but with the characters reversed (⇄) and then the first character removed (>> 21). We now have the top half of the diamond.

• Take this sequence and append to it the same sequence, but reversed (ɹ) and with the first element removed (ʓ). We now have the whole diamond.

Now we have the strings that make up the diamond, but we need a little more information. We need to know where the vertical middle of the diamond is. Initially this is of course r, but once we’ve appended other diamonds to the top and bottom of this, we will need to keep track of the position of the “middle” diamond so that we can vertically align the other stacks of diamonds correctly. The same goes for the horizontal extent of the diamond (need that when appending diamonds to the top and bottom). I also decided to keep track of the letter; I need that because otherwise the function ⬗ (which we get to in the next section) would have to have four parameters, but Funciton allows only three.

                             ┌─────────────────┐
│  ╓───╖          │
├──╢ ◆ ╟──┐       │
│  ╙───╜  │       │
│   ┌─────┴───┐   │
┌─┴─╖ │ ┌───╖ ┌─┴─╖ │
┌─┤ · ╟─┴─┤ › ╟─┤ › ║ │
│ ╘═╤═╝   ╘═╤═╝ ╘═╤═╝ │
│ ┌─┴─╖     │   ┌─┴─╖ │
│ │ ◇ ╟─────────┤ › ╟─┘
│ ╘═╤═╝         ╘═══╝
└───┘


We use the list API (› adds elements to the front of a list) to create a structure containing [x, y, c, q], where x is the x-coordinate of the horizontal center of the diamond, y is the y-coordinate of the baseline, c is the letter and q is the lazy sequence of strings. This structure will be used to contain all of the intermediate stages from now on.

## ⑤ ⬗ Append diamonds vertically

This function takes an existing diamond stack, a radius, and a boolean indicating whether to add the new diamond to the top (true) or bottom (false).

                 ┌─────────────────────────────────────────────────┐
┌─┴─╖         ┌───────────────────────────┐ ┌───╖ ┌─┴─╖
┌───┤ · ╟─────────┘ ╔═══╗ ┌───────────────┐   ├─┤ ‹ ╟─┤ ‹ ║
│   ╘═╤═╝           ║ 1 ║ │ ╓───╖         │   │ ╘═╤═╝ ╘═╤═╝
│     │             ╚═╤═╝ └─╢ ⬗ ╟─┐       │ ┌─┴─╖ │   ┌─┴─╖
│     │ ┌───╖ ┌───╖ ┌─┴──╖  ╙─┬─╜ │       └─┤ · ╟─┘ ┌─┤ ‹ ╟─┐
│   ┌─┴─┤ + ╟─┤ ♯ ╟─┤ << ║    │   │         ╘═╤═╝   │ ╘═══╝ │
│   │   ╘═╤═╝ ╘═══╝ ╘═╤══╝    │ ┌─┴─╖         │     │       │
│   │   ┌─┴─╖         └───────┴─┤ · ╟───┐   ┌─┴─╖   │       │
│   └───┤ ? ╟─┐                 ╘═╤═╝ ┌─┴───┤ · ╟─┐ │       │
│       ╘═╤═╝ ├───────────────────┘   │     ╘═╤═╝ │ │       │
│ ┌───╖ ┌─┴─╖ │               ┌─────┐ │ ┌───╖ │   │ │       │
└─┤ › ╟─┤ › ║ │       ┌───╖ ┌─┴─╖   │ └─┤ − ╟─┘   │ │       │
╘═╤═╝ ╘═╤═╝ │     ┌─┤ ‼ ╟─┤ ‼ ║   │   ╘═╤═╝     │ │       │
│   ┌─┴─╖ │     │ ╘═╤═╝ ╘═╤═╝ ┌─┴─╖ ┌─┴─╖     │ │       │
┌───┤ · ╟─┘     │ ┌─┴─╖   ├───┤ · ╟─┤ … ║     │ │       │
┌───┐     │   ╘═╤═╝       └─┤ · ╟───┘   ╘═╤═╝ ╘═╤═╝     │ │       │
│ ┌─┴─╖ ┌─┴─╖ ┌─┴─╖         ╘═╤═╝         │  ╔══╧═╗     │ │       │
│ │ ʭ ╟─┤ ? ╟─┤ › ╟─┐ ╔═══╗ ╔═╧═╕         │  ║ 32 ║     │ │       │
│ ╘═╤═╝ ╘═╤═╝ ╘═══╝ │ ║ 0 ╟─╢   ├─────────┘  ╚════╝     │ │       │
│ ┌─┘   ┌─┴─╖       │ ╚═══╝ ╚═╤═╛                       │ │       │
│ └─┬───┤ ʭ ╟─┐   ┌─┴─╖     ┌─┴─╖                       │ │       │
│ ┌─┴─╖ ╘═══╝ ├───┤ · ╟─────┤ ɱ ║                       │ │       │
└─┤ · ╟───────┘   ╘═╤═╝     ╘═╤═╝                       │ │       │
╘═╤═╝             │       ┌─┴─╖                       │ │       │
│               └─────┬─┤ ◇ ╟───────────────────────┘ │       │
│                     │ ╘═══╝                       ┌─┴─╖     │
│                     └─────────────────────────────┤ · ╟─────┘
│                                                   ╘═╤═╝
└─────────────────────────────────────────────────────┘


This is fairly straight-forward too; use ‹ to unpack the structure; use ◇ to generate the new diamond; use ɱ (map) to add spaces to the beginning and end of each string in the new diamond so that it all has the same width; append (ʭ) the new strings onto the old (if bottom) or the old onto the new (if top); and finally use › to construct the structure containing all the new values. In particular, if we are appending to the bottom, y doesn’t change, but if we are appending to the top, y must increase by ♯(r << 1) (r is the radius of the new diamond).

## ⑥ ❖ Concatenate stacks horizontally

This is the biggest function of them all. I won’t deny that it was fairly fiddly to get this right. It takes two stacks and concatenates them horizontally while respecting the correct vertical alignment.

                           ┌──────────────────────────────────┬───────────────────────┐
│     ┌──────────────────┐       ┌─┴─╖                   ┌─┴─╖
│     │    ┌───────────┐ └───────┤ · ╟───┬───────────────┤ · ╟─────────────┐
│     │  ┌─┴─╖         │         ╘═╤═╝   │               ╘═╤═╝             │
│     │  │ ‹ ╟───┐     │         ┌─┴─╖ ┌─┴─╖               │               │
│     │  ╘═╤═╝ ┌─┴─╖   └─────────┤ · ╟─┤ · ╟─────────┐     │               │
│     │    ├─┐ │ ‹ ╟───┐         ╘═╤═╝ ╘═╤═╝         │     │               │
│     │    └─┘ ╘═╤═╝ ┌─┴─╖ ╓───╖ ┌─┴─╖   │           │     │               │
│     │          │   │ ‹ ╟─╢ ❖ ╟─┤ ‹ ║   │           │     │               │
│     │          │   ╘═╤═╝ ╙───╜ ╘═╤═╝ ┌─┴─╖ ┌─┐     │     │               │
│     │          │     │           └───┤ ‹ ║ └─┤     │     │               │
│     │          │     │               ╘═╤═╝ ┌─┴─╖   │     │               │
│     │          │     │                 └───┤ ‹ ║   │     │               │
│     │          │     └─────────────────┐   ╘═╤═╝   │     │               │
│     │          │                     ┌─┴─╖ ┌─┴─╖ ┌─┴─╖ ┌─┴─╖             │
│     │          │      ┌──────────────┤ · ╟─┤ · ╟─┤ · ╟─┤ · ╟──────┐      │
│     │          └──────┤              ╘═╤═╝ ╘═╤═╝ ╘═╤═╝ ╘═╤═╝      │      │
│   ┌─┴─╖             ┌─┴─╖            ┌─┴─╖   │     │     │        │      │
│ ┌─┤ · ╟─────────────┤ · ╟────────────┤ · ╟───┘     │     │        │      │
│ │ ╘═╤═╝             ╘═╤═╝            ╘═╤═╝         │     │        │      │
│ │   │                 │         ┌────╖ │         ┌─┴─╖   │        │      │
╔═══╗ ┌────╖        │ │   │                 │       ┌─┤ << ╟─┴─────────┤ · ╟─┐ │        │      │
║ 1 ╟─┤ << ╟────────┘ │   │                 │       │ ╘═╤══╝           ╘═╤═╝ │ │        │      │
╚═══╝ ╘═╤══╝ ╔════╗   │   │               ┌─┴─╖     │ ┌─┴─╖              │   │ │     ┌──┴──┐   │
┌─┴─╖  ║ 32 ╟─┐ │   │ ┌─────────────┤ · ╟───┐ │ │ ♯ ║              │   │ │   ┌─┴─╖ ┌─┴─╖ │
│ ♯ ║  ╚════╝ │ │   └─┤ ┌───╖       ╘═╤═╝   │ │ ╘═╤═╝ ┌───╖ ╔════╗ │   │ │ ┌─┤ ? ╟─┤ < ║ │
╘═╤═╝   ┌───╖ │ │     └─┤ − ╟─────────┴─┐   │ │   └───┤ … ╟─╢ 32 ║ │   │ │ │ ╘═╤═╝ ╘═╤═╝ │
└─────┤ … ╟─┘ │       ╘═╤═╝         ┌─┴─╖ │ └───┐   ╘═╤═╝ ╚════╝ │   │ │ │ ┌─┴─╖   ├───┘
╘═╤═╝   │ ┌───╖ ┌─┴─╖ ┌───────┤ · ╟─┴─┐ ╔═╧═╗ ┌─┴─╖ ┌──────┘   │ │ └─┤ · ╟───┘
│   ┌─┴─┤ ʭ ╟─┤ ȶ ║ │ ┌───╖ ╘═╤═╝   │ ║ 1 ║ │ ⁞ ║ │ ┌────────┘ │   ╘═╤═╝
┌─┴─╖ │   ╘═╤═╝ ╘═╤═╝ └─┤ > ╟───┴─┐   │ ╚═══╝ ╘═╤═╝ │ │   ┌──────┘     └────┐
│ ⁞ ║ │   ┌─┴─╖ ┌─┴─╖   ╘═╤═╝     │ ┌─┴─╖ ┌───╖ │   │ │ ┌─┴─╖ ┌───╖ ┌───╖ ┌─┴─╖
╘═╤═╝ └───┤ ? ╟─┤ · ╟─────┴─┐     │ │ − ╟─┤ ȶ ╟─┴─┐ │ │ │ + ╟─┤ ♯ ╟─┤ › ╟─┤ › ║
┌─┴─╖     ╘═╤═╝ ╘═╤═╝       │     │ ╘═╤═╝ ╘═╤═╝   │ │ │ ╘═╤═╝ ╘═══╝ ╘═╤═╝ ╘═╤═╝
┌────────────────────┤ · ╟───────┴───┐ └─┐     ┌─┴─╖   └───┘   ┌─┴─╖   │ │ └───┘           │     │
│                    ╘═╤═╝         ┌─┴─╖ │   ┌─┤ · ╟───────────┤ · ╟───┘ │                       │
│ ┌────────────────┐   │   ┌───────┤ · ╟─┘   │ ╘═╤═╝           ╘═╤═╝     │                       │
│ │ ╔════╗ ┌───╖ ┌─┴─╖ └───┤ ┌───╖ ╘═╤═╝     │   │               │     ┌─┴───┐                   │
│ │ ║ 32 ╟─┤ ‼ ╟─┤ · ╟───┐ └─┤ ʭ ╟───┘       │   │             ┌─┴─╖ ┌─┴─╖ ┌─┴─╖                 │
│ │ ╚════╝ ╘═╤═╝ ╘═╤═╝   │   ╘═╤═╝     ┌─────┘   │             │ ʭ ╟─┤ · ╟─┤ ? ╟─┐               │
│ │        ┌─┴─╖ ╔═╧═╕ ╔═╧═╕ ┌─┴─╖   ┌─┴─╖       │             ╘═╤═╝ ╘═╤═╝ ╘═╤═╝ │               │
│ │        │ ‼ ╟─╢   ├─╢   ├─┤ ʑ ╟───┤ ʭ ║     ┌─┴─╖             └─────┘     │   │               │
│ │        ╘═╤═╝ ╚═╤═╛ ╚═╤═╛ ╘═╤═╝   ╘═╤═╝ ┌───┤ · ╟─────────────────────────┘   │               │
│ └──────────┘     │   ╔═╧═╗   │       ├───┘   ╘═╤═╝                             │               │
│                  └───╢ 0 ║ ┌─┴─╖   ┌─┴─╖       └───────────────────────────────┘             ┌─┴─╖ ╔═══╗
│                      ╚═══╝ │ ȶ ╟───┤ · ╟─────────────────────────────────────────────────────┤ › ╟─╢ 0 ║
│                            ╘═╤═╝   ╘═╤═╝                                                     ╘═══╝ ╚═══╝
│                            ┌─┴─╖   ┌─┴─╖
│                      ┌─────┤ ? ╟─┐ │ ɕ ║
│                    ┌─┴─╖   ╘═╤═╝ │ ╘═╤═╝
│            ┌───╖ ┌─┤ < ╟───┬─┘   │   │
└────────────┤ ɕ ╟─┤ ╘═══╝ ┌─┴─╖   │   │
╘═══╝ └───────┤ · ╟───┘   │
╘═╤═╝       │
└─────────┘


Here’s how it works.

• First, for each stack, generate an infinite sequence (⁞) of strings, each of which contains spaces (…) according to that stack’s width.

• The y values of the stacks tell us which one needs to “move down” and by how much. Prepend the appropriate space sequence, truncated (ȶ) to the right length (y1y2 or y2y1 as appropriate).

• Now determine the length of each of the string sequences (ɕ), which tells us their height. Find out which one is taller.

• Append the infinite space sequences to both stacks.

• Use zip (ʑ) to put them together. For each pair of strings, concatenate them (‼) along with an extra space in between.

• Then use ȶ to truncate the result of that to the tallest height. By doing this late, we don’t have to care which one of them needs the padding.

Finally, generate the structure again. At this point, we no longer need the character in the diamonds, so we set that to 0. The x value is just summed and incremented (so that the width of the stack can still be calculated as ♯(x << 1)). The y value is set to the higher one of the two.

## ⑦ ↯ Iterate over characters in a string

This is another useful function which I will add to the library. Given a string, it gives you a lazy sequence containing each character code.

                                        ╓───╖
║ ↯ ║
╙─┬─╜
┌──────────────┴────────────────┐
│      ┌─┐          ╔═══╗ ┌───╖ │
│      └─┤     ┌────╢ 0 ╟─┤ ≠ ╟─┴─┐
┌──────┴─┐ ┌┐ ╔═╧═╕ ┌─┴─╖  ╚═══╝ ╘═╤═╝   │
│        ├─┤├─╢   ├─┤ ? ╟──────────┤     │
│        │ └┘ ╚═╤═╛ ╘═╤═╝ ╔════╗ ┌─┴─╖   │
│ ╔══════╧══╗ ┌─┴─╖   │   ║ −1 ╟─┤ ≠ ╟───┘
│ ║ 2097151 ║ │ ↯ ║       ╚════╝ ╘═══╝
│ ╚═════════╝ ╘═╤═╝
│             ┌─┴──╖ ╔════╗
└─────────────┤ >> ╟─╢ 21 ║
╘════╝ ╚════╝


anding a string with 2097151 returns the first character. >>ing it by 21 removes it. We check for both 0 and −1 for a reason explained in the esolangs page; this is not relevant to this challenge, but I want the library function to be correct.

## ⑧ ⬖ Convert character to diamond stack

This function takes a single character and returns the structure for the vertical stack representing that one character.

                                   ╔════╗
║ 96 ║  ╓───╖
╚══╤═╝  ║ ⬖ ║
┌───╖ ┌───╖ ┌─┴─╖  ╙─┬─╜
┌───┤ ɗ ╟─┤ Ḟ ╟─┤ − ║    │
│   ╘═╤═╝ ╘═══╝ ╘═╤═╝    │
│   ┌─┴─╖         ├──────┘  ┌──┐
│   │ ɹ ║         │     ┌───┤  │
│   ╘═╤═╝   ┌─────┘     │   │  │
╔═╧═╗ ┌─┴─╖ ┌─┴─╖         │  ┌┴┐ │
║ 1 ╟─┤   ╟─┤ · ╟─────┐ ╔═╧═╕└┬┘ │
╚═══╝ └─┬─╜ ╘═╤═╝   ┌─┴─╢   ├─┘ ┌┴┐
┌───────────┐ │     └─┐   │   ╚═╤═╛   └┬┘
┌─┴─╖         │ │ ┌───╖ │   └─┐ ╔═╧═╕ ┌──┴─╖ ╔═══╗
┌─────┤ · ╟───┐     │ └─┤ ◆ ╟─┘   ┌─┴─╢   ├─┤ << ╟─╢ 1 ║
┌──┴─┐   ╘═╤═╝   │     │   ╘═╤═╝     │   ╚═╤═╛ ╘════╝ ╚═╤═╝
│ ┌──┴─╖ ┌─┴─╖ ╔═╧═╕ ╔═╧═╕ ┌─┴─╖   ┌─┴─╖ ┌─┴─╖        ┌─┴─╖
│ │ >> ╟─┤ ⬗ ╟─╢   ├─╢   ├─┤ ʩ ╟───┤ · ╟─┤ ʑ ╟────────┤ ⸗ ║
│ ╘══╤═╝ ╘═╤═╝ ╚═╤═╛ ╚═╤═╛ ╘═╤═╝   ╘═╤═╝ ╘═╤═╝        ╘═╤═╝
│  ╔═╧═╗  ┌┴┐    │   ╔═╧═╗   │       └─────┘          ╔═╧═╗
│  ║ 1 ╟─┐└┬┘    └───╢ 0 ║                            ║ 0 ║
│  ╚═══╝ ├─┘         ╚═══╝                            ╚═══╝
└────────┘


This function is interesting because we needed the diamonds to be appended alternatingly to the bottom and top. Here’s how I did it:

• First, subtract 96 (so 'a' becomes 1), get prime factors (Ḟ above), use ɗ to add the element 1 if the sequence is empty, and then reverse (ɹ) the order.

• Take the first element off and call ◆ to jumpstart the stack.

• Now, use ⸗ to generate a lazy sequence that just alternates the numbers 0 and 1 indefinitely.

• Use ʑ (zip) on that and the remaining prime factors. For each prime factor, shift it left by 1 and or the 0/1 onto it. We now have a sequence that encodes the prime numbers and the top/bottom information.

• Finally, use ʩ (fold left/aggregate). The initial value is the stack we generated from the first element above. For each value ν, call ⬗ (append a new diamond) with the previous stack, the prime (ν >> 1) and whether top or bottom (ν & 1).

## ⑨ Main program

Here we do the main work.

                       ┌─────┐
│   ┌─┴─╖
│   │ ⬖ ║
╔═══╗ ╔═╧═╕ ╘═╤═╝
║ 0 ╟─╢   ├───┘
╚═╤═╝ ╚═╤═╛ ┌───╖ ┌───╖ ╔═══╗
└─┐   └───┤ ɱ ╟─┤ ↯ ╟─╢   ║
┌─────────┐ └─────┐ ╘═╤═╝ ╘═══╝ ╚═══╝
│       ┌─┴─╖     │ ┌─┴─╖
│   ┌───┤ · ╟───┐ └─┤   ╟─┐
│   │   ╘═╤═╝   │   └─┬─╜ │
│ ┌─┴─╖ ╔═╧═╕ ╔═╧═╕ ┌─┴─╖ │
│ │ ❖ ╟─╢   ├─╢   ├─┤ ʩ ╟─┘
│ ╘═╤═╝ ╚═╤═╛ ╚═╤═╛ ╘═╤═╝
└───┘   ╔═╧═╗   │   ┌─┴─╖ ┌─┐
║ 0 ╟───┘ ┌─┤ ‹ ╟─┴─┘
╚═══╝     │ ╘═══╝
┌─┴─╖ ┌─┐
┌─┤ ‹ ╟─┴─┘
│ ╘═══╝
╔════╗ ┌───╖ ┌─┴─╖ ┌─┐
║ 10 ╟─┤ ʝ ╟─┤ ‹ ╟─┴─┘
╚════╝ ╘═╤═╝ ╘═══╝
│


First, map (ɱ) over the characters in the input string (↯) and turn each into a diamond stack using ⬖. Take the first element off that, and fold (ʩ) over the rest to concatenate them all (❖). Finally, unpack the structure using ‹ to get to the sequence of strings and join them all (ʝ) using 10 (the newline) as the separator.

## Example output

Input:

crusaders


Output (took 9 seconds to compute; cannot post here because size limit).

# Matlab, 466 393 - 20% = 314.4 bytes

Golfed: (Could save some more bytes, also because of @AndreasDeak's help!)

function q(W);function z=g(l,c);[x,y]=ndgrid(abs(-l:l));z=0*y;z(~x&~y)=c;z(x+y==l)=46;end;w=W-96;n=numel(w);R=n*26;C=1;A=zeros(2*R);for k=1:n;f=sort(factor(w(k)));C=C+max(f)+1;d=-1;r=R;for F=fliplr(f);v=-F:F;while norm(A(r+v,v+C));r=r+d;end;A(r+v,v+C)=g(F,W(k));d=-d;end;C=C+max(f);end;A=A(find(sum(A,2)),find(sum(A)));f=fopen([W,'.txt'],'w');for k=1:size(A,1);fprintf(f,[A(k,:),'\n']);end;end


It should work in Octave (opensource) too, but only with a lot of warnings. Use this version if you want to try it in octave (output to console, instead of file):

function q(W);function z=g(l,c);[x,y]=ndgrid(abs(-l:l));z=0*y;z(~x&~y)=c;z(x+y==l)=46;end;w=W-96;n=numel(w);R=n*26;C=1;A=zeros(2*R);for k=1:n;f=sort(factor(w(k)));C=C+max(f)+1;d=-1;r=R;for F=fliplr(f);v=-F:F;while norm(A(r+v,v+C));r=r+d;end;A(r+v,v+C)=g(F,W(k));d=-d;end;C=C+max(f);end;A=A(find(sum(A,2)),find(sum(A)));disp([A,'']);end


Ungolfed and explained:

function q(W)
function z=g(l,c) %get a square matrix for one prime factor
[x,y]=ndgrid(abs(-l:l));
z=0*y;
z(~x&~y)=c;    %character in the middle
z(x+y==l)=46;  %dots
end;
w=W-96;                %convert word to the corresponding indices
n=numel(w);
R=n*26;                %keeps track of the main row
C=1;                   %keeps track of the current column
A=zeros(2*R);          %make a 'canvas' matrix that is way to big
for k=1:n;
f=sort(factor(w(k)));          %get all the factors of current character
C=C+max(f)+1;                  %update current column
d=-1;                          %search direction
r=R;
for F=fliplr(f);
v=-F:F;
while norm(A(r+v,v+C));    %go up or down until there is enough space to write the prime factor
r=r+d;
end;
A(r+v,v+C)=g(F,W(k));     %insert all the prime factors
d=-d;
end;
C=C+max(f);
end;
A=A(find(sum(A,2)),find(sum(A))); %truncate all the unneccessary padding
f=fopen([W,'.txt'],'w');     %write to file
for k=1:size(A,1);
fprintf(f,[A(k,:),'\n']);
end;

end


The requested word: (And here as a file: (zoom out a lot): supercalifragilisticexpialidocious.txt)

                       .                                                                                                                                                         .                                                                                                                                                                      .
. .                                                                                                                                                       . .                                                                                                                                                                    . .
.   .                                                                                                                                                     .   .                                                                                                                                                                  .   .
.     .                                                                                                                                                   .     .                                                                                                                                                                .     .
.       .                                                                                                                                                 .       .                                                                                                                                                              .       .
.         .                                                                                                                                               .         .                                                                                                                                                            .         .
.           .                                                                                                                                             .           .                                                                                                                                                          .           .
.             .                                                                                                                                           .             .                                                                                                                                                        .             .
.               .                                                                                                                                         .               .                                                                                                                                                      .               .
.                 .                                                                                                                                       .                 .               .                                                                                                                                    .                 .
.                   .                                                                                                                                     .                   .             . .                                                                                                                                  .                   .
.                     .                                          .                .                    .                               .                  .                     .           . t .                               .                     .                                                                          .                     .
.                       .              .         .               . .              . .                  . .            .                . .                .                       .           . .                               . .    .              . .                                                         .              .                       .
.                         .            . .       . .             . r .            . l .                . r .          . .              . l .              .                         .           .                               . x .  . .            . l .                                                       . .            .                         .
.                           .          .   .     . p .     .       . .              . .                  . .          .   .              . .              .                           .          .                        .       . .  . p .            . .                   .                        .          .   .          .                           .
.                             .        .     .     . .     . .       .                .                    .          .     .              .              .                             .        . .                      . .       .    . .              .                   . .                      . .        .     .        .                             .
.                               .      .       .     .     .   .      .      .         .      .      .      .         .       .      .      .      .      .                               .      .   .      .      .      .   .      .     .     .         .      .           .   .      .      .      .   .      .       .      .                               .
.                                 .    .         .    .    .     .    . .    . .       . .    . .    . .    . .       .         .    . .    . .    . .    .                                 .    .     .    . .    . .    .     .    . .    .    . .       . .    . .    .    .     .    . .    . .    .     .    .         .    .                                 .
.                                   .  .           .  . .  .       .  .   .  .   .  .  .   .  .   .  .   .  .   .  .  .           .  .   .  .   .  .   .  .                                   .  .       .  .   .  .   .  .       .  .   .  . .  .   .  .  .   .  .   .  . .  .       .  .   .  .   .  .       .  .           .  .                                   .
.                  s                  ..      u      .. p ..    e    ..  r  ..  c  ..a..  l  ..  i  ..  f  ..  r  ..a..      g      ..  i  ..  l  ..  i  ..                  s                  ..    t    ..  i  ..  c  ..    e    ..  x  .. p ..  i  ..a..  l  ..  i  .. d ..    o    ..  c  ..  i  ..    o    ..      u      ..                  s                  .
.                                   .  .           .  . .  .       .  .   .  .   .  .  .   .  .   .  .   .  .   .  .  .           .  .   .  .   .  .   .  .                                   .  .       .  .   .  .   .  .       .  .   .  . .  .   .  .  .   .  .   .  . .  .       .  .   .  .   .  .       .  .           .  .                                   .
.                                 .    .         .    .    .     .    . .    . .       . .    . .    . .    . .       .         .    . .    . .    . .    .                                 .    .     .    . .    . .    .     .    . .    .    . .       . .    . .    .    .     .    . .    . .    .     .    .         .    .                                 .
.                               .      .       .     .     .   .      .      .         .      .      .      .         .       .      .      .      .      .                               .      .   .      .      .      .   .      .     .     .         .      .     .     .   .      .      .      .   .      .       .      .                               .
.                             .        .     .     . .     . .       .                .      .      .      .          .     .       .      .      .       .                             .        . .       .              . .       .    . .    .         .      .    . .     . .              .       . .        .     .        .                             .
.                           .          .   .     . p .     .       . .              . .    . .    . .    . .          .   .       . .    . .    . .       .                           .          .       . .              .       . .  . p .  . .       . .    . .  . d .     .              . .       .          .   .          .                           .
.                         .            . .       . .             .   .            . l .  .   .  . f .  .   .          . .       .   .  . l .  .   .       .                         .           .      .   .                    . x .  . .  .   .     . l .  .   .  . .      .             .   .      .           . .            .                         .
.                       .              .         .             .  r  .            . .  .  i  .  . .  .  r  .          .       .  i  .  . .  .  i  .       .                       .           . .    .  i  .                    . .    .  .  i  .     . .  .  i  .  .      . .           .  i  .    . .           .              .                       .
.                     .               .         .              .   .              .    .   .    .    .   .                    .   .    .    .   .         .                     .           . t .    .   .                      .     .   .   .       .    .   .         .   .           .   .    .   .          .               .                     .
.                   .               . .       . .              . .                     . .           . .                      . .           . .           .                   .             . .      . .                       .    . .   . .              . .         .  o  .           . .    .  o  .        . .               .                   .
.                 .               .   .     . p .              .                       .             .                        .             .             .                 .               .        .                       . .  . p .   .                .           .   .             .      .   .        .   .               .                 .
.               .               .  u  .     . .                                                                                                           .               .                                                . x .  . .                                  . .                      . .        .  u  .               .               .
.             .                 .   .       .                                                                                                             .             .                                                  . .    .                                    .                        .          .   .                 .             .
.           .                   . .                                                                                                                       .           .                                                    .                                                                               . .                   .           .
.         .                     .                                                                                                                         .         .                                                                                                                                      .                     .         .
.       .                                                                                                                                                 .       .                                                                                                                                                              .       .
.     .                                                                                                                                                   .     .                                                                                                                                                                .     .
.   .                                                                                                                                                     .   .                                                                                                                                                                  .   .
. .                                                                                                                                                       . .                                                                                                                                                                    . .
.                                                                                                                                                         .                                                                                                                                                                      .

• Wouldn't A=A(find(sum(A,2)),find(sum(A))); suffice for removing the padding in one step? Jan 3, 2016 at 0:30
• I actually got perfect results when I pasted the output text between two <pre> tags. Why don't you try that! Jan 3, 2016 at 1:54
• Are you sure you need sort(factor())? MATLAB's factor seems to be sorted already. And you might define a variable for max(f), since you seem to be using that same quantity twice. Jan 3, 2016 at 13:20
• @geokavel I believe you're looking at it the other way around:) From [the bible](en.wikipedia.org): MATLAB -> "Initial release - 1984", GNU Octave -> Initial release - 1988". How is it that Mathworks allow their commercial product to be copied up to such minor details? Or if you just meant why it's still profitable: I'm sure the available MATLAB toolboxes and features well overwhelm Octave (although the syntax of Octave is sometimes richer!). Not to mention speed (I think). Jan 5, 2016 at 10:27
• @geokavel It is as AndrasDeak said: Octave is a clone of Matlab, but unfortunately not a perfect one, as the developers also tried to improve the language. Here a slightly modified version that also works in the online interpreter: goo.gl/Jk7mpV Jan 5, 2016 at 10:46

# 05AB1E, 84 bytes

εUAyk>ÐV≠iÒDg;Y18Q-._}εXs<ú'.ìηy>j.º».∊}».c.B€SøJ•ΓXÇôнÒ¤Å¨ Â<’|Ë•24вYèú»}».B€SøJćÛ»


Try it online.

No 20% bonus, although I might try that later on. 05AB1E isn't able to write files to disk itself, but it can evaluate Python code, so I might be able to write a file to disk using Python code. It definitely won't save enough bytes to be worth the 20% bonus, though.

Explanation:

ε                     # Map over each letter of the (implicit) input-string
U                    #  Pop and store the letter in variable X
k                  #  Get the 0-based index
y                   #  of the letter
A                    #  in the lowercase alphabet
>                 #  And increase it by 1 to make it a 1-based index
Ð                #  Triplicate it
V               #  Pop and store one in variable Y
≠i           } #  If it's NOT equal to 1 (so not 'a'):
Ò            #   Get all prime factors including duplicates
Dg          #   Get the amount of prime factors (without popping by duplicating first)
;         #   Halve that amount
Y18Q     #   Check if Y is 18 (1 if truthy; 0 if falsey)
-    #   Subtract that from halve the amount of prime factors
._  #   And rotate the list of prime factors that many times towards the left
#   (which only uses the integer portion and ignores the decimal values)
#   (the Dg;Y18Q-._ is to put the prime factors in the correct order,
#    according to the third rule of the challenge description)
ε                    #  Then map over each prime factor y:
X                   #   Push the letter X
s                  #   Swap so the prime factor is at the top again
<                 #   Decrease it by 1
'.ì            '#   And prepend a "."
η            #   Then take the prefixes of this string
y>          #   Push the prime factor, and increase it by 1
j         #   Make all prefixes of equal length by padding with spaces,
#   up to a length of the prime factor + 1
#   (we now have the top-left portion of a diamond)
.º                  #   Mirror each line horizontally with overlap
»                 #   Join them by newlines
.∊               #   And also mirror everything vertically with overlap
#   (we now have the entire diamond)
}                    #  After the inner map:
»                   #  join all diamonds of the current letter with newline delimiter
.B               #  Split each line on newlines as box (also adds trailing spaces)
€S             #  Convert each line to a list of characters
ø            #  Zip/transpose; swapping rows/columns
J           #  Join all transposed inner character-lists to a string again
•ΓXÇôнÒ¤Å¨ Â<’|Ë•   #  Push compressed integer 384055587443514148837383584634491347
24в                #  Convert it to base-24 as list:
#   [11,23,22,21,22,19,21,17,17,21,19,13,16,11,17,19,17,7,16,5,14,17,13,1,16,19]
Yè              #  Index value Y into this list
»            #  And join them with a newline delimiter again
}                     # After the outer map:
»                    # join all diamond-towers together with newline delimiter
.B                  # Split each line on newlines as box (also adds trailing spaces)
€S                # Convert each line to a list of characters
ø               # Zip/transpose; swapping rows/columns
J              # Join all transposed inner character-lists to a string again
ć             # Extract head; pop and push remainder-list of lines and the first line
# (this first line is always a line consisting of only spaces,
#  since the padding list was incremented by 1 for each letter)
Û            # Trim all leading lines consisting of only spaces
»           # And join all remaining lines with newline delimiter
# (after which it is output implicitly as result)


See this 05AB1E tip of mine (section How to compress large integers? and How to compress integer lists?) to understand why •ΓXÇôнÒ¤Å¨ Â<’|Ë• is 384055587443514148837383584634491347 and •ΓXÇôнÒ¤Å¨ Â<’|Ë•24в is [11,23,22,21,22,19,21,17,17,21,19,13,16,11,17,19,17,7,16,5,14,17,13,1,16,19].