30
\$\begingroup\$

Write two triangle (i.e. pyramid) shaped programs.

The first one should be an upwards pointing text triangle with a minimum base width of three characters. So it would have a structure like

 X
XXX

or

  X
 XXX
XXXXX

or

   X
  XXX
 XXXXX
XXXXXXX

or larger. Each of the X's is to be replaced with the characters of your actual code, which may be anything except line terminators (so the X's could be spaces). All the X's must be replaced and the spaces and newlines that help form the triangle shape are required to stay as is.

The second program must have the same size and shape as the first, except that the triangle will be pointing down.

So if your first program looks like

  X
 XXX
XXXXX

then your second program would look like

yyyyy
 yyy
  y

where each y is a character you need to fill in with your actual code (probably different from your X code). The spaces and newlines must stay the same here too.

Your task is to write these programs such that they each output (to stdout or closest alternative) the title of a distinct Beatles song, not taking any input. This Wikipedia article will serve as our official song list for The Beatles. The output should be one of the titles exactly as listed, e.g. I Want You (She's So Heavy).

This is pretty easy, however, even with the weird triangle program requirement. So we're going to form another program from the first two that must output yet another song title.

By combining three copies of each of the two triangular programs we can create a third program shaped like a hexagon.

If the base width of your first program was three it would look like this:

 XyyyX
XXXyXXX
yyyXyyy
 yXXXy

If the base width was five it would look like this:

  XyyyyyX
 XXXyyyXXX
XXXXXyXXXXX
yyyyyXyyyyy
 yyyXXXyyy
  yXXXXXy

This program (when run with the spaces and newlines like the others) must output another Beatles song title, just like the first two programs. Also:

  • Your three programs must output different song titles.
  • Only song titles eight characters in length or longer are allowed.
  • You can only choose one of Revolution, Revolution 1 and Revolution 9 because the titles are so similar.
  • You must choose your three favorite Beatles songs. (Well, try to.)

Note that actual programs are required. Functions are not allowed. Reading your own source code in any program is also not allowed.

Example

If your first program was

  A
 AAA
AAAAA

it could output Across the Universe.

Then your second program

bbbbb
 bbb
  b

could output Revolution.

Then combined into the hexagon program

  AbbbbbA
 AAAbbbAAA
AAAAAbAAAAA
bbbbbAbbbbb
 bbbAAAbbb
  bAAAAAb

the output might be Get Back.

Scoring

The submission with the smallest triangle base width wins. In the likely case of ties the submission with the largest summed length of its three song titles wins.

\$\endgroup\$
7
  • 2
    \$\begingroup\$ Surely the tiebreaker should be the best choice of three songs? ;) \$\endgroup\$ Sep 18, 2015 at 3:36
  • 1
    \$\begingroup\$ I'm having difficulty writing a Python entry without just copying Sp3000's method (never thought I'd be complaining about syntactic whitespace!), but I wrote a script to assemble two triangles into a hexagon. In case it's useful to anyone else, here it is in a Gist. \$\endgroup\$ Sep 18, 2015 at 10:06
  • \$\begingroup\$ @mbomb007 Trailing spaces not part of the triangle pattern are not ok. \$\endgroup\$ Sep 18, 2015 at 21:08
  • \$\begingroup\$ @TimPederick Since I couldn't get your hexagon-ifier to work, I wrote a Python script to do it starting with 2 multi-line strings. See here if anyone wants to use it. \$\endgroup\$
    – mbomb007
    Sep 18, 2015 at 21:29
  • \$\begingroup\$ @mbomb007 Sorry but a trailing space isn't allowed since it's not part of the title. (I'd allow a trailing newline since lots of print statements add one.) I'm not sure about the usual backspace policy but they're ok with me. \$\endgroup\$ Sep 18, 2015 at 22:20

8 Answers 8

21
\$\begingroup\$

Befunge-93, width = 13 15, titles = 31 24 chars

A power outage last night prevented me from updating this when I figured it out, but I managed to reduce the triangle width and increase the song lengths!

Pointing-up program: "Dig a Pony", 10 characters:

      v
     v> 
    v#  >
   "<     
  v <>"y"v>
 <v"Dig a P"
"^>:#,_@.>"no

Explanation

I REALLY took advantage of Befunge's wrap-around trick and I picked "Dig a Pony" specifically because it had a space at the 6th position. This allows program flow to move through the song name. Try it in the online interpreter to see how it works.

Pointing-down program: "If I Fell", 9 characters:

< v"f I Fell"
 v>"I">:#,_@
  "raC yM "
   v"Drive


       .

(Period is extraneous and only included to make the other lines show up.)

Explanation

The only relevant lines here are the first two. I used the wrap-around trick (the instruction pointer is sent left immediately) to squeeze in one more character. The second line prints out the song name.

Combined: "Drive My Car", 12 characters:

      v< v"f I Fell"v
     v> v>"I">:#,_@v> 
    v#  >"raC yM "v#  >
   "<     v"Drive"<     
  v <>"y"v>     v <>"y"v>
 <v"Dig a P"   <v"Dig a P"
"^>:#,_@.>"no "^>:#,_@.>"no
< v"f I Fell"v< v"f I Fell"
 v>"I">:#,_@v> v>"I">:#,_@
  "raC yM "v#  >"raC yM "
   v"Drive"<     v"Drive
         v <>"y"v>     
        <v"Dig a P"   
       "^>:#,_@.>"no 

Here's the same thing, but with lines added to show the hexagon and triangles.

       -----------------
      /v\< v"f I Fell"/v\
     /v> \v>"I">:#,_@/v> \
    /v#  >\"raC yM "/v#  >\
   /"<     \v"Drive/"<     \
  /v <>"y"v>\     /v <>"y"v>\
 /<v"Dig a P"\   /<v"Dig a P"\
/"^>:#,_@.>"no\ /"^>:#,_@.>"no\
-------------------------------
\< v"f I Fell"/v\< v"f I Fell"/
 \v>"I">:#,_@/v> \v>"I">:#,_@/
  \"raC yM "/v#  >\"raC yM "/
   \v"Drive/"<     \v"Drive/
    \     /v <>"y"v>\     /
     \   /<v"Dig a P"\   /
      \ /"^>:#,_@.>"no\ /
       -----------------

Explanation

This is where the third and fourth lines of the pointing-down triangle come into play. There are several redirects at the edge of both triangles that serve to move the instruction pointer through those two lines and push "Drive My Car" onto the stack. Then it is printed out using the >:#,_@ bit in the pointing-up triangle. Incidentally, both the left and the right pointing-up triangles are used.

There might be a way to use more of the empty space, but I think my time is better spent on other questions. :P

\$\endgroup\$
2
  • \$\begingroup\$ Hmm. The rules of PPCG are that if a program works in at least one interpreter, then it's valid. Good spot, though. \$\endgroup\$ Dec 2, 2016 at 1:45
  • \$\begingroup\$ Another "rule" of PPCG is that the interpreter defines the language, not the specification. Thus, my Befunge code is, essentially, valid. \$\endgroup\$ Dec 2, 2016 at 3:30
18
\$\begingroup\$

GolfScript, width = 9 chars, titles = 33 chars

Hexagon

    "Let It Be"
   }";"Yeste"}";      
  "Twi""rda""Twi"
 "st an""y""st an"
"d Shout"}"d Shout"
Let It Be"Let It Be
 "Yeste"}";"Yeste"
  "rda""Twi""rda"
   "y""st an""y"
    }"d Shout"}

