# Row, row, row your boat

Everyone is likely familiar with the following song, which is a musical round:

# Background

Fewer people might recall trying to sing the 4-person version of this with a few friends and failing. Offsetting the lyrics of a song with different harmonious pitches is known as singing a "round" and that's what we're here to simulate today using static output. Here's an example of someone actually performing the piece (link to audio/video, will have sound).

# The Challenge

This challenge is to output the text as follows exactly as it follows:

Row, row, row your boat,           |-----------------------------------|-----------------------------------|-----------------------------------
Gently down the stream.            |Row, row, row your boat,           |-----------------------------------|-----------------------------------
Merrily, merrily, merrily, merrily,|Gently down the stream.            |Row, row, row your boat,           |-----------------------------------
Life is but a dream.               |Merrily, merrily, merrily, merrily,|Gently down the stream.            |Row, row, row your boat,
-----------------------------------|Life is but a dream.               |Merrily, merrily, merrily, merrily,|Gently down the stream.
-----------------------------------|-----------------------------------|Life is but a dream.               |Merrily, merrily, merrily, merrily,
-----------------------------------|-----------------------------------|-----------------------------------|Life is but a dream.


# Rules

• Trailing whitespace is acceptable, but not required, this includes newlines.
• Hyphens and bars are part of the required output, yes.
• Commas, periods, capitalization and all syntactical elements related to grammar are required.

This is , the lowest byte-count code without using standard loopholes is the winner.

• I just want to say, I greatly enjoy your large kolmogorov-complexity and ascii-art challenges! Both this one and a keyboard so real have been extremely fun to write solutions for. :) – DJMcMayhem Apr 21 '17 at 17:24
• @DJMcMayhem ever since finding this site I see challenges randomly in my daily life and keep a small notepad for the ideas I get, I'll keep trying to make fun ones! – Magic Octopus Urn Apr 21 '17 at 17:35

# 05AB1E, 80 77 bytes

“¢ã,¢ã,¢ã€žžÄ,““èî„‹€€šæ.“"merrily, "4×¨“‚ì€ˆ€³€…žâ.“'-35×Ð)€ª.B3FDÁ})øvy'|ý,


Try it online!

Work in progress.

• I was pretty unimpressed by the dictionary not having "05AB1E" in it, by the way. It made it near impossible to efficiently sing 05AB1E happy birthday. Cool answer though, was hoping to see a dictionary-base 05AB1E answer haha. Also DJMcMayhem is correct, it does. – Magic Octopus Urn Apr 21 '17 at 16:25
• Wait, what is ª? Nevermind, sentence cased, brilliant. – Magic Octopus Urn Apr 21 '17 at 17:46
• @carusocomputing: Yeah, I only recently noticed that it exists. Have needed it several times in the past :P – Emigna Apr 21 '17 at 18:04
• vy can be ʒ to save a byte. – Kevin Cruijssen Jun 6 '19 at 11:17

# V, 139, 128 bytes

iLife is but a dream ±µ |4amerrily, x7b~A|Gently down the stream.±² |3arow, X5b~Ayour boat,±± |3I³µ-|3AòÄó.û-}|ò5DÎ4f|C|


A one-liner! (sortof :P)

Try it online!

Hexdump:

00000000: 694c 6966 6520 6973 2062 7574 2061 2064  iLife is but a d
00000010: 7265 616d 20b1 b520 7c1b 3461 6d65 7272  ream .. |.4amerr
00000020: 696c 792c 201b 7837 627e 417c 4765 6e74  ily, .x7b~A|Gent
00000030: 6c79 2064 6f77 6e20 7468 6520 7374 7265  ly down the stre
00000040: 616d 2eb1 b220 7c1b 3361 726f 772c 201b  am... |.3arow, .
00000050: 5835 627e 4179 6f75 7220 626f 6174 2cb1  X5b~Ayour boat,.
00000060: b120 7c1b 3349 b3b5 2d7c 1b33 4101 1bf2  . |.3I..-|.3A...
00000070: c4f3 2efb 2d7d 7cf2 3544 ce34 667c 437c  ....-}|.5D.4f|C|


