27
\$\begingroup\$

Your task is to write a program which prints following four verses extracted from the lyrics from The Beatles' song "Hey Jude" (© Sony/ATV Music Publishing LLC):

Hey Jude, don't make it bad\n
Take a sad song and make it better\n
Remember to let her into your heart\n
Then you can start to make it better\n
\n
Hey Jude, don't be afraid\n
You were made to go out and get her\n
The minute you let her under your skin\n
Then you begin to make it better\n
\n
Hey Jude, don't let me down\n
You have found her, now go and get her\n
Remember to let her into your heart\n
Then you can start to make it better\n
\n
Hey Jude, don't make it bad\n
Take a sad song and make it better\n
Remember to let her under your skin\n
Then you'll begin to make it\n
\n

BUT

The only input you are allowed to use to construct these four verses is this list of tokens:

"Hey Jude, don't"
" make it bad"
" be afraid"
" let me down"
"Take a sad song and make it better"
"You"
" were made to go out"
" and get her"
" have found her, now go"
"Remember to"
"The minute you"
" let her"
" into your heart"
" under your skin"
"Then"
" you"
" can start"
"'ll"
" begin"
" to make it"
" better"

Note that some tokens have a space preceded and that enclosing quotes are not part of the tokens. You are free to use any format for the list and to rearrange the order of the tokens.

Your generated output has to exactly match the above four verses. Note that\n is used for newlines and an extra newline is added after each verse. You can use this file (MD5: 4551829c84a370fc5e6eb1d5c854cbec) to check your output against.

You can use following railroad diagram to understand the structure of the verses (each element represents a token): enter image description here

Shortest code in bytes wins. Happy golfing.

\$\endgroup\$
  • 47
    \$\begingroup\$ The part that goes Nah nah nah nah nah nah, nah nah nah, would have easier to compress. ^^ \$\endgroup\$ – Arnauld Feb 19 '18 at 16:14
  • 3
    \$\begingroup\$ @Arnauld Related :P \$\endgroup\$ – DJMcMayhem Feb 19 '18 at 16:20
  • 10
    \$\begingroup\$ @Arnauld obligatory XKCD xkcd.com/851_make_it_better \$\endgroup\$ – Nathaniel Feb 20 '18 at 0:30
  • 3
    \$\begingroup\$ It must be hard to sing all those backslashes at the end of every line. \$\endgroup\$ – Tamás Sengel Feb 20 '18 at 10:36
  • 2
    \$\begingroup\$ @bonh railroad-diagrams \$\endgroup\$ – arminb Feb 20 '18 at 15:03

13 Answers 13

9
\$\begingroup\$

Jelly, 42 bytes

;⁷“Ṙç€ṘḋḷŒø|Ṁ2kḤ⁽⁼SƁẒVṿẎj]ð⁵ṀƒƤ)÷Ƒ¦Ẋ½Iɠ⁻’ṃ

Try it online!

Hardcoding version.

Input:

["Hey Jude, don't", ' make it bad', 'Take a sad song and make it better', 'Remember to', ' let her', ' into your heart', 'Then', ' you', ' can start', ' to make it', ' better', ' be afraid', 'You', ' were made to go out', ' and get her', 'The minute you', ' under your skin', ' begin', ' let me down', ' have found her, now go', "'ll"]
\$\endgroup\$
17
\$\begingroup\$

JavaScript (ES6), 108 bytes

a=>`01
4
9bc
efgjk

02
567
abd
efijk

03
587
9bc
efgjk

01
4
9bd
efhij

`.replace(/./g,n=>a[parseInt(n,36)])

Try it online!


Alternate version, 114 bytes

A slightly better compression, but sadly ruined by the larger decompression code.

a=>`835fc3cbbd3
84db3db4bbdb3
85cd1cc3cbbd3
835fc4bbcb3

`.replace(/./g,n=>a[n='0x'+n,i=n%8&&n%8-2+i]+[`
`[n>>3]])

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I did not know that the m flag is not required for multi-line template literals. Interesting. \$\endgroup\$ – Grant Miller Feb 27 '18 at 0:56
7
\$\begingroup\$

Ruby + -p, 177 136 120 118 115 109 bytes (full program)

$_="abvevjlmvopqtuvvacvfghvklnvopstuvvadvfihvjlmvopqtuvvabvevjlnvoprstv".gsub(/./){|c|(eval$_)[c.ord-97]||$/}

Try it online!

-41 bytes: Switch from using variables to using characters as array indexes

-16 bytes: Switch to a more convenient input format