Prints Let It Be. (9 characters)

Try it online.

How it works

The token "Let It Be" on the first line pushes the string Let It Be on the stack.

The second line begins with }, an undocumented "super comment" that aborts execution immediately.

Before exiting, GolfScript prints the contents of the stack.

X triangle

    "
   }";
  "Twi"
 "st an"
"d Shout"

Prints Twist and Shout. (15 characters)

Try it online.

How it works

The first two lines push the string "\n }", which the command ; discards from the stack.

The remaining lines contain the tokens "Twi", "st an" and "d Shout", which push the string Twist and Shout in three pieces.

Before exiting, GolfScript prints the contents of the stack.

Y triangle

Let It Be
 "Yeste"
  "rda"
   "y"
    }

Prints Yesterday. (9 characters)

Try it online.

How it works

The tokens Let, It and Be on the first line are undefined, so they do nothing.

The three following lines contain the tokens "Yeste", "rda" and "y", which push the string Yesterday in three pieces.

The } on the last line does nothing; the program would have finished anyway.

Once more, GolfScript prints the contents of the stack before exiting.

\$\endgroup\$
18
\$\begingroup\$

Python 2, width = 51

                         #print "Yellow Submarine" if id else "(Reprise)"   ##
                        #.##...............................................##.#
                       #...##.............................................##...#
                      #.....##...........................................##.....#
                     #.......##.........................................##.......#
                    #.........##.......................................##.........#
                   #...........##.....................................##...........#
                  #.............##...................................##.............#
                 #...............##.................................##...............#
                #.................##...............................##.................#
               #...................##.............................##...................#
              #.....................##...........................##.....................#
             #.......................##.........................##.......................#
            #.........................##.......................##.........................#
           #...........................##.....................##...........................#
          #.............................##...................##.............................#
         #...............................##.................##...............................#
        #.................................##...............##.................................#
       #...................................##.............##...................................#
      #.....................................##...........##.....................................#
     #.......................................##.........##.......................................#
    #.........................................##.......##.........................................#
   #...........................................##.....##...........................................#
  #.............................................##...##.............................................#
 #...............................................##.##...............................................#