Do I get bonus points for landing exactly on 2^7?

This took a while to figure out. I'm hoping I can golf tons off like my keyboard ASCII art answer, but I'm not sure. We'll see. They are very similar challenges (and both very fun :D)

Originally I tried this (180):

3irow, ch your boat,±± ||"rCLife is but a dream.±µ ||"lD4imerrily, r||"mCGently down the stream.±² ||"gC³µ-|B"dCR³D
GRDD
MGRD
LMGR
DLMG
DDLM
³DLÍR/r
ÍG/g
ÍM/m
ÍL/l
ÍD/d


Try it online!

Which inserts this:

RDDD
GRDD
MGRD
LMGR
DLMG
DDLM
DDDL


and then does substitution to expand it out. But building it style is much shorter (and more fun TBH)

• You get 0^(2^7) bonus points for landing on 2^7 haha. Interesting first thought though on the 180 version. – Magic Octopus Urn Apr 21 '17 at 17:40
• @carusocomputing Aww, why not give him (2^7)/0 bonus points? – Matthew Roh Apr 21 '17 at 23:38

## Batch, 292288 275 bytes

@set d=-------
@set "d=%d%%d%%d%%d%%d%^|
@set "m=M_ m_ m_ m_^|
@set "s=           ^|
@set "s=Life is but a dream.    %s%%m:_=errily,%Gently down the stream. %s%Row, row, row your boat,%s%%d%%d%%d%"
@for /l %%i in (1,1,6)do @call:c
:c
@echo %s:~111,146%
@set "s=%d%%s%


Edit: Saved 13 bytes by rewriting the code to use a version of the substring trick I used in my Retina answer. Conveniently I can loop six times and then fall through for a seventh iteration of the loop body, which means the quoting needed to output |s doesn't get too onerous, however I have to be careful to take the ^s into account when selecting the substring.

# Python 3, 252235208206 205 bytes

Alright, alright. Here's a less boring answer:

w=' '*11
t=["Row, row, row your boat,"+w,"Gently down the stream. "+w,"Merrily,"+" merrily,"*3,"Life is but a dream.    "+w,*['-'*35]*3]
for a in zip(*[t[z:]+t[:z]for z in range(7,3,-1)]):print(*a,sep='|')


Boring answer, and the other Python answer is shorter, but I thought I'd try if this approach is shorter. Python 3 despite the savings in byte/string 2-3 difference because both gzip and base64 are shittier in Python 2.

from base64 import*
from gzip import*
print(decompress(b85decode('ABzY8Fgf~I0{;ujFV|5hf)WaqK3h)N%@H-ItmC-qe~c2OAVKMYF<fBr9w)6d7eT^Myf(_Nl|KIuATz2dxGfaW-i~<qN2>4N*#q<oQxVex|z!-Gc8pivsfXiv_v6MAqB%CkU6w=GZ!&|OJj#}Q7chW$(>wu%p_Rd3;?AKH=M}>000')).decode())  • 25% of the original length, pretty impressive, but you could be far smarter and compress just the first iteration, split on newlines and perform 4 shifts. This would likely beat the other implementation of python. Thoughts to consider. I wasn't the one to -1, don't know who did that. – Magic Octopus Urn Apr 21 '17 at 17:38 • @carusocomputing True. I was really just interested how well run-off-the-mill compression works on such a highly redundant fixed output task. Converted my answer to a shorter, less dumb one though. – L3viathan Apr 21 '17 at 17:50 • Can you also edit back in the compression one? I, personally, found that approach interesting as well. Namely how low the byte-count got via simple gzip. It must use Huffman or something... +1 regardless for the effort. – Magic Octopus Urn Apr 21 '17 at 17:54 • @carusocomputing I'll add it at the bottom I guess. Also, I think it's not the Huffman part of deflate that is making this relatively great, but the LZ part. – L3viathan Apr 21 '17 at 17:58 • @JonathanAllan Indeed, I missed that. Fixed, lost a byte. – L3viathan Apr 23 '17 at 7:15 # PowerShell, 224207 202 bytes $a=' '*11;0..6|%{((0..4+4+4)[($_,($_+=6),--$_,--$_|%{$_%7})]|%{("Row, row, row your boat,$a","Gently down the stream.$a ","Merrily,$(' merrily,'*3)","Life is but a dream.$a ",('-'*35))[$_]})-join'|'}


