It's my Birthday :D

112

19

Introduction

Last year was my birthday (really!) and sadly I had to organise my own party. Well, now you know, couldn't you at least make the cake?

Challenge

Given an integer n as input, write a full program to output a birthday cake with n candles on.

Output

A piece of cake with one candle on is:

 $
 |
---
~~~
---

And a piece of cake with three candles on is:

 $ $ $
 | | |
-------
~~~~~~~
-------

I'm sure you can work it out from that

However, for input 0, you must output the following:

Congratulations on your new baby! :D

For input less than 0, you should output a candleless cake:

---
~~~
---

Nothing is allowed to be output to STDERR.

Trailing newlines and spaces are allowed.

Winning

Shortest code in bytes wins.

Leaderboard

var QUESTION_ID=57277;OVERRIDE_USER=30525;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

anon

Posted 2015-09-08T06:39:23.053

Reputation:

161Happy Birthday! – Dennis – 2015-09-08T06:40:54.200

1is leading whitespace (for example 2 newlines) allowed for the candleless cake? – Level River St – 2015-09-08T07:16:34.210

2@steveverrill Yes – None – 2015-09-08T07:21:49.580

Just to make sure: Should all negative numbers produce the same 3-character-wide candleless cake, or a cake of the same width as the corresponding positive number? – Paŭlo Ebermann – 2015-09-08T19:10:48.597

2@PaŭloEbermann A cake of 3-width – None – 2015-09-08T20:05:33.987

Nothing can be output to stderr only? What about outputting to System.err or file descriptor 2? – user253751 – 2015-09-09T07:33:02.347

1@immibis, isn't it the same? – sigod – 2015-09-09T16:28:41.093

I like the leaderboard. You should post the language and how many bytes it is. – jvriesem – 2015-09-09T16:52:30.130

@jvriesem I don't understand what you mean :/ – None – 2015-09-09T17:16:39.677

@sigod One per execution... – None – 2015-09-09T17:17:21.800

4@jvriesem No. It's code for snippet. – sigod – 2015-09-11T10:54:24.900

The leaderboard snippet is not working. – Starx – 2018-01-28T13:13:22.190

@Starx It appears to work for me. What's the problem for you? – None – 2018-01-28T16:57:35.910

It's an off-by-one error for me (: – Beefster – 2019-09-09T22:55:52.530

Answers

36

Pyth, 73 72 71 69 67 bytes

?Qjb+m*+\ dQ"$|"*RhyeS,1Q"-~-""Congratulations on your new baby! :D

Try it online.

Output for n < 0 contains 2 leading newlines, as permitted in comments. To get rid of them, use

?QjbfT+jR*\ hQ"$|"*RhyeS,1Q"-~-""Congratulations on your new baby! :D

PurkkaKoodari

Posted 2015-09-08T06:39:23.053

Reputation: 16 699

The smallest code, ofcourse, appears to be least human readable. – SKPS – 2016-10-07T13:39:40.560

WTF is this??? LOL – Starx – 2017-01-11T09:28:27.953

18

CJam, 76 75 bytes

ri_W>\_1e>)" $ |--~~--"2/f*Wf<N*"Congratulations on your new baby! :D"?_8>?

Try it online in the CJam interpreter.

How it works

ri           e# Read an integer from STDIN.
_W>          e# Check if it is greater than -1.
\_           e# Swap input and Boolean and copy the input.
1e>)         e# Take the maximum of input and 1 and increment the result.
             e# Let's call the result R.
" $ |--~~--" e# Push that string.
2/           e# Split it into [" $" " |" "--" "~~" "--"].
f*           e# Repeat each chunk R times.
Wf<          e# Discard the last character of each repeated chunk.
N*           e# Join the repreated chunks, separating by linefeeds.

"Congratulations on your new baby! :D"

?            e# If the input is non-zero, select the cake; else, keep the string.
_8>          e# Push a copy and discard the first 8 characters (single candle).
?            e# Select the unmodified cake/string if the input was non-negative,
             e# a candleless cake otehrwise.

Dennis

Posted 2015-09-08T06:39:23.053

Reputation: 196 637

11

Ruby, 120 bytes

Revision 1 (120 bytes)

18 bytes saved thanks to manatwork

n=gets.to_i
puts ['Congratulations on your new baby! :D',%w{\ $ \ | - ~ -}.map{|e|e.ljust 2*n+1,e},'---
~~~
---'][n<=>0]

Revision 0 (138 bytes)

n=gets.to_i
n>0&&[' $',' |',?-,?~,?-].each{|e|puts''.rjust(2*n+1,e)}
puts ['Congratulations on your new baby! :D','','---
~~~
---'][n<=>0]

For positive numbers: this iterates through a string corresponding to each line of the cake. These are used as pad strings to right justify the empty string to length 2*n+1. This avoids any complications with having to print an odd number of characters, when the natural repetition is equal to the pitch of the candles (i.e. 2 characters.) n>0&& is necessary to avoid outputting a single column in case of input zero.

For all numbers: "n<=>0" finds the sign of the input. The baby message is output for n=0, and an empty string for positive n (as correct output has already been given above.) For negative n, Ruby interprets the -1 as meaning the last element of the array, and outputs the candleless cake.

Level River St

Posted 2015-09-08T06:39:23.053

Reputation: 22 049

1Aren't there too many puts? `n=gets.to_i puts ['Congratulations on your new baby! :D',%w{\ $ \ | - ~ -}.map{|e|''.rjust 2*n+1,e},'---

---'][n<=>0]`
 – manatwork  – 2015-09-08T11:09:40.967

1One more: ''.rjuste.ljust. – manatwork – 2015-09-08T11:20:09.387

@manatwork thanks, I should have spotted that, but I did this very quick. I didn't know about backslash space with %w. And e.just: very clever. – Level River St – 2015-09-08T12:18:47.250

11

R, 157

write(if(n<-scan()){
z=matrix(c("$","|","-","~","-"),N<-2*max(1,n)+1,5,T)
z[seq(1,N,1+(n>0)),1:2]=" "
z}else"Congratulations on your new baby! :D","",N,F,"")

flodel

Posted 2015-09-08T06:39:23.053

Reputation: 2 345

2I'm learning a lot on write parameters there. Brilliant one – Tensibai – 2015-09-09T07:31:46.393

10

R, 228 226 220 221 Bytes


Last edit to correct the candleless cake, was as wide as the positive one on negative cases, thanks @CathG and @jbaums for the feedback

n=scan()
s=strsplit
p=paste0
a=b='-~-'
if(!n)cat('Congratulations on your new baby! :D')else{
if(n>0){a=p('  ',a);b=p('$|',b)}else n=1
a=s(a,'')
b=s(b,'')
d=data.frame(rep(c(a,b),n),a)
cat(do.call(p,d),sep="\n")}

Tensibai

Posted 2015-09-08T06:39:23.053

Reputation: 409

1A couple of bytes can be saved: <- can be =, and you can use a=b='-~-'. – jbaums – 2015-09-08T11:37:28.333

Ho, thanks @jbaums forget the first = and didn' tthough of the dual assignation – Tensibai – 2015-09-08T11:44:07.470

You have a bracket issue somewhere, I get Error: unexpected '}' – flodel – 2015-09-08T23:48:50.187

@flodel corrected. Copy/paste issue – Tensibai – 2015-09-09T05:27:30.523

10

JavaScript ES6, 136

Using alert for output - bad proportional font and the result is ugly. In the snippet below the alert is redirect to the snipped body, giving a better result.
The newline inside backticks is significant and counted.

Test running the snippet in Firefox.

/* Redefine alert for testing purpose */ alert=x=>O.innerHTML=x;

alert((n=+prompt())?[...'$|-~-'].map((c,i)=>(i>1?c:' '+c).repeat(i>1?n>0?n-~n:3:n>0&&n)).join`
`:'Congratulations on your new baby! :D')
<pre id=O></pre>

Less golfed

n=+prompt(); // get input and convert to number

if (n) { // if n != 0 prepare the cake
   output = [...'$|-~-'].map( // for each char of the five lines
     (c,i) => (i>1 ? c : ' '+c) // in line 0 and 1 symbols are space separated
     // if n < 0 repeat count is 0 for line 0 and 1, 3 for the other
     // if n > 0 repeat count is n for line 0 and 1, n+n+1 for the other
     .repeat(i>1 ? n>0 ? n-~n : 3 : n>0 && n) // 
   ).join`\n`;
}
else {
    output = 'Congratulations on your new baby! :D');
}

alert(output);

edc65

Posted 2015-09-08T06:39:23.053

Reputation: 31 086

Try this $('div pre code')[2].innerHTML ;) – Vasu Adari – 2015-09-11T13:34:05.843