print "Sgt. Pepper's Lonely Hearts Club Band",;id=0#print "Sgt. Pepper's Lonely Hearts Club Band",;id=0
print "Yellow Submarine" if id else "(Reprise)"   ##print "Yellow Submarine" if id else "(Reprise)"   #
 #...............................................##.##...............................................#
  #.............................................##...##.............................................#
   #...........................................##.....##...........................................#
    #.........................................##.......##.........................................#
     #.......................................##.........##.......................................#
      #.....................................##...........##.....................................#
       #...................................##.............##...................................#
        #.................................##...............##.................................#
         #...............................##.................##...............................#
          #.............................##...................##.............................#
           #...........................##.....................##...........................#
            #.........................##.......................##.........................#
             #.......................##.........................##.......................#
              #.....................##...........................##.....................#
               #...................##.............................##...................#
                #.................##...............................##.................#
                 #...............##.................................##...............#
                  #.............##...................................##.............#
                   #...........##.....................................##...........#
                    #.........##.......................................##.........#
                     #.......##.........................................##.......#
                      #.....##...........................................##.....#
                       #...##.............................................##...#
                        #.##...............................................##.#
                         #print "Sgt. Pepper's Lonely Hearts Club Band",;id=0#

Yeah, well... Python.

Python comments begin with #, so the majority of lines is just comments. For the upwards facing triangle, the only thing that executes is

print "Sgt. Pepper's Lonely Hearts Club Band",;id=0

which prints Sgt. Pepper's Lonely Hearts Club Band.

For the downwards facing triangle, we execute

print "Yellow Submarine" if id else "(Reprise)"

which prints Yellow Submarine, since the function id is truthy.

When we combine the programs however, all that happens is the above two lines in sequence. Since the end of the first line sets id=0, which is now falsy, the end result is that we tack a (Reprise) to the end, getting Sgt. Pepper's Lonely Hearts Club Band (Reprise) as our output (Calvin said this is okay).

\$\endgroup\$
3
  • 16
    \$\begingroup\$ This makes me think of the Imperial March more than any Beatles song... \$\endgroup\$ Sep 18, 2015 at 2:54
  • 7
    \$\begingroup\$ I can hear the TIE-fighter sound effect just by seeing this shape \$\endgroup\$
    – Fatalize
    Sep 18, 2015 at 7:19
  • \$\begingroup\$ @Calvin'sHobbies Hahaha. Indeed! \$\endgroup\$
    – Luis Mendo
    Sep 18, 2015 at 12:17
17
\$\begingroup\$