Try it online! (the output is wrapped if your screen isn't wide enough)

Good grief, this array generation thing is ugly, but it saved 17 bytes, so ...

0..6|%{((0..4+4+4)[($_,($_+=6),--$_,--$_|%{$_%7})]  We loop from 0 to 6. Each iteration, we're indexing into an array (0,1,2,3,4,4,4). The indexing is based on the current digit, the current digit +6, that -1, and then that -1. Each of those is then fed through a loop where we modulo with %7. For example, if we're on 0 of the outer 0..6 loop, then these would be 0,6,5,4, then each %7, so 0,6,5,4. That's indexed into the (0,1,2,3,4,4,4) array, so the output is 0,4,4,4. For input 1 we get 1,7,6,5 then 1,0,6,5 which yields 1,0,4,4. And so on. (things would be so much easier if we had a .clamp function) Those are one-at-a-time spit into a loop |%{}. Each iteration, we index into the proper spot in the song-lyrics-array, and leave that string on the pipeline. Those strings are then -joined together with | to format the output line. Those strings are left on the pipeline and output is implicit. Saved some bytes thanks to Value Ink. • Considering that you already have $a saved to 11 spaces, you can change the fourth line to end in $a plus 4 spaces instead of $(' '*15) for -3 bytes, yes? – Value Ink Apr 24 '17 at 19:28

# JavaScript (ES8), 285256240231229217214213211 210 bytes

_=>"0444104421043210432144324443".replace(/./g,(x,y)=>a[x].padEnd(35)+
|||[++y&3],a=["Row, row, row your boat,","Gently down the stream.","Merrily,"+(m=" merrily,")+m+m,"Life is but a dream.","-".repeat(35)])


Saved a few bytes by borrowing a trick from Arnauld's answer

## Try It

f=

|||[++y&3],a=["Row, row, row your boat,","Gently down the stream.","Merrily,"+(m=" merrily,")+m+m,"Life is but a dream.","-".repeat(35)])

o.innerText=f()
<pre id=o>

• '0444,1044,2104,3210,4321,4432,4443'.split,.map saves you 10 bytes. Also, padEnd isn't part of ES6, or even ES7. – Neil Apr 21 '17 at 19:04
• Oops, meant to update that to ES8 - thanks, @Neil. And thanks for the tip, but I was in the process of working on another solution that ended up saving me 12 bytes. – Shaggy Apr 21 '17 at 19:38

# PHP, 191 Bytes

for(;$n<7;$n++)for($m=0;$m<4;)echo $m?"|":"\n",str_pad($i=["Row, row, row your boat,","Gently down the stream.",M.($t="errily,")." m$t m$t m$t","Life is but a dream."][$n-$m++],35," -"[!$i]);  Try it online! Expanded for(;$n<7;$n++) for($m=0;$m<4;) echo$m?"|":"\n"
,str_pad($i=["Row, row, row your boat,","Gently down the stream." ,M.($t="errily,")." m$t m$t m$t","Life is but a dream."][$n-$m++] ,35," -"[!$i]);

• You could save a character by removing the brackets from echo (it's not a function) – scrowler Apr 25 '17 at 2:50
• @RobbieAverill I know but the brackets include a ternary operator and I could remove it only it I replace the point through a comma – Jörg Hülsermann Apr 25 '17 at 11:00

# Python 2, 199 bytes

w=' '
s=['-'*35]
t=['Row, row, row your boat,'+w*11,'Gently down the stream.'+w*12,'Merrily,'+' merrily,'*3,'Life is but a dream.'+w*15]
print'\n'.join(map('|'.join,zip(t+s*3,s+t+s+s,s+s+t+s,s*3+t)))


Try it online!

Thanks to @mathjunkie for saving 14 bytes

• 'Merrily, merrily, merrily, merrily,' could be ('merrily, '*4).capitalize() right? Or is that not Python? – Magic Octopus Urn Apr 21 '17 at 17:43
• Or even shorter, 'Merrily,'+' merrily,'*3 – math junkie Apr 21 '17 at 17:54

# CJam, 128 122 bytes

"Row, row, row your boat,""gently down the stream."'M" merrily,"4*2>+"Life is but a dream."'-35*__]{35Se]}%a4*4,.m>z'|f*N*


Try it online!

Explanation

"Row, row, row your boat,"  e# Push this string.
"gently down the stream."   e# Push this string.
'M                          e# Push the character 'M'.
" merrily,"4*               e# Push the string " merrily, merrily, merrily, merrily,".
2>+                         e# Remove the first two letters of it, and append it to 'M',
e#   fixing the capitalization.
"Life is but a dream."      e# Push this string.
'-35*__                     e# Push a string containing 35 hyphens and make two copies of it.
]                           e# Collect all these strings in an array.
{35Se]}%                    e# Pad each of them to length 35 by adding spaces to the right.
a4*                         e# Repeat the array 4 times.
4,                          e# The range [0 1 2 3].
.m>                         e# Rotate each subarray of strings rightward by the corresponding
e#   number in the range.
z                           e# Transpose the array.
'|f*                        e# Join the strings on each row with '|' characters.
N*                          e# Join the rows together with newlines.


