Funciton, 4322 − 50% = 2161
Not really trying to golf here. Going more for the beauty angle. I think the main program looks really neat, a perfect rectangular box tucked away on the right.
As always, you can get a better rendering by executing $('pre').css('line-height',1)
in your browser console.
┌─────────────────────────┐
┌─┴─╖ ┌─┴─╖
┌────────┤ · ╟─────────────────────┤ · ╟─────────────┐ ╔═════════╗ ╔════╗ ╔════╗
│ ╘═╤═╝ ╔═════════╗ ╘═╤═╝ ╓───╖ │ ║ 1257283 ║ ┌─╢ 40 ║ ║ 25 ║
│ │ ║ 2097151 ║ ├───╢ ʫ ╟───┐ │ ║ 6456094 ║ │ ╚════╝ ╚══╤═╝
┌─┴─╖ │ ╚════╤════╝ ┌─┴─╖ ╙─┬─╜ ┌─┴─╖ │ ║ 8219021 ║ │ ┌───╖ ┌─┴─╖
┌───┤ · ╟────────┴────┐ └─────┬────┤ · ╟───┴───┤ · ╟─┤ ║ 4660190 ║ └──┤ × ╟───┤ % ║
│ ╘═╤═╝ │ ┌┴┐ ╘═╤═╝ ╘═╤═╝ │ ╚════════╤╝ ╘═╤═╝ ╘═╤═╝
│ │ │ └┬┘ │ │ │ ╔═══╗ ┌─┴─╖ ┌──┴─╖ ╔═╧═╗
│ │ ╔═══╗ ┌────╖ │ ┌─┴─╖ ┌┐ │ │ │ ║ 8 ╟──┤ ʫ ╟──┤ >> ║ ║ ║
│ │ ║ 1 ╟─┤ >> ╟─┘ ┌───┤ ? ╟─┤├─┤ │ │ ╚═══╝ ╘═╤═╝ ╘══╤═╝ ╚═══╝
│ │ ╚═══╝ ╘══╤═╝ │ ╘═╤═╝ └┘ │ │ │ ╔════════════════╧═════════╗
│ │ ┌─┴─╖ ┌───╖ ┌─┴─╖ ┌─┴─╖ ╔═╧═╗ │ │ ║ 609678112368778425678534 ║
│ ┌─┴─────────┤ ʫ ╟─┤ ‼ ╟─┤ · ╟─┤ ‼ ║ ║ 1 ║ │ │ ║ 616189712722605554111376 ║
│ │ ╘═╤═╝ ╘═╤═╝ ╘═╤═╝ ╘═╤═╝ ╚═══╝ │ │ ║ 461573643915077926310571 ║
│ │ │ │ │ ╔═╧══╗ │ │ ║ 355541007599150245813976 ║
│ │ ╔══════╗ │ │ └───╢ 45 ║ │ │ ║ 426564826002362964111793 ║
│ │ ║ 2097 ║ │ ┌─┴─╖ ┌───╖ ╚════╝ │ │ ║ 714054902293682079346275 ║
│ │ ║ 1565 ║ └───┤ · ╟─┤ ♭ ╟─┐ │ │ ║ 663973372550500581508544 ║
│ │ ╚═╤════╝ ╘═╤═╝ ╘═══╝ ├────────────────────┘ │ ║ 874263187322344354338195 ║
│ │ ┌─┴─╖ ┌─┴─╖ │ │ ║ 642609790172899326178321 ║
│ │ │ ‼ ╟─────────┤ ? ╟───────┘ │ ║ 071643306454414932126243 ║
│ │ ╘═╤═╝ ╘═╤═╝ │ ║ 308860823981077902637848 ║
│ ┌─┴─╖ ┌─┴─╖ ╔═══╗ ┌─┴─╖ │ ║ 322657399386789617074176 ║
└─┤ · ╟─┤ ʫ ╟─╢ 8 ║ ┌─┤ ? ╟────────────────────────────────┘ ╚══════════════════════════╝
╘═╤═╝ ╘═╤═╝ ╚═══╝ │ ╘═╤═╝
│ ┌───┴╖ ╔════╗ │ ╔═══╗
└─┤ >> ╟─╢ 21 ║ └─╢ 0 ║
╘════╝ ╚════╝ ╚═══╝
Continuing in the tradition of giving Funciton functions names consisting of a single, strange, rarely-used Unicode character, I thought about what could best represent this challenge, and it occurred to me that Link and Zelda (or, if you want, Legend of Zelda) give you LZ, so the lower-case digraph ʫ (U+02AB, ʟᴀᴛɪɴ sᴍᴀʟʟ ʟᴇᴛᴛᴇʀ ʟᴢ ᴅɪɢʀᴀᴘʜ) seems appropriate.
Explanation
As explained in the esolangs article, the Funciton program receives the input encoded as what I would call “UTF-21”, but as a single humongous integer. If I wanted to use this number as a key to a hashmap (dictionary, associative array), I’d need a hash function that satisfies two criteria: one, it’s simple enough to implement in Funciton, and two, all of the 13 expected input strings give a different hash value. The simplest hash function I could think of was input % m
for some value of m
. Therefore, I tried m
= 13, 14, 15, etc. until I got to the smallest integer for which all the hash values are unique. Turns out this number is 25.
The hash values are:
zel = 6
sas = 19
eps = 10
sos = 22
sot = 1
sst = 9
mof = 14
bof = 3
sow = 13
nos = 17
ros = 21
pol = 16
scs = 23
We encode each song by having one bit represent the presence or absence of a note. For example, Zelda's Lullaby would be encoded as follows:
---^-----^------- = 01001000
-<-----<--------- = 10010000
----->----->----- = 00100100
----------------- = 00000000
----------------- = 00000000
except that the bits are in the opposite order; the top left cell is in the least significant bit. This means every song is 40 bits long.
We thus create a (moderately sparse) hash table by taking a 40×25 = 1000-bit number and placing the bit pattern for each song in the right place according to its hash value. The monstrous number in the program is exactly this hash table.
Here’s what each of the remaining numbers mean:
45
= 0x2D
is the Unicode for -
.
1257283645609482190214660190
: This is the string ^<>VA
in UTF-21. In hindsight I could have used 7 bits per character here, making the number shorter, but UTF-21 is so deeply traditional in Funciton that it simply didn’t occur to me.
2097151
= 0x1FFFFF
= (1 << 21) − 1. Used to get the first character from the above string.
20971565
: This is the string -\n
, which is appended to the end of each line.
- It may seem curious that this number and the previous look so similar, but if you think about it, it’s because we’re using decimal and the Unicode for
\n
happens to be 10. That last number is (10 << 21) + 45.
The program now proceeds as follows:
- The main program calls
ʫ
with the following 3 parameters:
- B: The hash table, shifted right by 40 bits times the hash value of the input. The song we want to output is now in the 40 least significant bits.
- c: The string
^<>VA
.
- a: The number 8.
- In each iteration of
ʫ
,
- if c is not empty,
- if a is not zero, look at the bottom bit of B. Output
-
, followed by another -
if it is zero or the first character of c otherwise. Shift right B by one to remove one bit and decrement a.
- if a is zero, output
-\n
, then chop off the first character from c and start another loop with a = 8.
- if c is empty, we are done.
v
would look better. \$\endgroup\$