Snowman 1.0.2, width = 13

      }?}///////////}
     ///"Get Back"////
    ///////////////////
   /////////////////////
  "Sun King//"[["Sun King
 "*"BirthdaysP/"*"Birthday
"]]8AaLsP[[///"]]8AaLsP[[//
?}///////////}?}///////////
 "Get Back"////"Get Back"/
  ///////////////////////
   /////////////////////
    //"[["Sun King//"[[
     sP/"*"BirthdaysP/
      /"]]8AaLsP[[///

Finally! A challenge where Snowman can thrive! :D :D

The slashes are mostly for aesthetic purposes, and the majority of them can be replaced with spaces (but that would make it look a whole lot more boring). Some slashes are necessary, for comments.

Program A (output: Birthday):

      }
     ///
    /////
   ///////
  "Sun King
 "*"Birthday
"]]8AaLsP[[//

This one's pretty simple. The first character (}) sets up our active variables, then there's a bunch of comments / no-ops. It then stores the string "Sun King\n " and immediately discards it (via *, storing it in a permavar which we never use). Then it stores "Birthday\n".

]] is a no-op here, since [[ foo ]] is a block comment in Snowman, but since there's no matching [[ before this ]] (within program A itself), it simply does nothing. Then 8AaL grabs the first 8 characters of the string, sP prints it, and [[ comments out the rest of the program (because again, there's no matching ]].

Program B (output: Get Back):

?}///////////
 "Get Back"/
  /////////
   ///////
    //"[[
     sP/
      /

This one's also pretty straightforward. ?} is equivalent to } (? simply sets all variables to inactive, which is a no-op here but again, important later). Then it stores the string "Get Back", does a bunch of no-ops (// to end of line is always a comment), and prints via sP.

Full program

Output is, you guessed it, Sun King1.