# SOGL, 83 bytes

┌׀0ρMVxDrž|⁷ΨB≈π93|↑D~Νķ‰¤t╤▼ΣΗ⁶⅔¾№⁷Ζ÷│²╥Ν9°‘-”)0ΔH«‘4*jŗ"ΣΨ¬¹‘4*;+7{’⁄{»}⁽:’∞n1wpX


The 1st part ┌׀0ρMVxDrž|⁷ΨB≈π93|↑D~Νķ‰¤t╤▼ΣΗ⁶⅔¾№⁷Ζ÷│²╥Ν9°‘ is a compressed string resulting in

life is but a dream.               |-|gently down the stream.            |row, row, row your boat,           |


These are the lines reversed (since this is printing them line-by-line), with the "merrily" part cut out to be replaced in the program.
The rest of the program:

...‘                                        Push the compressed string
)0ΔH«‘                                push "merrily, "
4*                              repeat it 4 times
j                             take the last letter off
-”         ŗ                            replace "-" with the merrily line
"ΣΨ¬¹‘                      push 35 dashes with an appending "|"
4*                    repeat it 4 times
;+                  add inverted ("---|---..."+"Life is but a dream  ...")
The resulting string of above is "-----------------------------------|-----------------------------------|-----------------------------------|-----------------------------------|life is but a dream.               |merrily, merrily, merrily, merrily,|gently down the stream.            |row, row, row your boat,           |"
7{                repeat 7 times
’⁄{»}            rotate right 35 times
⁽           uppercase the 1st letter
:          duplicate
’∞n       split into parts of length 135
1w     get the 1st one
p    output that
X   delete the splat array


# ///, 200 bytes

/_/     //&/errily,//*/ m&//+/-------//@/Row, row, row your boat, __//#/Gently down the stream.  __//$/M&***//%/Life is but a dream.___//~/+++++/@|~|~|~ #|@|~|~$|#|@|~
%|$|#|@ ~|%|$|#
~|~|%|$~|~|~|%  Try it online! Simple, uses common occurrences as replacements. # PHP, 179 bytes: for($m="errily,";$i<28;)echo str_pad($s=["Row, row, row your boat,","Gently down the stream.","M$m m$m m$m m$m","Life is but a dream."][($i>>2)-$i%4],35," -"[!$s])," |||"[++$i%4];


ungolfed

for($i=0;$i<28;$i++) {$x=$i%4;$y=$i>>2;$s=["Row, row, row your boat,",
"Gently down the stream.",
M.($m="errily,")." m$m m$m m$m",
"Life is but a dream."
][$y-$x];

$pad_string =$s ? " ":"-";
$postfix =$x<3 ? "|" : "\n";
echo str_pad($s,35,$pad_string),$postfix; }  ## JavaScript (ECMAScript 2017), 191187 182 bytes Saved 3 bytes thanks to Shaggy f=(i=27,s=['Life is but a dream.','Merrily,'+(m=' merrily,')+m+m,'Gently down the stream.','Row, row, row your boat,'][(i>>2)-i%4]||'')=>i?s.padEnd(35,' -'[+!s])+ |||[i&3]+f(i-1):s o.innerHTML = f(); <pre id=o style="font-size:10px"></pre> • I think 'Merrily,'+' merrily,'.repeat(3) saves a byte. – Neil Apr 21 '17 at 20:02 • Oh, and I forgot to mention that padEnd isn't in ES7, let alone ES6. – Neil Apr 21 '17 at 20:10 • M${s='errily, '}m${s}m${s}m instead of M${s='errily,'} m${s} m${s} m saves 2 bytes – Luke Apr 21 '17 at 21:02 • You can save 3 bytes with "Merrily,"+(s=" merrily,")+s+s. – Shaggy Apr 22 '17 at 8:09 • @Shaggy Ah yes. That seems to be the best option. Thanks! – Arnauld Apr 22 '17 at 8:53 Microsoft Sql Server, 421 bytes with v as(select left(s+space(35),35)s,n from(values('Row, row, row your boat,',1),('Gently down the stream.',2),('Merrily, merrily, merrily, merrily,',3),('Life is but a dream.',4))t(s,n))select isnull(v.s,s.s)+'|'+isnull(b.s,s.s)+'|'+isnull(c.s,s.s)+'|'+isnull(d.s,s.s)from v full join v b on v.n=b.n+1 full join v c on b.n=c.n+1 full join v d on c.n=d.n+1 cross apply(select replicate('-',35)s)s order by isnull(v.n,9)  Check It Online • I love it. Database is my message! – Zahiro Mor Apr 22 '17 at 20:55 # C (GCC), 231 230 bytes -1 byte thanks to ceilingcat! #define m"errily, " char s[7][35]={"Life is but a dream.","M"m"m"m"m"m"m"m,"Gently down the stream.","Row, row, row your boat,"};f(l,c){memset(s[4],45,'k');for(l=7;l--;)for(c=0;c<4;)printf("%-35.35s%c",s[(4+l+c++)%7],"|||\n"[c]);}  Pretty straightforward. First it builds the 7 lines string array, part via a macro to factorise out the "merrily" part, then the lines of dashes are filled in with a memset. Then the lines are printed with the adequate offset and separators. Try it online! • @ceilingcat thanks! – Quentin Jun 12 '19 at 7:21 # MATLAB, 280 bytes a='errily,'; z={'Row, row, row your boat,';'Gently down the stream.';['M',a,' m',a,' m',a,' m',a];'Life is but a dream.'}; z{5}(1:35)='-'; y=5*ones(7,4); for j=1:4;z{j}(end+1:35)=' ';y(j:j+3,j)=(1:4)';end x=z(y); for j=1:7;fprintf('%s|%s|%s|%s\n',x{j,1},x{j,2},x{j,3},x{j,4});end  The cell array indexing is pretty costly, that seems like the easiest place to discard some bytes (if possible). • Welcome to the site! – DJMcMayhem Apr 21 '17 at 20:10 # Retina, 153 150 bytes  <-|>Life is but a dream.15|M!< m!>|Gently down the stream.12|Row, row, row your boat,11<|-> <(.*?)>$1$1$1
!
errily,
-
35$*- \d+$*
r!&.{71}\|.{71}


Try it online!

I tried arbitrary run-length encoding but $1$*$2 doesn't do what I want and repeating strings proved too tricky. Edit: Saved 2 bytes by encoding errily, and 1 byte by removing an unnecessary ^. # Python 2, 225 Bytes w=[["-"*35]*7for _ in[0]*4] for i in [0]*4:w[i][i:i+4]=[a.ljust(35)for a in["Row, row, row your boat,","Gently down the stream.","Merrily,"+" merrily,"*3,"Life is but a dream."]] print "\n".join(["|".join(i)for i in zip(*w)])  Try it online! # Perl 5, 215 bytes $m='merrily,';$s=' 'x11;$l='-'x35;
@t=@s=("Row, row, row your boat,$s","Gently down the stream.$s",
"\u$m$m $m$m","Life is but a dream.    $s",$l,$l,$l);
map{$i--;map$t[$_].="|".$s[$i++%7],0..6}1..3;print"$_\n"for@t


Try it online!

# Swift, 416406405380372 307 bytes

var f=String.init(repeating:count:);_={[[0,4,4,4],[1,0,4,4],[2,1,0,4],[3,2,1,0],[4,3,2,1],[4,4,3,2],[4,4,4,3]].forEach{print($0.map{["Row, row, row your boat,"+f(" ",11),"Gently down the stream."+f(" ",12),"Merrily,"+f(" merrily,",3),"Life is but a dream."+f(" ",15),f("-",35)][$0]}.joined(separator:"|"))}}


You can try it here.

Thanks to @Mr. Xcoder for saving me 65 bytes!

• Great to see a swift answer! – brimstone Apr 21 '17 at 23:17
• You can make it shorter by replacing the declaration of f to the following: var f=String.init(repeating:count:), which saves a ton of bytes: 30 – Mr. Xcoder Apr 22 '17 at 12:31
• Also, in the sandbox you shouldn't print(o()), you should just call o() because you have a print statement inside it, which gives a () at the end of the output – Mr. Xcoder Apr 22 '17 at 12:33
• Also, remove the unnecessary whitespace. It will save lots of bytes. I'll comment an improved version. – Mr. Xcoder Apr 22 '17 at 12:34
• Here is an improved version, 309 bytes. This is 63 bytes shorter and can be golfed, I believe – Mr. Xcoder Apr 22 '17 at 12:48

# T-SQL, 296 277 276 bytes

PRINT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE('1|0|0|0
2|1|0|0
3|2|1|0
4|3|2|1
0|4|3|2
0|0|4|3
0|0|0|4',0,REPLICATE('-',35))
,2,'Gently down the stream. 6')
,3,'M5 m5 m5 m5')
,4,'Life is but a dream.    6')
,5,'errily,')
,6,SPACE(11))