7

R, 279 bytes

Interactive version (286 bytes):

b<-function(){
n=scan()
if(n==0)cat("Congratulations on your new baby! :D\n")
if(n>0){k=2*n+1;m=rep("-",k);cat(paste(c(rep(c(" ","$"),l=k),"\n",rep(c(" ","|"),l=k),"\n",m,"\n",rep("~",k),"\n",m,"\n"),collapse=""))}
if(n<0){m=rep("-",3);cat(paste(c(m,"\n",rep("~",3),"\n",m,"\n"),collapse=""))}
}

Not interactive version (279 bytes):

b<-function(n){
if(n==0)cat("Congratulations on your new baby! :D\n")
if(n>0){k=2*n+1;m<-rep("-",k);cat(paste(c(rep(c(" ","$"),l=k),"\n",rep(c(" ","|"),l=k),"\n",m,"\n",rep("~",k),"\n",m,"\n"),collapse=""))}
if(n<0){m=rep("-",3);cat(paste(c(m,"\n",rep("~",3),"\n",m,"\n"),collapse=""))}
}

Cath

Posted 2015-09-08T06:39:23.053

Reputation: 171

7

MATLAB / Octave, 194 198 195 189 171 167 bytes

Happy birthday to you Beta Decay! :)

Thanks to HamtaroWarrior for shaving off 4 bytes!