Let's look at this line by line:

  • Line 1

          }?}///////////}
    

    This sets our active variables, just like the previous programs (we can see now that the ? is needed so as to not simply toggle them on and then back off with }}). The rest of the line is commented out.

  • Lines 2-4

         ///"Get Back"////
        ///////////////////
       /////////////////////
    

    Comments...

  • Line 5

      "Sun King//"[["Sun King
    

    Here we store the string "Sun King//", and then start a block comment. This essentially skips everything until the next ]].

  • Line 6

     "*"BirthdaysP/"*"Birthday
    

    Still inside the block comment...

  • Line 7

    "]]8AaLsP[[///"]]8AaLsP[[//
    

    Here we break out of the block comment for a short period of time, to execute the code 8AaLsP. This is actually reused from program A. Since I chose all songs that are 8 letters long, I can simply use the same code for the combined program.

    Then it gets a little tricky. The next time we emerge from the block comment, we see 8AaLsP again. This time, however, all variables are undefined (we called sp, print, in consume mode, which gets rid of the variables). Since aal requires two arguments, and this time it only has one (8), it errors and leaves the variables unchanged.

    Similarly, sp encounters the 8, realizes it's the wrong type to be printed, and leaves the variables as is.

  • Lines 8-13

    ?}///////////}?}///////////
     "Get Back"////"Get Back"/
      ///////////////////////
       /////////////////////
        //"[["Sun King//"[[
         sP/"*"BirthdaysP/
    

    Still stuck in that block comment...

  • Line 14

          /"]]8AaLsP[[///
    

    Finally, we try calling that same print-first-8-chars sequence once again, and it fails once again, producing another two errors. (The 8 means that the variables are now 8 8, which is the correct number of variables for aal now, but still not the right types.)


1: as well as four runtime errors (SnowmanExceptions) to STDERR, but as per meta that doesn't matter.

\$\endgroup\$
1
  • \$\begingroup\$ The slashes are mostly for aesthetic purposes, and the majority of them can be replaced with spaces (but that would make it look a whole lot more boring) But it does make it a bit harder to grasp what's going on... \$\endgroup\$ Sep 18, 2015 at 11:41
14
\$\begingroup\$

><>, width = 11

     /"yadhtri"\ /
           v"B"/   
        ?!;>ol      
  duJ yeH" /"eduJ yeH
 o   >l?!;   o   >l?!;
staC"/"klaw staC"/"klaw
"yadhtri"\ /"yadhtri"\ 
     v"B"/       v"B"/
  ?!;>ol      ?!;>ol 
   " /"eduJ yeH" /"e
       o   >l?!;   
      staC"/"klaw 

2D languages have a pretty good time with this challenge.

Upwards arrow

     /


  duJ yeH
 o   >l?!;
staC"/"klaw

Program flow starts from the top-left, moving rightward. The / reflects up, and since ><> is toroidal we reappear from the bottom. We then hit another / and reflect again, and push the characters klawstaC one-by-one to the stack in string "" mode. Finally, we reflect upwards and hit a >l?!;o loop, which is the idiomatic way of printing the entire stack in ><>.

This prints Catswalk.

Downwards arrow

"yadhtri"\ 
     v"B"/
  ?!;>ol 
   " /"e

Basically the same thing, pushing the characters from the get go and using mirrors and arrows to direct program flow. This prints Birthday.

Combined

     /

  ?!;>ol      ?!;>ol 
     /"eduJ yeH" / 

The relevant parts are above (I've cut out a lot of lines in the middle). Using the / from the upwards arrow, we reflect upwards and wrap around, but since we now have the downwards arrow underneath, part of that code is executed instead. We then push the relevant characters to the stack, and reuse the output loop from the downwards arrow.

This prints Hey Jude.

\$\endgroup\$
5
\$\begingroup\$

Python 2, size 21

This program requires an ANSI-compatible terminal (DOS ANSI.SYS to be specific), since I use \x1b[2J to clear the console AND move the cursor to top-left. To make this compatible with other ANSI terminals, print \x1b[1J\x1b[H (this can still fit in a size 21 hexagon). I wasn't able to test this part, because I don't have a terminal that prints ANSI escape codes.

I think the program looks pretty cool, similar to the radioactive symbol (though the ASCII shading implies the colors are backwards) or the icon of the sniper weapon from Metroid Prime: Hunters.

It did fit in size 17, but I'd forgotten id=0 in the up arrow. I don't think I can shrink it back down, since that has to all be on one line...

Also, credit goes to Sp3000 for the idea to use id.

          #exec('print"'       ##
         ###'\x1b[2J"+(id '   ####
        #####'and"Hey Ju'    ######
       #######'de"or"Ca'    ########
      #########'tswalk'    ##########
     ###########'")')     ############
    ##############       ##############
   ################     ################
  ##################   ##################
 #################### ####################
id=0;print"Birthday"##id=0;print"Birthday"#
exec('print"'       ##exec('print"'       #
 '\x1b[2J"+(id '   ####'\x1b[2J"+(id '   #
  'and"Hey Ju'    ######'and"Hey Ju'    #
   'de"or"Ca'    ########'de"or"Ca'    #
    'tswalk'    ##########'tswalk'    #
     '")')     ############'")')     #
      #       ###############       #
       #     #################     #
        #   ###################   #
         # ##################### #
          #id=0;print"Birthday"##

Up Arrow:

          #
         ###
        #####
       #######
      #########
     ###########
    #############
   ###############
  #################
 ###################
id=0;print"Birthday",

Down Arrow:

exec('print"'       #
 '\x1b[2J"+(id '   #
  'and"Hey Ju'    #
   'de"or"Ca'    #
    'tswalk'    #
     '")')     #
      #       #
       #     #
        #   #
         # #
          #

"Hey Jude" is one of my favorite Beatles songs, but I really don't know that many. I've never heard the other two songs I'm using. It's not a genre I listen to often.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 1. \x1b[2J works only with ANSI.SYS; it shouldn't do anything in other terminals. Also, \x1b[;H expects an integer after the semicolon. To make both row and column default to 1, use \x1b[H. 2. \x1b[1J\x1b[H and \x1b[H\x1b[J should work on all ANSI terminals. 3. On Linux terminals, you can simply use \x1bc to reset the terminal. 4. \x1b can be replaced with a literal ESC byte, in case that helps improving your score. \$\endgroup\$
    – Dennis
    Sep 19, 2015 at 2:08
  • \$\begingroup\$ @Dennis Thanks for clearing that up. I still won't be able to improve my score, since I can't figure out a way to break the up-arrow's code onto multiple lines. \$\endgroup\$
    – mbomb007
    Sep 19, 2015 at 5:10
2
\$\begingroup\$

C (gcc), base width = 17

Top, "Hey Jude"

        s
       ;//
      s;///
     main(//
    ){puts(//
   #define T//
  s?"Michell"//
 "e":"Hey Jud"//
"e");}///////////

Try it online!

Bottom, "Matchbox"

s=1;/////////////
 #ifndef T//////
  main(){puts//
   ("Matchb"//
    "ox");}//
     # endif
      /////
       //\
        ;

Try it online!

Hexagon, "Michelle"

        ss=1;/////////////s
       ;//#ifndef T//////;//
      s;///main(){puts//s;///
     main(//("Matchb"//main(//
    ){puts(//"ox");}//){puts(//
   #define T//# endif#define T//
  s?"Michell"///////s?"Michell"//
 "e":"Hey Jud"////\"e":"Hey Jud"//
"e");}///////////;"e");}///////////
s=1;/////////////ss=1;/////////////
 #ifndef T//////;//#ifndef T//////
  main(){puts//s;///main(){puts//
   ("Matchb"//main(//("Matchb"//
    "ox");}//){puts(//"ox");}//
     # endif#define T//# endif
      /////s?"Michell"///////
       //\"e":"Hey Jud"////\
        ;"e");}///////////;

Try it online!

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

gawk, base length 15

Just found out it doesn't work with mawk :/

It's not too tricky, but being grown up in the 70s, with The Beatles still omnipresent on air, I had to answer this. First I thought awk wasn't suited, but then it came to me.

Since these scripts contain BEGIN- and/or END-blocks, they need to be told that there will be no input to execute the END-block. This can be achieved by either pressing Ctrl-D after starting them, or starting them like this:

awk -f script.awk </dev/null

which I think is more convenient. echo | awk -f script.awk will also work, but if I would have used an empty line as input I would have done this completely different.

Pointing up, prints For No One (Youtube link)

       #
      # #
     #   #
    BEGIN {
   print n?#
  #         #
 n"So Tired":#
n="For No One"}

The essential code without comments is this. Since n isn't defined it prints "For No One" if called by itself.

    BEGIN {
   print n?

 n"So Tired":
n="For No One"}

Pointing down, prints Blackbird

END{a="Blackb"#
 a=n?_:a"ird"#
  printf a  #
   n="I'm "#
    if(a) #
     print
      } #
       #

The essential code is this. If n was defined before it doesn't print anything. I enforced the nice output with a newline after every track name, because I had the room to do that and it looks nicer in the console. n is defined in the process; that's needed for the Hexagon.

END{a="Blackb"
 a=n?_:a"ird"
  printf a
   n="I'm "
    if(a)
     print
      }

Hexagon, prints I'm So Tired

       #END{a="Blackb"##
      # #a=n?_:a"ird"## #
     #   #printf a  ##   #
    BEGIN {n="I'm "#BEGIN {
   print n?#if(a) #print n?#
  #         #print#         #
 n"So Tired":#} #n"So Tired":#
n="For No One"}#n="For No One"}
END{a="Blackb"##END{a="Blackb"#
 a=n?_:a"ird"## #a=n?_:a"ird"#
  printf a  ##   #printf a  #
   n="I'm "#BEGIN {n="I'm "#
    if(a) #print n?#if(a) #
     print#         #print
      } #n"So Tired":#} #
       #n="For No One"}#

The essential code. Now finally that mysterious n is used. Because n is defined in the first line, the upwards pointing triangle prints the alternative output, and the downwards pointing triangle prints emptiness.

    BEGIN {n="I'm "
   print n?

 n"So Tired":
n="For No One"}
END{a="Blackb"
 a=n?_:a"ird"
  printf a  
   n="I'm "
    if(a) 
     print
      } 
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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