Line breaks at the beginning are part of the original string, line breaks near the end are for display purposes only, and are not counted toward the byte total.

Pretty straight-forward multi-replacement, but a few things that help save bytes:

• SQL allows line breaks in the original string
• Using numerals instead of characters allows me to eliminate a whole bunch of single quotes
• Nested replacements (5 and 6), save me even more bytes (thanks, @t-clausen.dk)

If only I could REPLACE all the REPLACEs with something shorter. Hmm....

• If you REPLACE space 11,12,15 using your own method, you can save 1 byte – t-clausen.dk Aug 13 '19 at 9:04

# Japt-R, 999594929089 87 bytes

R³iLife  ¿t a Ým.
M{34îÎk, m}
Gt§ Üµ e Ðpam.
Row, w, w yr ¾,ú)·ú-
£éY Å¤q|


Try it

R³iL...{34î...}...,ú)·ú-
R                                :Newline
³                               :Repeat 3 times
i                              :Prepend
                             :  Decompress
L...                         :    "Life is but a dream.\nM"
{                        :    Interpolate
34î                     :      Repeat & slice to length 34
...                :        The compressed string "errily, m"
}               :    End interpolation
...,           :    "\nGently down the stream.\nRow, row, row your boat,"
:  End decompression
ú         :  Right pad each line with spaces to the length of the longest
)        :End prepend
·       :Split on newlines
ú-     :Right pad each element with "-" to the length of the longest
£éY Å¤q|                         :Assign the above to U
£                                :Map each element at 0-based index Y
éY                              :  Rotate U right Y times
Å                            :  Slice off the first element
¤                           :  Slice off the first two elements
q|                         :  Join with "|"
:Implicit output, joined with newlines