-1 byte: No space needed between puts and "abv...

-1 byte: Use $/ global instead of ?\n literal

-3 bytes: Use gsub(/./) instead of .chars.map

-6 bytes: Call with -p and make use of $_. Thanks Pavel!

Each character in the magic string represents an index into the input array. I need the variable z so that I only read from STDIN once.

I could save some cost from IO by writing a lambda accepting an array and returning a string. This requires an extra v at the end, because it's not getting a free newline from -p.

Ruby, 162 110 108 105 bytes (function)

->z{"abvevjlmvopqtuvvacvfghvklnvopstuvvadvfihvjlmvopqtuvvabvevjlnvoprstvv".gsub(/./){|c|z[c.ord-97]||$/}}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I haven't been able to find a way to use String#unpack to be shorter than .chars with .ord-97, but there might be one. \$\endgroup\$ – benj2240 Feb 19 '18 at 22:01
  • 1
    \$\begingroup\$ Here's a few bytes off: tio.run/##VY/… \$\endgroup\$ – Pavel Feb 20 '18 at 4:32
  • \$\begingroup\$ Neat, thanks! Today I learned about -p and $_ \$\endgroup\$ – benj2240 Feb 20 '18 at 5:22
  • \$\begingroup\$ Forgive my ignorance, but how would I run this from the command-line or IRB? \$\endgroup\$ – John Topley Feb 21 '18 at 8:47
  • 1
    \$\begingroup\$ @JohnTopley If you want to use IRB, you could copy-paste these three lines one by one. To use the full program from the command line, start here \$\endgroup\$ – benj2240 Mar 2 '18 at 18:49
4
\$\begingroup\$

Java 8, 241 233 141 140 138 bytes

a->{a.add("\n");"01E4E9;<E>?@CDEE02E567E:;=E>?@CDEE03E587E91<E>?@CDEE01E4E91=E>?ABCEE".chars().forEach(i->System.out.print(a.get(i-48)));}

Explanation:

Try it online.

a->{                  // Method with ArrayList<String> parameter and no return-type
 a.add("\n");         //  Add a new-line as last item (index 21) to the input-List
 "01E4E9;<E>?@CDEE02E567E:;=E>?@CDEE03E587E91<E>?@CDEE01E4E91=E>?ABCEE".chars().forEach(i->
                      //  Loop over the bytes of this String above
   System.out.print(  //   Print:
     a.get(i-48)));}  //    The String in the list at index `i-48`

It basically converts the ASCII characters 0 (48) through E (69) to the 0-indexed indices 0 through 21 with the i-48.

\$\endgroup\$
4
\$\begingroup\$

Python 3, 162 147 144 142 138 127 bytes

lambda k,x=b'ABVCVDEFVGHIJKVVALVMNOVPEWQVGHRJKVASVVMTOV':"".join([(k+['\n',' '])[i-65]for i in x+x[5:16]+x[:4]+b'VDEWQVGHURJ'])

Try It Online

Special thanks to user202729 and Pavel.

\$\endgroup\$
4
\$\begingroup\$

05AB1E, 142 68 66 65 bytes

`¶)•7/è¸ĀuVI{è:÷MDS.₁bö¼d@ÉÃƶõî›Λðë’OŒβι"žHƒö>“ÃaÈǝõöÓ∍¿þœθÀ•2ôèJ

Try it online!

-74 bytes thanks to EriktheOutgolfer, using a base-255 compressed string.

-2 bytes by reversing the compressed string to prevent having to concatenate three 0's

-1 byte thanks to EriktheOutgolfer, by switching two items in the input array in order to avoid the leading 0's, and thus removing the Reverse R command.

\$\endgroup\$
2
\$\begingroup\$

Retina 0.8.2, 115 bytes

^
12F5F:<=F?@ADEFF13F678F;<>F?@CDEFF14F698F:<=F?@ADEFF12F5F:<>F?@BCDF¶
{`1(?=.*¶(.*))
$1
^(.*)¶.*
$1
}T`1-E`0-D
F
¶

Try it online! Takes input as a newline-delimited list of strings.

\$\endgroup\$
2
\$\begingroup\$

Stax, 59 58 bytes

îòÖ╥╬╬╞:,y╓ønä⌠╦╒ï╦≤x◘‼ε╩ⁿ◙ΓZ►e«qpôr╡"╣Ü≥┤╢┴;╡ÑkAú0:=;m╠╠x

Run and debug it

The corresponding ascii representation of the same program is this.

