APLPresent

Author:   pdw
Category: Christmas Challenge
System:   IBM 5110
Language: APL
Len source code: 40 characters
Len exe file:    N/A
Len code only:   N/A
Instructions:
 Run on the IBM 5110 emulator at
 https://norbertkehrer.github.io/ibm_5110/emu5110.html
 (Or on any other APL implementation.)

 The 5110's screen only has 16 lines, so the screenshot uses a modified
 program that draws a smaller image.
Description:

 The full program is:

     ⍉(11⌽19↑'\O/'),' !-+'[1+A∘.+2×A←1=9|⍳19]

 Step by step:

       ⍝ The integers 1 to 19.
       ⍳19
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

       ⍝ The remainder after division by 9.
       9|⍳19
 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1

       ⍝ Find the ones.
       1=9|⍳19
 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1

       ⍝ And call this vector A.
       A←1=9|⍳19

       ⍝ Make a table of the sum of A and A doubled.
       A∘.+2×A
 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 2 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2
 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3

       ⍝ Looking good. Let's call this B in this explanation.
       B←A∘.+2×A

       ⍝ Map this to characters.
       ' -!+'[1+B]
 +--------+--------+
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 +--------+--------+
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 +--------+--------+

       ⍝ Take the string '\O/', enlarge it to the required length, then
       ⍝ rotate it so that the \O/ is in the right position.
       11⌽19↑'\O/'
         \O/

       ⍝ Append that to our previous result
       (11⌽19↑'\O/'),' -!+'[1+B]
  +--------+--------+
  !        !        !
  !        !        !
  !        !        !
  !        !        !
  !        !        !
  !        !        !
  !        !        !
 \!        !        !
 O+--------+--------+
 /!        !        !
  !        !        !
  !        !        !
  !        !        !
  !        !        !
  !        !        !
  !        !        !
  !        !        !
  +--------+--------+

       ⍝ Oops, that's the wrong axis. We could fix it like this.
       (11⌽19↑'\O/'),[1]' -!+'[1+B]
         \O/
 +--------+--------+
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 +--------+--------+
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 +--------+--------+

       ⍝ But it's actually shorter to use the transpose operator.
       ⍉(11⌽19↑'\O/'),' !-+'[1+B]
         \O/
 +--------+--------+
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 +--------+--------+
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 !        !        !
 +--------+--------+