# Ruby, 162 bytes

7.times{|i|puts (~i..~i+3).map{|j|[*[?-*35]*3,"Life is but a dream.",?M+['errily,']*4*" m","Gently down the stream.","Row, row, row your boat,"][j].ljust(35)}*?|}


# Java, 295 bytes / 272 259 bytes

with newlines every 4 columns (295b)

void r(){String m=" merrily,",t="-------",s="     ",e=t+t+t+t+t;String[]v={"Gently down the stream.  "+s+s, "Merrily,"+m+m+m, "Life is but a dream."+s+s+s, e, e, e, "Row, row, row your boat, "+s+s};for(int i=0;i<7;i++){for(int j=6+i;j>2+i;j--)System.out.print(v[j%7]+'|');System.out.println();}}


Try it Online

no newline version (259b):

void r(){String m=" merrily,",t="-------",s="     ",e=t+t+t+t+t;String[]v={"Gently down the stream.  "+s+s, "Merrily,"+m+m+m, "Life is but a dream."+s+s+s, e, e, e, "Row, row, row your boat, "+s+s};for(int i=0;i<28;i++)System.out.print(v[(6-i%4+i/4)%7]+'|');}

• Condensed 2 for loops into 1

Try it Online

# Japt, 158 157 bytes

='|L=Row, žw, žw yŒr ¾…,+Sp11 +UV=Gt§ Üµ e Ðpam.+S³²²+UW=M€Îk,+ ´rÎk,³+UJ=W+VX=Life ‰ ¿t a Ý„m.+Sp15 +UZ='-p35 +U[LZ³RVLZ²RJLZRXJLRZXJRZ²XWRZ³X]q