n=input('');m='$|'.';d='  '.';if(n==0)disp('Congratulations on your new baby! :D'),break;elseif(n<0)m=d;n=1;end,disp([[d repmat([m d],1,n)];repmat('-~-'.',1,2*n+1)]);

Sample Runs

I placed this into a script file called happy_birthday.m, then ran it a few times in the command prompt. Take note that when you enter in a negative number, there are two leading carriage returns, but that's allowed in this challenge:

>> happy_birthday
-1


---
~~~
---
>> happy_birthday
0
Congratulations on your new baby! :D
>> happy_birthday
1
 $ 
 | 
---
~~~
---
>> happy_birthday
2
 $ $ 
 | | 
-----
~~~~~
-----
>> happy_birthday
3
 $ $ $ 
 | | | 
-------
~~~~~~~
-------
>> happy_birthday
4
 $ $ $ $ 
 | | | | 
---------
~~~~~~~~~
---------
>> happy_birthday
5
 $ $ $ $ $ 
 | | | | | 
-----------
~~~~~~~~~~~
-----------

Code with spacing and explanations

% Get the input number from the user
n=input('');

% If the number is positive, the core candle sequence is going to be a column vector of a $ followed by a | character
m='$|'.';    

%// Array of one column and it has two spaces - going to use more than once
d = '  '.';

% If the number is 0, display the congratulations message and get out
if(n==0)
    disp('Congratulations on your new baby! :D')
    break;

% m stores the core candle sequence for displaying on the screen
% If the number is negative, the core candle sequence is going to be a column of two blank spaces
elseif(n<0)
    m=d; 
    n=1; % n is set to 1 as this is the number of "blank candles" we want to display
end

% This displays candles and the base together
% The top half is the displaying of the candles
% It is a column vector of spaces, followed by pairs of $,| in a column
% and another column of spaces - repeated n times
% The bottom half is the displaying of the cake
% The bottom half is a column vector of -,~,- for the base of the cake
% and is repeated 2*n + 1 times to match the candle display
disp([[d repmat([m d],1,n)];repmat('-~-'.',1,2*n+1)]);

The displaying part at the end is probably the most obfuscated part of the code. This is going to display a 5 row character matrix where the first two rows consists of the candles and the last three rows consists of the base of the cake.

The basis for the top half of the display is either two spaces in a column followed by another two spaces in another column in the case that the age is negative, or a $,- in a column followed by two spaces in another column. This is a 2 x 2 character matrix. The basis for the bottom half of the display is a single column vector of -,~,- which is a 3 x 1 character matrix.

The display command first tackles the first two rows of the cake by placing two spaces in the first column, followed pairs of a column of $,- or a column of spaces if n is negative, which gets changed to n=1, and another column of two spaces repeated for a total of n times. The next three rows simply replicate the -,$,- column vector for 2*n + 1 times to align the candles together with the base, thus completing the picture.

Try it online!

You can try this online using IDEOne's Octave compiler: http://ideone.com/4qXDdJ - however, there is a slight bug when reading in values from standard input. As such, the script is slightly modified where you have to change the value of n at the beginning of the code. Fork a new version of the script and change this to whatever integer value suits you in order to see what the output looks like.

rayryeng - Reinstate Monica

Posted 2015-09-08T06:39:23.053

Reputation: 1 521

1Pity you can't save the dot in ' '.' ! – Luis Mendo – 2015-09-08T21:54:17.407

1@LuisMendo - I know!... though I'm sure you don't object to the use of the transpose that way :) – rayryeng - Reinstate Monica – 2015-09-08T21:55:06.970

1Hahaha. I was once told here that this site is for abusing the language. And I follow that rule faithfully! – Luis Mendo – 2015-09-08T21:56:55.070

1@LuisMendo - I really wanted to get rid of the dot... but couldn't because MATLAB interprets that as a single quotation in the string :(. Would have saved me a few bytes... but after many iterations, this was the best I could come up with. – rayryeng - Reinstate Monica – 2015-09-08T22:00:59.680

@LuisMendo - managed to shrink it down to 171! – rayryeng - Reinstate Monica – 2015-09-09T02:05:10.103

Why don't you set m='$|'.' at the beggining, then only change to m=d if n<0? This way you could get rid of the else & end in else m='$|'.';end – Ikaros – 2015-09-11T09:15:27.353

@HamtaroWarrior good tip! – rayryeng - Reinstate Monica – 2015-09-11T14:21:06.360

6

JavaScript, 143 153 Bytes

for(v in k=' $ 0 | 0---0~~~0---'.split(+!(n=+prompt(c=''))))c+=k[v].repeat(n<0?1:n)+'\n';alert(n>0?c:n?c.slice(8):'Congratulations on your new baby! :D')

To see output in mono space font replace 'alert' by 'console.log'

Nainemom

Posted 2015-09-08T06:39:23.053

Reputation: 61

Welcome to PPCG! :) – None – 2015-09-08T13:47:32.327

2Sadly this displays the congratulation message for negative input too. – manatwork – 2015-09-08T13:50:02.733

@BetaDecay tnx :-) – Nainemom – 2015-09-08T13:57:59.307

Manatwork's right :/ I don't know enough JS to help – None – 2015-09-08T14:00:59.223

@manatwork yes you right! i misunderstood! – Nainemom – 2015-09-08T14:01:55.983

@manatwork i fix that with 10 more characters :-D – Nainemom – 2015-09-08T19:47:07.633

5

Moonscript, 141 bytes

n=0+io.read!
m=3
f=(s='-')->print s\rep m
if n>0
 m=n
 m=1+2*m,f' $',f' |'
if n==0 print"Congratulations on your new baby! :D"else f f!,f'~'

Ryan Russell

Posted 2015-09-08T06:39:23.053

Reputation: 131

3Welcome to Programming Puzzles and Code Golf! – Dennis – 2015-09-08T22:39:00.327

4

JavaScript ES6, 154 chars

alert((n=+prompt())?((n>0?` $
 |
`:(n=1)&&"")+`--
~~
--`).replace(/../gm,x=>x.repeat(n)).replace(/(.).*/gm,"$&$1"):"Congratulations on your new baby! :D")

And one more (154 too)

alert((n=+prompt())?` $
 |
--
~~
--`.slice(n<0?(n=1)-9:0).replace(/../gm,x=>x.repeat(n)).replace(/(.).*/gm,"$&$1"):"Congratulations on your new baby! :D")

To see output in monospace font (and move ouptut to the console) use

alert=x=>console.log(x)

Qwertiy

Posted 2015-09-08T06:39:23.053

Reputation: 2 697

4

rs, 117 bytes

^0$/Congratulations on your new baby! :D
-.+/-1
$$r=)^^(\1)\n
$$m=-(--)^^(\1)\n
(\d+)/ ($ $r (| $r$m~(~~$r$m
^-[^-]+/

Live demo and test cases.

kirbyfan64sos

Posted 2015-09-08T06:39:23.053

Reputation: 8 730

4

Mouse, 164 161 bytes

?N:N.0=["Congratulations on your new baby"33!'" :D"$]N.0>[#P,32!'36,N.;#P,32!'124,N.;]N.0<[1N:]2N.*1+D:#P,45,D.;#P,126,D.;#P,45,D.;$P0I:(I.2%=0=^1%!'I.1+I:)"!"@

Mouse is clearly not an ideal choice for this task, but it was fun.

Ungolfed:

? N.                               ~ Read N from STDIN
N. 0 = [                           ~ Have a baby for N == 0
  "Congratulations on your new baby" 33 !' " :D" $
]
N. 0 > [                           ~ If N > 0...
  #P, 32 !' 36, N.;                ~ Print the candle flames
  #P, 32 !' 124, N.;               ~ Print the candle sticks
]
N. 0 < [                           ~ If N < 0...
  1 N:                             ~ Set N = 1
]
2 N. * 1 + D:                      ~ Assign D = 2N + 1
#P, 45, D.;                        ~ Print the top cake layer
#P, 126, D.;                       ~ Print the middle layer
#P, 45, D.;                        ~ Print the bottom
$P                                 ~ Define the printing macro...
  0 I:                             ~ Initialize I to 0
  ( I. 2% = 0 = ^                  ~ While I != the second input
    1% !'                          ~ Print the first input
    I. 1 + I:                      ~ Increment I
  )
  "!"                              ~ Print a newline
@

The stack can contain only integers. !' takes an integer off the stack and prints the ASCII character with that code.

Alex A.

Posted 2015-09-08T06:39:23.053

Reputation: 23 761

4

Ceylon, 322 307 300 282 278 260 bytes

shared void run(){if(exists t=process.readLine(),exists n=parseInteger(t)){String r(String s)=>s.repeat(n);print(n>0thenr(" $")+"\n"+r(" |")+"\n"+r("--")+"-\n"+r("~~")+"~\n"+r("--")+"-"else(n<0then"---\n~~~\n---"else"Congratulations on your new baby! :D"));}}

The not yet golfed original (assuming negative cakes have width 3 instead of –2·n+1):

shared void birthdayCake() {
    if (exists text = process.readLine(), exists number = parseInteger(text)) {
        switch (number <=> 0)
        case (equal) {
            print("Congratulations on your new baby! :D");
        }
        case (smaller) {
            print("---\n~~~\n---");
        }
        case (larger) {
            print(" $".repeat(number));
            print(" |".repeat(number));
            print("--".repeat(number) + "-");
            print("~~".repeat(number) + "~");
            print("--".repeat(number) + "-");
        }
    }
}

This features the condition list in the if statement, each condition defining a value usable in the following conditions and in the body. Because they have the exist, the condition is only fulfilled when the values is not null, and thus the compiler knows the values is not null for the following code. (If nothing is entered (EOF), readline returns null. If parseInteger hits a non-integer, it also returns null. Our program then does nothing. As the behavior for those cases was not defined, I guess this is okay.)

Also we have the <=> operator, which maps to the Comparable.compare method, and returns a Comparison object, i.e. one of equal, smaller and larger. The compiler knows that those exhaust the Comparison type, so no else clause is needed in our switch statement.

The repeat method of class String does what one would expect. It is actually inherited from the same-named method in interface Iterable (as a string is, beside other stuff, just a list of characters).

Replacing my identifiers by one-letter ones and removing unneeded white space gives 322 characters:

shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){switch(n<=>0)case (equal){print("Congratulations on your new baby! :D");}case(smaller){print("---\n~~~\n---");}case(larger){print(" $".repeat(n));print(" |".repeat(n));print("--".repeat(n)+"-");print("~~".repeat(n)+"~");print("--".repeat(n)+"-");}}}

Replacing the series of print by explicit \ns (and one single print) brings it down to 307:

shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){switch(n<=>0)case(equal){print("Congratulations on your new baby! :D");}case(smaller){print("---\n~~~\n---");}case(larger){print(" $".repeat(n)+"\n"+" |".repeat(n)+"\n"+"--".repeat(n)+"-\n"+"~~".repeat(n)+"~\n"+"--".repeat(n)+"-");}}}

I tried alias-importing of repeat as r, but it doesn't help (the import declaration adds 40 characters, and we can only save 25 by replacing repeat with r).

What slightly helps, is using n.sign instead of n<=>0. While these two expressions have the same textual length, they have different types: the latter one is of type Comparison mentioned before (which has the three values smaller, larger and equal), the former one has type Integer, with the values -1, 1, 0 ... and because Integer has many more values, we also need an else clause. This is 300 characters long:

shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){switch(n.sign)case(0){print("Congratulations on your new baby! :D");}case(-1){print("---\n~~~\n---");}case(1){print(" $".repeat(n)+"\n"+" |".repeat(n)+"\n"+"--".repeat(n)+"-\n"+"~~".repeat(n)+"~\n"+"--".repeat(n)+"-");}else{}}}

Here with whitespace:

shared void b() {
    if (exists t = process.readLine(), exists n = parseInteger(t)) {
        switch (n.sign)
        case (0) {
            print("Congratulations on your new baby! :D");
        }
        case (-1) {
            print("---\n~~~\n---");
        }
        case (1) {
            print(" $".repeat(n) + "\n" +
                        " |".repeat(n) + "\n" +
                        "--".repeat(n) + "-\n" +
                        "~~".repeat(n) + "~\n" +
                        "--".repeat(n) + "-");
        }
        else {}
    }
}

We can safe some more by resigning about our switch statement and using if, coming to 282 characters(=bytes):

shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){if(n==0){print("Congratulations on your new baby! :D");}else if(n<0){print("---\n~~~\n---");}else{print(" $".repeat(n)+"\n"+" |".repeat(n)+"\n"+"--".repeat(n)+"-\n"+"~~".repeat(n)+"~\n"+"--".repeat(n)+"-");}}}

Formatted:

shared void b() {
    if (exists t = process.readLine(), exists n = parseInteger(t)) {
        if (n == 0) {
            print("Congratulations on your new baby! :D");
        } else if (n < 0) {
            print("---\n~~~\n---");
        } else {
            print(" $".repeat(n) + "\n" +
                        " |".repeat(n) + "\n" +
                        "--".repeat(n) + "-\n" +
                        "~~".repeat(n) + "~\n" +
                        "--".repeat(n) + "-");
        }
    }
}