`ORIpY$T&z{m6Y=>mR)_ .VQ)eN70e[:0yO8j$^RN[ Bp{IN/$|"3^;G#^&lv!`FAx+@]p

`ORIpY$T&z{m6Y=>mR)_ .VQ)eN70e[:0yO8j$^RN[ Bp{IN/$|"3^;G#^&lv!` is a compressed literal with a value of "CDBGBLNOBQRSVWBBCEBHIJBMNPBQRUVWBBCFBHKJBLNOBQRSVWBBCDBGBLNPBQRTUVBB". The characters represent indexes into the token table. This program adds another token to represent a newline. It's not in the input, but added during execution. The rest of the program works like this.

F           for each character, execute the rest of the program
 A          integer literal 10, character code of newline
  x+        append 10 to the input array
    @       get element at index, using wrap-around
                the list is size 22, and B is 66, so B gets the first token
     ]      wrap the result in a singleton array.
                this effectively turns 10 into "\n"
      p     print without newline
\$\endgroup\$
2
\$\begingroup\$

C (gcc) function, 139 bytes

i,m;f(char**s){for(i=0;i<68;)m="AB@E@JLM@OPQTU@@AC@FGH@KLN@OPSTU@@AD@FIH@JLM@OPQTU@@AB@E@JLN@OPRST@@"[i++],printf(m^64?"%s":"\n",s[m-65]);}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Nice. Can you explain the code? \$\endgroup\$ – arminb Mar 6 '18 at 13:35
  • \$\begingroup\$ @arminb Nothing too fancy, the long "AB@E..." String contains the indices of the tokens and newlines ABC... = token[012].. '@' = newline, A token or newline is printed as 'i' iterates through that string. \$\endgroup\$ – PrincePolka Mar 6 '18 at 20:25
  • \$\begingroup\$ merge the printf in for \$\endgroup\$ – l4m2 Apr 20 '18 at 11:07
  • 1
    \$\begingroup\$ reverse the coding \$\endgroup\$ – l4m2 Apr 20 '18 at 11:09
  • 1
    \$\begingroup\$ 126 bytes \$\endgroup\$ – ceilingcat Jun 28 '18 at 20:37
1
\$\begingroup\$

Red, 133 bytes

foreach c{abzezjlmzopqtuzzaczfghzklnzopstuzzadzfihzjlmzopqtuzzabzezjlnzoprstzz}[prin either c =#"z"["^/"][t/(to-integer c -#"a"+ 1)]]

Try it online!

Ungolfed

t is a block with the list of tokens

s:{abzezjlmzopqtuzzaczfghzklnzopstuzzadzfihzjlmzopqtuzzabzezjlnzoprstzz}
foreach c s[                           ; for each character in s
    prin either c = #"z"               ; if it's a 'z' 
        ["^/"]                         ; print CR
        [t/(to-integer c - #"a" + 1)]  ; otherwise find which token to print
]                                      ; by mapping its offset to the alphabet
\$\endgroup\$
1
\$\begingroup\$

D, 166 bytes

import std.algorithm,std.range;T f(T)(T[]s){return"abvevjlmvopqtuvvacvfghvklnvopstuvvadvfihvjlmvopqtuvvabvevjlnvoprstvv".map!((int a){return(s~["\n"])[a-97];}).join;}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Mathematica, 102 bytes

""<>Append[#,"
"][[36^^ajikrj7lg8pya7wgtt43pvrilsik1dea1uht6mx3go33m4mjj02hb4wi9w3~IntegerDigits~23]]&

Pure function. Takes a list of strings as input and returns a string as output. Just encodes all the token indices, similarly to other answers.

\$\endgroup\$
1
\$\begingroup\$

Ruby, 97 bytes

->a{112.times{|i|$><<a[i%7-1+i%28/7*5]*("0@Xg(44k$,Xg0@Tz"[i/7].ord>>~i%7&1)+$/*(i%7/6+i%28/27)}}

Try it online!

Saved a few bytes with a different approach to most other answers.

The number of possible tokens in each line is as follows

Line number   Tokens 
1             4
2             5
3             5
4             7

The magic string contains one character per line, which is interpreted as a bitmap of which of up to 7 available tokens is to be printed for each of the 16 lines of the song.

a[i%7-1+i%28/7*5] iterates through the tokens of each line, shifting by 5 for each new line, and with an offset of 1 to account for the fact that the first line has only 4 tokens.

For lines 1-3 only the 64's through 4's bits are used - not using the 2's and 1's bits avoids printing tokens from the next line. for line 4, all 7 bits from 64's to 1's are used.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.