Try it online!

# Stax, 63 bytes

∞╖]ÇàI╨‼Çö¼fi╩╨╛Aóß╟uƒ←37qÄô.Z╛Θ6►Mûj╚#Å[░]Oá0"y╧o╙)5;V╞♥╬F¼♫t~


Run and debug it

# Perl 5, 163 bytes

say join'|',(('-'x26)x3,"Life is but a dream".$"x7,ucfirst(join$",("merrily,")x3),"Gently down the stream    ",ucfirst "row, "x3 ."your boat  ")[-$_..3-$_]for 1..7


Try it online!

# Runic Enchantments, 292 bytes

B͍"-"'#*"|"3s
"Row, row, row your boat,"b" "S*q"|"3sB͍>01B10B3*1-akr@>12B01B10B2*1-akr@>13B12B01B10B1-akr@>14B13B12B01B1-akr@>10B3*14B1-r0[10B2*14B13B1-akr0[10B14B13B12B1-akr]]@
B͍"Gently down the stream."c" "S*q"|"3s
B͍"Merrily,"3" merrily,"S*q"|"3s
B͍"Life is but a dream."f" "S*q"|"3s


Try it online!

I don't generally do challenges, but the layout was one I could work with without too much trouble. Runic does not have good ways to compress arbitrary strings, so all we have to work with are the repetitious parts.

### Explanation:

Uncompressing slightly:

B͍"-"'#*"|"3s
B͍"Row, row, row your boat,"b" "S*q"|"3s
B͍"Gently down the stream."c" "S*q"|"3s
B͍"Merrily,"3" merrily,"S*q"|"3s
B͍"Life is but a dream."f" "S*q"|"3s
>11B10B3*1-akr@
>12B11B10B2*1-akr@
>13B12B11B10B1-akr@
>14B13B12B11B1-akr@
>10B3*14B1-r0[10B2*14B13B1-akr0[10B14B13B12B1-akr]]@


First 5 lines act as functions to build each portion of the song (where the first line generates the 35 - for the spacer using the decimal value of # to save 2 bytes over 3X5+). The return instruction is at the beginning of the line to insure that all IPs that enter a function will also leave the function after the same number of cycles to avoid IPs merging (resulting in missing lines of output), as programs are rectangular and empty cells are implicit.

The next four lines are responsible for printing the first four lines of the output

The fifth line then prints the last 3 lines of output. Due to all three lines needing to start with at least one stanza-spacer it is not feasible to use 3 separate IPs (as they would need delays in order to avoid merging). >, y, @, and a newline cost more bytes (4) than 0[...] (3 bytes) where ... is arbitrary instructions (ie. another line of output).

Conversely replacing > and @ to use a single IP requires more bytes.

Finally, merging all five entry-point lines onto the 2nd line saves 5 bytes worth of newlines. We just have to insure that the B͍ranch-return instruction moves to the end of its line first, preserving the function's functionality.