We can safe another byte by swapping the cases around, since > is shorter than ==. Another "annoyance" is the repeated repeat(n) – we can define a local function (a closure, it remembers n from the defining block) with a shorter name:

String r(String s) => s.repeat(n);

This is a shorter way of writing this:

String r(String s) {
    return s.repeat(n);
}

We could use function instead of the return type for type inference, but this is not shorter. This gives us 278 bytes:

shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){if(n>0){String r(String s)=>s.repeat(n);print(r(" $")+"\n"+r(" |")+"\n"+r("--")+"-\n"+r("~~")+"~\n"+r("--")+"-");}else if(n<0){print("---\n~~~\n---");}else{print("Congratulations on your new baby! :D");}}}

Formatted:

shared void b() {
    if (exists t = process.readLine(), exists n = parseInteger(t)) {
        if (n > 0) {
            String r(String s) => s.repeat(n);
            print(r(" $") + "\n" + r(" |") + "\n" + r("--") + "-\n" + r("~~") + "~\n" + r("--") + "-");
        } else if (n < 0) {
            print("---\n~~~\n---");
        } else {
            print("Congratulations on your new baby! :D");
        }
    }
}

Actually, using the then and else operators instead of the if statements allows us to save some calls of print (and some braces):

shared void run() {
    if (exists t = process.readLine(), exists n = parseInteger(t)) {
        String r(String s) => s.repeat(n);
        print(n > 0 then r(" $") + "\n" +
                        r(" |") + "\n" +
                        r("--") + "-\n" +
                        r("~~") + "~\n" +
                        r("--") + "-"
                    else (n < 0
                        then "---\n~~~\n---"
                        else "Congratulations on your new baby! :D"));
    }
}

This is just 261 bytes:

shared void run(){if(exists t=process.readLine(),exists n=parseInteger(t)){String r(String s)=>s.repeat(n);print(n>0thenr(" $")+"\n"+r(" |")+"\n"+r("--")+"-\n"+r("~~")+"~\n"+r("--")+"-"else(n<0then"---\n~~~\n---"else"Congratulations on your new baby! :D"));}}

(I used run instead of b for the function name because this way it can be run with ceylon run without passing a function name.)

My Github repository has a commented version of this.

Paŭlo Ebermann

Posted 2015-09-08T06:39:23.053

Reputation: 1 010

4

Powershell, 139 134 132 126 bytes

$n=$args[0];if($n){$d=3;if($n-gt0){' $'*$n;' |'*$n;$d=$n*2+1}'-'*$d;'~'*$d;'-'*$d}else{'Congratulations on your new baby! :D'}

Justin Dunlap

Posted 2015-09-08T06:39:23.053

Reputation: 421

