| Bytes | Lang | Time | Link |
|---|---|---|---|
| 162 | AWK | 250411T205038Z | xrs |
| 056 | Vyxal | 210530T060043Z | emanresu |
| 052 | Canvas | 201105T065102Z | Razetime |
| 075 | CJam | 150908T065038Z | Dennis |
| 044 | 05AB1E | 190909T155904Z | Grimmy |
| 162 | Zsh | 190910T114039Z | roblogic |
| 087 | K ngn/k | 190910T094106Z | scrawl |
| 185 | PHP | 170111T121753Z | Starx |
| 046 | Jelly | 180126T213355Z | ellie |
| 197 | Java 7 | 170111T143232Z | Kevin Cr |
| 128 | JavaScript ES6 | 161110T144602Z | Arnauld |
| 260 | Ceylon | 150908T203459Z | Paŭlo Eb |
| 729 | C | 150921T105558Z | REVOLUTI |
| 221 | ScriptCS C# script | 150916T001006Z | Justin D |
| 196 | C | 150914T152010Z | Cole Cam |
| 126 | Powershell | 150909T222049Z | Justin D |
| 467 | C# | 150912T152641Z | user4139 |
| 167 | MATLAB / Octave | 150908T210500Z | rayryeng |
| 131 | Python 2 | 150911T115224Z | cjfaure |
| 242 | bash | 150910T124634Z | Tarod |
| nan | Pip | 150911T005012Z | DLosc |
| 392 | C | 150910T225517Z | Funmungu |
| 229 | D | 150909T163644Z | sigod |
| 136 | JavaScript ES6 | 150908T143825Z | edc65 |
| 134 | ECMAScript 2015 – | 150910T112322Z | Toothbru |
| 160 | CoffeeScript | 150910T112444Z | Bojidar |
| 567 | pb | 150910T023020Z | undergro |
| 164 | Mathematica | 150909T143643Z | Charlott |
| 117 | Perl | 150908T162821Z | phillipo |
| 150 | Python 2 | 150908T141519Z | Blex |
| 299 | Lua | 150908T091733Z | FabiF |
| 221 | R | 150908T095058Z | Tensibai |
| 157 | R | 150908T231622Z | flodel |
| 141 | Moonscript | 150908T214053Z | Ryan Rus |
| 143 | Julia | 150908T192039Z | Alex A. |
| 161 | Mouse | 150908T185651Z | Alex A. |
| 113 | golflua | 150908T195836Z | manatwor |
| 153 | JavaScript | 150908T134614Z | Nainemom |
| 169 | Python 3 | 150908T184100Z | moorecm |
| 164 | SpecBAS | 150908T161843Z | Brian |
| 187 | Lua 5.2 | 150908T152059Z | Jakuje |
| 154 | JavaScript ES6 | 150908T081344Z | Qwertiy |
| 117 | rs | 150908T142553Z | kirbyfan |
| 120 | Ruby | 150908T074922Z | Level Ri |
| 144 | Perl | 150908T115009Z | r3mainer |
| 158 | Python 2 | 150908T104444Z | SimonPJ |
| 279 | R | 150908T090047Z | Cath |
| 067 | Pyth | 150908T072813Z | PurkkaKo |
AWK, 169 162 bytes
!$1{print"Congratulations on your new baby! :D"}$1{for($1<0&&x=$1=1;k++<=$1*2;k<=$1&&s=s" $"){k>$1&&k<=$1*2&&r=r" |";p=p"~";t=t"-"}print!x?s"\n"r:X}$0=t"\n"p"\n"t
!$1{print # if input is zero print
"Congratulations on your new baby! :D"}
$1{ # if non-zero
if($1<0) # if negative
{$1=1;x++} # set size to one and flag
for(;k++<=(z=$1*2); # cake is twice as long as candles
k<=$1&&s=s" $") # append flames
{k>$1&&k<=z&&r=r" |"; # append candles
p=p"~"; # middle of cake
t=t"-"} # top and bottom of cake
print!x?s"\n"r:X} # if flag not set print candles
$0=t"\n"p"\n"t # print base of cake
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 otherwise.
05AB1E, 45 44 bytes
_i“Ûà€‰€ž€¢‡Í! :D“ćuìëdiU„ $„ |}…-~-`)X·>δ∍»
_i # if input != 0:
“Ûà€‰€ž€¢‡Í! :D“ # dictionary string "congratulations on your new baby! :D"
ćuì # uppercase the first character
ë # 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
Zsh, 162 bytes
((!$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"
K (ngn/k), 87 bytes
{$[x<0;3#'2_*:;x;,'/(1+2*x)#;:"Congratulations on your new baby! :D"](" -~-";"$|-~-")}
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"](" -~-";"$|-~-")}
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";
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:
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
---
~~~
---
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));
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.
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);
}
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)))))
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");
}
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'}
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("--");
}
}
}
}
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.
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:
-$-$-$-$-$-
~|~|~|~|~|~
-----------
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`
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"
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?
Ifais truthy (i.e. not zero):a<0?yX3
Ifais negative, returnywith each element repeated 3 times:["---";"~~~";"---"]- Else (
ais positive):(s.^"$|")Xa
Split"$|"into a list of characters, prepend a space (s) to each, and repeat each resulting elementatimesyX2*a+1
Repeat each element ofy2*a+1timesAL
Append the two lists
- Else (
ais 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!
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 ( "--", "-" )
}
}
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
;
}
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);
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'
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!
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]
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"
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-'
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 :(
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
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")}
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,"")
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'~'
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
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.
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
---
~~~
---
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'
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))
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
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 :)
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)
rs, 117 bytes
^0$/Congratulations on your new baby! :D
-.+/-1
$$r=)^^(\1)\n
$$m=-(--)^^(\1)\n
(\d+)/ ($ $r (| $r$m~(~~$r$m
^-[^-]+/
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.
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"
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
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=""))}
}
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