You can save 5 bytes by using $input instead of $args[0] (question doesn't say to use arguments instead of stdin), and you can use unary + to convert to a number: $n=+$input; – briantist – 2015-09-12T01:59:15.520

+$input did not seem to work - it complained that $input is an enumerator and does not have an addition operator. However, $args[0] can and should be an actual int, allowing us to at least drop the [int]. – Justin Dunlap – 2015-09-14T06:57:31.573

1So, this is really old, but you can save a couple bytes by moving the input into the if and swapping the else for an ;exit -- 122 bytes -- if($n=$args[0]){$d=3;if($n-gt0){' $'*$n;' |'*$n;$d=$n*2+1}'-'*$d;'~'*$d;'-'*$d;exit}'Congratulations on your new baby! :D' – AdmBorkBork – 2016-10-12T16:46:15.830

4

CoffeeScript, 160 bytes

f=(i,l=[" $ "," | ",_="---","~~~",_])->if!i then"Congratulations on your new baby! :D"else (if i<0then[_,l[3],_]else i++;(Array(i).join r for r in l)).join "\n"

Ungolfed:

f=(i)->
  l = [" $ "," | ","---","~~~","---"] # The layers
  if i == 0
    return "Congratulations on your new baby! :D"
  else if i < 0
    return [l[2], l[3], l[2]].join("\n")
  else
    i++
    return (Array(i).join(r) for r in l).join("\n")

Use it like:

f(10) # In the CoffeeScript console
alert(f(~~prompt("Y"))) # Browser, alert popup
console.log(f(~~prompt("Y"))) # Browser, log to console, and thus has monospace font

Try it online: link (Contains some custom display code, so everything looks soo nice...)

Ooops, almost forgot it! Happy birthday, @BetaDecay!

Bojidar Marinov

Posted 2015-09-08T06:39:23.053

Reputation: 209

4

C, 392 bytes

(known segmentation fault if no arguments are given)

#include <stdio.h>
#define P(s) printf(s);
#define F for(i=0;i<n;i++)
#define A(s, e) F{P(s)}P(e "\n")
int main(int c, char**v){int i,n=atoi(v[1]);if(n<0){n=3;A("-",)A("~",)A("-",)}else if(!n)P("Congratulations on your new baby! :D\n")else{A(" $",)A(" |",)A("--","-")A("~~","~")A("--","-")}}

Unminified and copiously spaced

#include <stdio.h>
#define P(s) printf ( s ) ;
#define F for ( i = 0 ; i < n ; i++ )
#define A(s, e) F { P ( s ) } P ( e "\n" )
int main ( int c, char ** v )
{
        int i, n = atoi ( v [ 1 ] ) ; 
        if ( n < 0 ) 
        {   
                n = 3 ; 
                A ( "-", )
                A ( "~", )
                A ( "-", )
        }   
        else if ( ! n ) 
                P ( "Congratulations on your new baby! :D\n" )
        else
        {   
                A ( " $", )
                A ( " |", )
                A ( "--", "-" )
                A ( "~~", "~" )
                A ( "--", "-" )
        }   
}

Funmungus

Posted 2015-09-08T06:39:23.053

Reputation: 41

Without C boilerplate the #defines's and main body total 247. – Funmungus – 2015-09-10T23:00:23.483

Welcome to PPCG! This is a really good answer--I especially like the macro abuse with A. I do see a couple more spaces that could be removed, and you can get rid of i by using c for the loop variable instead. Also, at least with gcc, including stdio.h or specifying the return type of main() isn't necessary: the compiler complains about it, but hey, this is code golf. ;) – DLosc – 2015-09-10T23:39:01.487

3

Python 2, 158 bytes


i=input()
l='\n'
s=''
if i==0:s='Congratulations on your new baby! :D'
elif i<0:s='---\n~~~\n---'
else:n=i*2+1;a=l+'-'*n;s=' $'*i+l+' |'*i+a+l+'~'*n+a
print s

SimonPJ

Posted 2015-09-08T06:39:23.053

Reputation: 141

3

Python 2, 150 bytes

m=input()
n=m-1
p="---"+"--"*n
g="\n~~~"+"~~"*n+"\n"
if m>0:print" $"*m,"\n"," |"*m
s=p+g+p
print s if m!=0 else"Congratulations on your new baby! :D"

Close to author's Python :(

Blex

Posted 2015-09-08T06:39:23.053

Reputation: 289

3

Perl, 139 127 117 bytes

Does not require '-n' or '-p' options.

Revision 3 (with thanks to Dom Hastings below):

$==<>;map{print$_ x(!$=||(/ /?$=:($=<1||$=)*2+1)).$/}!$=?'Congratulations on your new baby! :D':split 0,' $0 |0-0~0-'

Revision 2:

$n=<>;map{print$_ x($n==0?1:(/ /?$n:($n<1?1:$n)*2+1)).$/}$n==0?('Congratulations on your new baby! :D'):(' $',' |','-','~','-')

Revision 1:

$n=<>;map{print$_ x(($l=length())>2?1:($l==2?$n:($n<1?1:$n)*2+1)).$/}$n==0?('Congratulations on your new baby! :D'):(' $',' |','-','~','-')

Here's a version of revision 3 that doesn't have the leading blank new lines on negative input - 132 bytes.

$==<>;map{print$_ x(!$=||(/ /?$=:($=<1||$=)*2+1)).(/ /&&$=<0?'':$/)}!$=?'Congratulations on your new baby! :D':split 0,' $0 |0-0~0-'

phillipo

Posted 2015-09-08T06:39:23.053

Reputation: 31

Hey there, welcome! Thought I'd share a couple of ways you can save some bytes! You can drop the brackets around "Congratulations..." and if you replace ' $',' |','-','~','-' with split 0,' $0 |0-0~0-' you can drop those brackets too. Another save is replacing $n=<>;$n==0 with ($n=<>)==0. Also your ?1: could be || as you'd be saying $n==0 (which is 1) or your calculation. Hope that helps! – Dom Hastings – 2015-09-08T19:56:13.933

Hey there, thanks for that. Those brackets are a good one, and reminding me of the semantics of || is very helpful - it reminded me of $= to basically chomp the input, eliminating the requirement for specific 0 value tests. I'm not sure what you mean by $n=<>;$n==0 - my golf doesn't have that, and given I handle the input=0 case as input into the map{}(), I'm not sure how this would apply?

Anyway, taking your comments and using $= as my variable, this has been golfed down to 117 parbytes. Thanks very much! – phillipo – 2015-09-09T11:13:40.483

No problem at all! Glad to have helped! What I mean was that you have $n=<>; at the beginning and then $n==0 at the back of the map{}... so I think you could have the check as ($n=<>)==0 but if you're using $= instead you might be able to shrink it more! I always forget which of $- or $= can't be negative so I didn't want to mention it and be wrong! :) – Dom Hastings – 2015-09-09T11:17:31.417

3

golflua, 113 characters

\p(c)w(S.t(c,n))~$n=I.r()+0?n==0w"Congratulations on your new baby! :D"!??n>0p" $"p" |"n=n*2+1!?n=3$p"-"p"~"p"-"$

Sample run:

bash-4.3$ golflua -e '\p(c)w(S.t(c,n))~$n=I.r()+0?n==0w"Congratulations on your new baby! :D"!??n>0p" $"p" |"n=n*2+1!?n=3$p"-"p"~"p"-"$' <<< 5
 $ $ $ $ $
 | | | | |
-----------
~~~~~~~~~~~
-----------

bash-4.3$ golflua -e '\p(c)w(S.t(c,n))~$n=I.r()+0?n==0w"Congratulations on your new baby! :D"!??n>0p" $"p" |"n=n*2+1!?n=3$p"-"p"~"p"-"$' <<< 0
Congratulations on your new baby! :D

bash-4.3$ golflua -e '\p(c)w(S.t(c,n))~$n=I.r()+0?n==0w"Congratulations on your new baby! :D"!??n>0p" $"p" |"n=n*2+1!?n=3$p"-"p"~"p"-"$' <<< -5
---
~~~
---

manatwork

Posted 2015-09-08T06:39:23.053

Reputation: 17 865

3

Pip, 74 + 1 = 75 bytes

Takes the age as a command-line argument. Requires the -n flag.

Y^"-~-"a?a<0?yX3(s.^"$|")XaALyX2*a+1"Congratulations on your new baby! :D"

Github repository for Pip

The command-line argument is stored in a. We split "-~-" into a list of characters and Yank it into the variable y. The rest of the program is a big ternary expression:

  • a?
    If a is truthy (i.e. not zero):
    • a<0?yX3
      If a is negative, return y with each element repeated 3 times: ["---";"~~~";"---"]
    • Else (a is positive):
      • (s.^"$|")Xa
        Split "$|" into a list of characters, prepend a space (s) to each, and repeat each resulting element a times
      • yX2*a+1
        Repeat each element of y 2*a+1 times
      • AL
        Append the two lists
  • Else (a is zero), return the congratulations string

At the end of the program, the -n flag ensures that lists are printed with elements on separate lines, thus displaying a properly layered cake.

Here are the steps for an input of 2:

Candles
["$";"|"]
[" $";" |"]
[" $ $";" | |"]

Cake
["-";"~";"-"]
["-----";"~~~~~";"-----"]

Put it together
[" $ $";" | |";"-----";"~~~~~";"-----"]

Final output
 $ $
 | |
-----
~~~~~
-----

Happy birthday!

DLosc

Posted 2015-09-08T06:39:23.053

Reputation: 21 213

2

K (ngn/k), 87 bytes

{$[x<0;3#'2_*:;x;,'/(1+2*x)#;:"Congratulations on your new baby! :D"]("  -~-";"$|-~-")}

Try it online!

edit: whoops, easy 1-byte reduction i missed


if 2 lines of whitespace is permitted where the candles would be in the x<0 case, we can save 2 bytes with

{$[x<0;3#'*:;x;,'/(1+2*x)#;:"Congratulations on your new baby! :D"]("  -~-";"$|-~-")}

scrawl

Posted 2015-09-08T06:39:23.053

Reputation: 1 079

2

Lua, 299 Bytes

a=0+io.read() b=string.rep p=print if a==0 then p("Congratulations on your new baby! :D") else p(b(" ",a)..b("$ ",a)..("\n")..b(" ",a)..b("| ",a)) if a<0 or a==1 then p("---\n~~~\n---") else p(b(" ",a-1).."-"..b("-",2*a).."\n"..b(" ",a-1).."~"..b("~",2*a).."\n"..b(" ",a-1).."-"..b("-",2*a))end end

FabiF

Posted 2015-09-08T06:39:23.053

Reputation: 21

1Welcome to PPCG! Your code as it stands seems to give an error (attempt to compare string with number), but adding 0+ before io.read() fixes it for me. You can also save quite a few bytes by assigning print and string.rep to single-character variables. – DLosc – 2015-09-09T01:04:49.103

@DLosc thanks good idea :) and yeah u were right with the error sorry about that – FabiF – 2015-09-09T08:28:22.560

2

Perl, 144 bytes

143 bytes of code, plus one extra byte for the -n switch to capture stdin.

if($_!=0){print$_>0?" \$"x$_.$/." |"x$_.$/:""x($_=1);$_=$_*2+1;print"-"x$_.$/."~"x$_.$/."-"x$_;exit}print"Congratulations on your new baby! :D"

r3mainer

Posted 2015-09-08T06:39:23.053

Reputation: 19 135

1print"-~-"=~s!.!$&x($_*2+1).$/!ger for the cake? – manatwork – 2015-09-08T15:36:43.817

If you change the switch to -p this will also work: $_=$_!=0?($_>0?' $'x$_.$/." |"x$_:""x($_=1))."-~-"=~s!.!$/.$&x($_*2+1)!ger:"Congratulations on your new baby! :D" – manatwork – 2015-09-08T15:49:25.333

2

SpecBAS, 164

Uses the apostrophe shortcut to move to new line

INPUT n: IF n=0 THEN PRINT "Congratulations on your new baby! :D" ELSE IF n<0 THEN PRINT "---"'"~~~"'"---" ELSE PRINT " $"*n'" |"*n'"-";"--"*n'"~";"~~"*n'"-";"--"*n

Formatted for easier reading

INPUT n
IF n=0 THEN PRINT "Congratulations on your new baby! :D" 
ELSE IF n<0 THEN PRINT "---"'"~~~"'"---" 
ELSE PRINT " $"*n'" |"*n'"-";"--"*n'"~";"~~"*n'"-";"--"*n

Brian

Posted 2015-09-08T06:39:23.053

Reputation: 1 209

2

Python 3, 169 bytes

n=int(input())
m=max(n*2+1,3)
f=' {}'*n+'\n'+' {}'*n+'\n'+'-'*m+'\n'+'~'*m+'\n'+'-'*m
if n==0:f='Congratulations on your new baby! :D'
print(f.format(*['$']*n+['|']*n))

moorecm

Posted 2015-09-08T06:39:23.053

Reputation: 21

2

Julia, 143 bytes

n=int(readline())
p=println
l="\n"
n>0&&p(" \$"^n*l*" |"^n)
d=2(n<0?1:n)+1
p(d>1?"-"^d*l*"~"^d*l*"-"^d:"Congratulations on your new baby! :D")

Pretty straightforward. Ungolfed:

# Read n from STDIN and convert to an integer
n = int(readline())

# Print the candles for positive n
n > 0 && println(" \$"^n * "\n" * " |"^n)

# Define d as the width of the cake
d = 2(n < 0 ? 1 : n) + 1

# Newborns can't eat cake
if d > 1
    println("-"^d * "\n" * "~"^d * "\n" * "-"^d)
else
    println("Congratulations on your new baby! :D")
end

Alex A.

Posted 2015-09-08T06:39:23.053

Reputation: 23 761

2

Mathematica, 164 Bytes

Completely missed the candle-less cakes for n < 0, adding an additional 15 characters

r[a_,b_]:=StringRepeat[a,Abs@b];c=" $ ";t="---";m="~~~";f[n_]:=If[n>0,r[c,n]~~"\n",""]~~r[t,n]~~"\n"~~r[m,n]~~"\n"~~r[t,n];f[0]:="Congratulations on your new baby! :D"

Charlie Joey Hadley

Posted 2015-09-08T06:39:23.053

Reputation: 151

1Welcome to PPCG, this challenge is known as code golf, where you try and make your code as short as possible. This can be done by removing unnecessary whitespace and shortening variable names. – None – 2015-09-09T14:38:12.717

Thanks @BetaDecay I was getting a fast version up.. minimising now. Cheers :D – Charlie Joey Hadley – 2015-09-09T14:41:19.883

No problem. Looks good :) – None – 2015-09-09T14:41:40.877

2

pb, 567 bytes

^w[B=45]{vb[-1]^b[0]>w[B!0]{t[B]b[0]<b[T]>>}<}w[B!0]{>}b[65]w[X!0]{<b[B-48]}>w[B!65]{t[B]<t[B*10+T]b[0]>b[T]>}b[0]<t[B]b[0]<[X]>b[T]<b[T]vw[B=0]{b[1]}t[B]b[0]^b[B*T]vw[X!3]{b[45]vb[126]vb[45]^^>}^<<t[B]<b[B+T]w[B!0]{<vw[X!3]{b[0]vb[0]vb[0]^^>}^<<t[B]vvw[T!0]{b[124]^b[36]v>>t[T-1]}v<w[X!-1]{b[45]vb[126]vb[45]^^<}}^[Y]^<[X]>w[B=0]{>vvw[X!-1]{b[0]vb[0]^<}^>}t[111]b[67]>b[T]>b[110]>b[103]>b[114]>b[97]>b[116]>b[117]>b[108]>b[97]>b[116]>b[105]>b[T]>b[110]>b[115]>>b[T]>b[110]>>b[121]>b[T]>b[117]>b[114]>>b[110]>b[101]>b[119]>>b[98]>b[97]>b[98]>b[121]>b[33]>>b[58]>b[68]

I have some regrets.

There are some ways that this could be better. For example, upon figuring out that the input is negative, I then proceed to deduce which negative number it is. This is unnecessary, and maybe one day I'll dive back into this code to stop it.

Don't try to run this in pbi's "watch" mode, if you input a negative it'll crash when it tries to print chr(-1).

Here's the explained version version where I took notes while writing the program. If you'd like to better understand how it works... good luck, and let me know if you figure it out.

# parse number

^w[B=45]{vb[-1]^b[0]>     # if negative, put a -1 at (0, 0)
    w[B!0]{t[B]b[0]<b[T]>>} # move all digits left
<}
w[B!0]{>}b[65]        # put an "A" at the end of the number
w[X!0]{<b[B-48]}      # subtract 48 from each byte to get the digits of the number
>w[B!65]{             # while there's no "A" at the second digit
    t[B]<t[B*10+T]      # set T to (first digit * 10) + second digit
    b[0]                # destroy first digit
    >b[T]               # override 2nd digit with T
    >}                  # point at second digit to restart loop
b[0]<t[B]b[0]<[X]>b[T]<b[T] # move number to (0, -1) and (1, -1)
vw[B=0]{b[1]}t[B]b[0]^b[B*T] # multiply (0, -1) by -1 if required
vw[X!3]{b[45]vb[126]vb[45]^^>} # draw the negative cake
^<<t[B]<b[B+T]w[B!0]{ # if it's positive
    <vw[X!3]{b[0]vb[0]vb[0]^^>} # erase the cake
    ^<<t[B]vvw[T!0]{b[124]^b[36]v>>t[T-1]} # draw the candles
    v<w[X!-1]{b[45]vb[126]vb[45]^^<}       # draw the cake
}^[Y]^<[X]>w[B=0]{>vvw[X!-1]{b[0]vb[0]^<}^>} # erase the part of the cake that would show up
# hardcoded string for input 0
t[111]b[67]>b[T]>b[110]>b[103]>b[114]>b[97]>b[116]>b[117]>b[108]>b[97]>b[116]>b[105]>b[T]>b[110]>b[115]>>b[T]>b[110]>>b[121]>b[T]>b[117]>b[114]>>b[110]>b[101]>b[119]>>b[98]>b[97]>b[98]>b[121]>b[33]>>b[58]>b[68]

undergroundmonorail

Posted 2015-09-08T06:39:23.053

Reputation: 5 897

2

ScriptCS (C# script), 221 bytes

Obviously this won't win any prizes, but...

var n=int.Parse(Env.ScriptArgs[0]);Console.WriteLine(n==0?"Congratulations on your new baby! :D":string.Join("\n",new[]{" $"," |","-","~","-"}.Select((s,i)=>string.Concat(Enumerable.Repeat(s,i>1?(n>0?n:1)*2+1:n>0?n:0)))))

Justin Dunlap

Posted 2015-09-08T06:39:23.053

Reputation: 421

1

PHP, 197 185 bytes

<?php $t=($i=$argv[1])<0?3:2*$i+1;$n="
";$f='str_repeat';$d=$f('-',$t);$t=$f('~',$t);echo!$i?'Congratulations on your new baby! :D':($i>0?$f(' $',$i).$n.$f(' |',$i).$n:'')."$d$n$t$n$d";

Contributions:

  • -12 bytes from Jo.

More readable:

PHP, 197 bytes

<?php
$i=$argv[1];
$t=$i<0?3:2*$i+1;
$n="\n";
$f='str_repeat';
$d=$f('-',$t);
$t=$f('~',$t);
echo $i==0?'Congratulations on your new baby! :D':($i>0?$f(' $',$i).$n.$f(' |',$i).$n:'')."$d$n$t$n$d";

Starx

Posted 2015-09-08T06:39:23.053

Reputation: 111

You can save 12 bytes with a few changes

– Jo. – 2018-01-27T21:05:16.697

@Jo, haha, thanks. That certainly is a way to save some bytes. I like how you didn't use \n for the line break. I have updated. – Starx – 2018-01-28T13:12:01.647

1

Jelly, 49 46 bytes

Ḥ‘»3“-~-”ẋ€;@⁶p⁾$|¤ẋ€$Yµ“ŒḅœÑḄŻ:Ṁ¿Þ5sṭ+¬ḅḣ;»¹?

Try it online!

-3 bytes from Erik

ellie

Posted 2015-09-08T06:39:23.053

Reputation: 131

The non-competing policy doesn't exist anymore. – Erik the Outgolfer – 2018-01-26T22:13:31.227

@EriktheOutgolfer Oh, didn't know about that. Answer fixed, thanks! – ellie – 2018-01-27T06:47:53.940

Oh, and a few bytes less.

– Erik the Outgolfer – 2018-01-27T14:12:25.897

1

05AB1E, 44 bytes

_i“Ûà€‰€ž€¢‡Í! :D“.ªëdi>V„ $„ |}…-~-`)εY∍û}»

Try it online!

_i                               # if input != 0:
  “Ûà€‰€ž€¢‡Í! :D“               #  dictionary string "congratulations on your new baby! :D"
                  .ª             #  sentence case
ë                                # else:
 di        }                     #  if input >= 0:
   >V                            #   set Y = input + 1 (by default, Y is 2)
     „ $                         #   push literal " $"
        „ |                      #   push literal " |"
…-~-                             #  push literal "-~-"
    `                            #  dump each character separately
     )                           #  wrap the entire stack in a list:
                                 #   [" $", " |", "-", "~", "-"] if input > 0
                                 #   ["-", "~", "-"] if input < 0
      ε   }                      #  for each item in that list:
       Y∍                        #   extend to length Y
         û                       #   palindromize
           »                     #  join the stack by newlines
                                 # implicit output

Grimmy

Posted 2015-09-08T06:39:23.053

Reputation: 12 521

1

Zsh, 162 bytes

try it online!!

((!$1))&&<<<"Congratulations on your new baby! :D"&&exit
y=$[$1<0?2:2*$1] a=${(l:y:: $:)} b=${(l:y+1::-:)}
(($1>0))&&echo "$a\n${a//$/|}"
echo "$b\n${b//-/~}\n$b"

roblogic

Posted 2015-09-08T06:39:23.053

Reputation: 554

1

Lua 5.2, 187 Bytes

p=print n=io.read"*n"r=string.rep
if n==0 then p"Congratulations on your new baby! :D"else
m=3*math.max(n,1)if n>0 then p(r(" $ ",n))p(r(" | ",n))end
p(r("-",m))p(r("~",m))p(r("-",m))end

Minimalistic version. I'm open for improvements :)

Jakuje

Posted 2015-09-08T06:39:23.053

Reputation: 468

1

D, 276 264 257 251 249 234 231 229 bytes

import std.conv,std.range,std.algorithm,std.stdio:w=writeln;void main(string[]a){int n=a[1].to!int;n>0?"$|-~-".each!((i,c)=>repeat((i<2?" ":"")~c,i<2?n:2*n+1).joiner.w):n?"---
~~~
---".w:"Congratulations on your new baby! :D".w;}

You can test it on DPaste. Just enter desired N as command line argument on input tab. Or compile and run it in real command line: rdmd birthday_golf.d <N>

Not minified version:

import std.conv;
import std.range;
import std.algorithm;
import std.stdio;

void main(string[] args)
{
    int n = args[1].to!int;

    n > 0
        ?
            "$|-~-".each!((i, c) =>
                repeat((i < 2 ? " " : "") ~ c, i < 2 ? n : 2*n + 1).joiner.writeln)
        :
            n
                ? "---\n~~~\n---".writeln
                : "Congratulations on your new baby! :D".writeln
        ;
}

sigod

Posted 2015-09-08T06:39:23.053

Reputation: 111

1

bash, 264 242 bytes

First of all: happy birthday, @BetaDecay :)

And now...

read n;p="printf ";e="echo ";x="exit";s="seq ";[ $n -eq 0 ]&&$e"Congratulations on your new baby! :D"&&$x;[ $n -gt 0 ]&&{ $p' %.s$ ' `$s 1 $n`;$e; $p' %.s| ' `$s 1 $n`;$e;};$p'%.s---' `$s 1 $n`;$e;$p'%.s~~~' `$s 1 $n`;$e;$p'%.s---' `$s 1 $n`

Tarod

Posted 2015-09-08T06:39:23.053

Reputation: 181

1You young whippersnappers with your $() constructs. Don't forget the good ol' backtick (not sure how to quote them): read n;[ $n -eq 0 ]&&echo "Congratulations on your new baby! :D"&&exit;[ $n -gt 0 ]&&{ printf ' %.s$ ' seq 1 $n; echo; printf ' %.s| ' seq 1 $n; echo;};printf '%.s---' seq 1 $n;echo;printf '%.s~~~' seq 1 $n;echo;printf '%.s---' seq 1 $n (247 bytes) – Mike S – 2015-09-10T21:20:06.923

@MikeS Thank you! The last update has also other improvements. – Tarod – 2015-09-11T06:34:07.660

If you gzip the script and put a little header in front of it, you can actually get it down to 208 bytes. Unfortunately, since it's binary I have to deliver it in uuencoded format. Is this allowed? begin 644 c.uue M<V5D("]><V5D+V0@)#@?"!G=6YZ:7@+6,@?"!B87-H("US("TM(#L@97AI M=H?BP@(F-?R50#80!]S,.P48!/"[IQA-U6F5J^V-MQ!)M[IJ$_F6[5<T MV&>W_B4JXC2'^<TXK4I0EI;ZD#*W<H&8(/0>8RR31*\V%M',4N44-UO%QE(- M2VAMXT#ZB$(5;1_3>13PR?!K7_%S?\;.&>(UAAB,ZCA$7H?O24"YQ/U==L3E <E[C*-PE""-$A#_'1>^__]E_[W@V096/,``$````` end – Mike S – 2015-09-11T13:44:48.933

To @Tarod But I didn't include your code in my gzipped file. The way to make it is this: Put your code into file a. gzip -c a > b . Create a file c with the following contents: sed /^sed/d $0|gunzip -c|bash -s --;exit. Now cat b >> c (you cannot edit c because vim at least munges the binary). Run c. BTW, you can change $n -eq 0 to $n = 0 and save 2 bytes above because bash has virtually no typing. Finally, if I DO use your code from above instead of what I have in the uue above, it's actually 215 bytes. Funny how gzip compresses. – Mike S – 2015-09-11T13:54:06.433

1

C, 729 bytes

I'm new to programming, and new to Stack Exchange, however I still wanted to give it a shot with whatever my professor has taught me as of now:

#include<stdio.h>
int main(void)
{char a[2][100]={" "}, b[3][100],i;int c;for(i=1;i<100;i+=2){a[0][i]='$';a[1][i]='|';}for(i=0;i<100;++i){b[0][i]='-';b[1][i]='~';b[2][i]='-';}puts("enter ur age");scanf("%d", &c);if (c==0)printf("congratulations on your new baby!");else if (c<0){for(i=0;i<3;++i){printf("%c", b[0][i]);}printf("\n");for(i=0;i<3;++i){printf("%c", b[1][i]);}printf("\n");for(i=0;i<3;++i){printf("%c", b[2][i]);}printf("\n");}else{for(i=0;i<2*c;++i){printf("%c", a[0][i]);}printf("\n");for(i=0;i<2*c;++i){printf("%c", a[1][i]);}printf("\n");for(i=0;i<=2*c;++i){printf("%c", b[0][i]);}printf("\n");for(i=0;i<=2*c;++i){printf("%c", b[1][i]);}printf("\n");for(i=0;i<=2*c;++i){printf("%c", b[0][i]);}printf("\n");}return(0);}

The readable version of it is,

#include<stdio.h>
int main(void)
{

    char a[2][100]={" "}, b[3][100],i;
    int c;

    for(i=1; i<100; i+=2)
    {
        a[0][i]='$';
        a[1][i]='|';        
    }

    for(i=0; i<100; ++i)
    {
        b[0][i]='-';
        b[1][i]='~';
        b[2][i]='-';
    }   
    puts("enter ur age");
    scanf("%d", &c);
    if (c==0)
    printf("congratulations on your new baby!");
    else if (c<0)
    {

        for(i=0;i<3;++i)
        {
            printf("%c", b[0][i]);
        }
        printf("\n");
        for(i=0;i<3;++i)
        {
            printf("%c", b[1][i]);
        }
        printf("\n");

        for(i=0;i<3;++i)
        {
            printf("%c", b[2][i]);
        }
        printf("\n");
    }
    else
    {
        for(i=0;i<2*c;++i)
        {
            printf("%c", a[0][i]);
        }
        printf("\n");
        for(i=0;i<2*c;++i)
        {
            printf("%c", a[1][i]);
        }
        printf("\n");
        for(i=0;i<=2*c;++i)
        {
            printf("%c", b[0][i]);
        }
        printf("\n");
        for(i=0;i<=2*c;++i)
        {
            printf("%c", b[1][i]);
        }
        printf("\n");
        for(i=0;i<=2*c;++i)
        {
            printf("%c", b[0][i]);
        }
        printf("\n");

    }

    return(0);
}

REVOLUTION

Posted 2015-09-08T06:39:23.053

Reputation: 11

1

JavaScript (ES6), 128 bytes

n=>n?[...n<0?(n=1,'  -~-'):'$|-~-'].map((c,i)=>(i<2?' '+c:c).repeat(i<2?n:n*2+1)).join`
`:'Congratulations on your new baby! :D'

Demo

let f =

n=>n?[...n<0?(n=1,'  -~-'):'$|-~-'].map((c,i)=>(i<2?' '+c:c).repeat(i<2?n:n*2+1)).join`
`:'Congratulations on your new baby! :D'

console.log(f(-1));
console.log(f(0));
console.log(f(1));
console.log(f(2));

Arnauld

Posted 2015-09-08T06:39:23.053

Reputation: 111 334

0

Java 7, 197 198 bytes

String c(int y){String a=" ",b=a,c="---",n="\n";for(int i=0;i<y;a+="$ ",b+="| ")if(y>0&i++>0)c+="--";c=c+n+c.replace('-','~')+n+c;return y<0?c:y>0?a+n+b+n+c:"Congratulations on your new baby! :D";}

Ungolfed:

String c(int y){
   String a = " ",
          b = a,
          c = "---",
          n = "\n";
    for(int i = 0; i < y; a += "$ ",
                          b += "| "){
      if(y > 0 & i++ > 0){
        c += "--";
      }
    }
    c = c + n + c.replace('-', '~') + n + c;
    return y < 0
            ? c
            : y > 0
               ? a + n + b + n + c
               : "Congratulations on your new baby! :D";
  }

Test code:

Try it here.

class M{
  static String c(int y){String a=" ",b=a,c="---",n="\n";for(int i=0;i<y;a+="$ ",b+="| ")if(y>0&i++>0)c+="--";c=c+n+c.replace('-','~')+n+c;return y<0?c:y>0?a+n+b+n+c:"Congratulations on your new baby! :D";}

  public static void main(String[] a){
    System.out.println(c(1));
    System.out.println();
    System.out.println(c(3));
    System.out.println();
    System.out.println(c(25));
    System.out.println();
    System.out.println(c(0));
    System.out.println();
    System.out.println(c(-1));
  }
}

Output:

 $ 
 | 
---
~~~
---

 $ $ $ 
 | | | 
-------
~~~~~~~
-------

 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ 
 | | | | | | | | | | | | | | | | | | | | | | | | | 
---------------------------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---------------------------------------------------

Congratulations on your new baby! :D

---
~~~
---

Kevin Cruijssen

Posted 2015-09-08T06:39:23.053

Reputation: 67 575

0

ECMAScript 2015 – 134 bytes

n=>n?[' $'.repeat(n=(n>0)*n),' |'.repeat(n),d='-'.repeat(c=n?1+2*n:3),'~'.repeat(c),d].join`
`:'Congratulations on your new baby! :D'

Toothbrush

Posted 2015-09-08T06:39:23.053

Reputation: 3 197

0

Python 2, 131 bytes

x,y,n="$|-~-","  -~-",input()
for i in zip(y,*[y,y]*(n<0)+[x,y]*n)if n else["Congratulations on your new baby! :D"]:print"".join(i)

Happy belated birthday to OP :D Haven't been here in ages, I need to warm up my golfing skills again...using my favorite 90 degree list rotation trick with zip() here. The 0 case kinda threw me off, without it this code is 83 bytes.

As a bonus, taking the whitespace out of the y variable results in some interesting cake variations. Removing one space results in:

 $ $ $ $ $
-|-|-|-|-|-
~-~-~-~-~-~
-~-~-~-~-~-

and with the whitespace stripped entirely:

-$-$-$-$-$-
~|~|~|~|~|~
-----------

cjfaure

Posted 2015-09-08T06:39:23.053

Reputation: 4 213

Replace the second line with for i in(["Congratulations on your new baby! :D"],zip(y,*[y,y]*(n<0)+[x,y]*n))[n!=0]:print"".join(i). -1 bytes. – Erik the Outgolfer – 2016-09-13T18:10:20.940

0

C#, 467 Bytes

I know I won't win, but I think I at went overboard with while loops.

using System;class P{static void Main(string[]a){int i=int.Parse(a[0]);if(i==0){Console.Write("Congratulations on your new baby! :D");}else{int e=i;while(i-->0){Console.Write(" $");}if(e > 0){i = e;Console.Write("\n");while(i-- > 0){Console.Write(" |");}Console.Write("\n");i = e;} else {i=(e=1);}Console.Write("-");while(i-->0){Console.Write("--");}i=e;Console.Write("\n~");while(e-->0){Console.Write("~~");}Console.Write("\n-");while(i-->0){Console.Write("--");}}}}

Non minified version:

using System;
class P {
    static void Main(string[] a) {
        int i = int.Parse(a[0]);
        if(i == 0) {
            Console.Write("Congratulations on your new baby! :D");
        } else {
            int e = i;
            while(i-- > 0) {
                Console.Write(" $");
            }
            if(e > 0) {
                i = e;
                Console.Write("\n");
                while(i-- > 0) {
                    Console.Write(" |");
                }
                Console.Write("\n");
                i = e;
            } else {
                i = (e = 1);
            }
            Console.Write("-");
            while(i-- > 0) {
                Console.Write("--");
            }
            i = e;
            Console.Write("\n~");
            while(e-- > 0) {
                Console.Write("~~");
            }
            Console.Write("\n-");
            while(i-- > 0) {
                Console.Write("--");
            }
        }
    }
}

user41392

Posted 2015-09-08T06:39:23.053

Reputation:

0

C, 196 bytes

Prints leading spaces before empty candle cake. According to comments in the challenge, that's okay.

i,n;main(c,v)char**v;{c=atoi(v[1]);n=c<0;if(c)for(c=n?1:c;i++<10*c+10;)putchar(i%(2*c+2)?i<4*c+5?n|i%2?32:i<2*c+2?36:'|':i/(2*c+2)==3?'~':45:10);else puts("Congratulations on your new baby! :D");}

Ungolfed:

i,n;

int main(int c, char **v)
{
    c = atoi(v[1]);
    n = c < 0;
    if(c)
        for(c=n?3:c;i++<10*c+10;)
            putchar(i%(2*c+2) /* print '\n' at the end of each row */
                    ? i<4*c+5 /* first two rows are candles, last 3 are cake */
                        ? n || i % 2 /* alternate between space and candle */
                                ? ' '
                                : i<2*c+2 /* first row is '$', second is '|' */
                                    ? '$'
                                    : '|'
                        : i / (2*c+2) == 3 /* alternate rows between '-' and '~' */
                            ? '~'
                            : '-'
                    : '\n');
    else
        puts("Congratulations on your new baby! :D");
}

Cole Cameron

Posted 2015-09-08T06:39:23.053

Reputation: 1 013