Extendify the ASCII Sun

Write a program that takes in (via STDIN/command line) a non-negative integer N.

When N is 0, your program should print O (that's capital Oh, not zero).

When N is 1, your program should print

\|/
-O-
/|\


When N is 2 your program should print

\ | /
\|/
--O--
/|\
/ | \


When N is 3 your program should print

\  |  /
\ | /
\|/
---O---
/|\
/ | \
/  |  \


For larger N, this pattern continues on in the same exact fashion. Each of the eight rays of the "sun" should be made of N of the appropriate -, |, /, or \ characters.

Details

• Instead of a program, you may write a function that takes an integer. The function should print the sun design normally or return it as a string.

• You must either

• have no trailing spaces at all, or
• only have enough trailing spaces so the pattern is a perfect (2N+1)*(2N+1) rectangle.
• The output for any or all N may optionally have a trailing newline.

Scoring

The shortest code in bytes wins.

• Is a leading newline allowed? Especially interesting for N=0. – Jakube May 7 '15 at 23:10
• @Jakube No. Trailing only. – Calvin's Hobbies May 7 '15 at 23:12

Pyth, 3938 36 bytes

jbXmXXj\|m*\ Q2d\\_hd\/JhyQQX*\-JQ\O


Try it online: Pyth Compiler/Executor

Explanation

jbXmXXj\|m*\ Q2d\\_hd\/JhyQQX*\-JQ\O   implicit: Q = input
JhyQ            J = 1 + 2*Q
m                  J               map each d of [0,1,...,2*Q] to:
*\ Q                           " "*input
m    2                          list with twice " "*input
j\|                                join this list by "|"
X         d\\                       replace the value at d to "\"
X             _hd\/                  replace the value at -(d+1) to "/"
X                        Q           replace line Q by:
*\-J        "-"*J
X    Q\O     replace element at Q with "O"
jb                                     join by "newlines"


Another 36 bytes solution would be:

jbmXXj\|m*?\-KqdQ\ Q2d\\_hd?\OK\/hyQ


C: 116102999592 90

s(n){for(int c=-n,r=c;r<=n;c++)putchar(c>n?c=-c,r++,10:c?r?c-r?c+r?32:47:92:45:r?124:79);}


I think that I am getting fairly close to a minimal solution using this approach, but I can't stop feeling that there is a much better approach in C. Ungolfed:

void s(int n) {
for(
int c = -n, r = c;
r <= n;
c++
)
putchar(
c > n
? c = -c, r++, '\n'
: c
? r
? c - r
? c + r
? ' '
: '/'
: '\\'
: '-'
: r
? '|'
: 'O'
);
}

• "c++" in C ... heh! – bjb568 May 10 '15 at 0:54
• I'm glad you ungolfed it. Those ternary ifs are insane! – ldam May 15 '15 at 7:54
• You can save 2 more bytes and make it vc 2012 compliant ;) c,r;s(n){for(r=c=-n;r<=n;c++)putchar(c>n?c=-c,r++,10:c?r?c-r?c+r?32:47:92:45:r?124:79);} – Johan du Toit May 8 '17 at 10:57

GNU sed, 252 + 1

Phew - I beat the php answer!

Score + 1 for using the -r parameter.

Because of sed limitations, we have to burn nearly 100 bytes just convert N to a string of N spaces. The rest is the fun stuff.

/^0/{y/0/O/;q}
s/./<&/g
s/9/8 /g
s/8/7 /g
s/7/6 /g
s/6/5 /g
s/5/4 /g
s/4/3 /g
s/3/2 /g
s/2/1 /g
s/1/ /g
s/0//g
:t
s/ </<          /g
tt
s/<//g
:
s/ //
s^.*^\\&|&/^;ta
:a

Output

 $for i in {0..3}; do sed -rf asciisun.sed <<<$i ; done
O
\|/
-O-
/|\
\ | /
\|/
--O--
/|\
/ | \
\  |  /
\ | /
\|/
---O---
/|\
/ | \
/  |  \
$ J, 3734 40 bytes 1:echo('O\/-|'{.@#~0=+&|,-,+,[,])"*/~@i:  Usage:  (1:echo('O\/-|'{.@#~0=+&|,-,+,[,])"*/~@i:) 2 NB. prints to stdout: \ | / \|/ --O-- /|\ / | \  Explanation (from left to right): • i: generates list -n, -(n-1), ..., n-1, n • ( )"*/~@i: creates the Descartes product of i: with itself in a matrix arrangement, e.g. for n = 1 creates the following 3-by-3 matrix ┌─────┬────┬────┐ │-1 -1│-1 0│-1 1│ ├─────┼────┼────┤ │0 -1 │0 0 │0 1 │ ├─────┼────┼────┤ │1 -1 │1 0 │1 1 │ └─────┴────┴────┘  • for every matrix-element with integers x y we do the following • +&|,-,+,[,] calculate a list of properties • +&| abs(x)+abs(y), equals 0 iff (if and only if) x=0 and y=0 • - x-y, equals 0 iff x=y i.e. we are on the diagonal • + x+y, equals 0 iff x=-y i.e. we are on the anti-diagonal • [ x, equals 0 iff x=0 i.e. we are on the middle row • ] y, equals 0 iff y=0 i.e. we are on the middle column • 'O\/-|'#~0= compare these above property values to 0 and take the ith character from the string 'O\/-|' if the ith property is true. • the first character in the resulting string will always be the one we need, if there string is empty we need a space • {. takes the first character of a string and if there is no one it returns a space character as padding just as we need • we now have the exact matrix we need so we print it to stdout once with 1:echo Try it online here. • This is the ungolfed version?! I feel like a pretty average programmer at times, and then for some reason I end up on codegolf and see the stuff you guys pull off and can't help but feel like an idiot. – JustSid May 7 '15 at 22:56 • @JustSid Well, the text wasn't up to date with the code but technically I never wrote that the code is ungolfed. :) – randomra May 8 '15 at 9:54 • It's still mighty impressive either way – JustSid May 8 '15 at 10:05 • @JustSid Not that it's any less impressive but J code pretty much just looks like that, and this seems like a challenge that it would be a good language for. It's a very impressive answer, but so is everything else in J :) – undergroundmonorail May 8 '15 at 12:46 PHP, 182 bytes This seemed like a fun activity for my first answer. Comments on my code are welcome. <?php function s($n){$e=2*$n+1;for($i=0;$i<$e*$e;$i++){$x=$i%$e;$y=floor($i/$e);echo$y==$x?($x==$n?"O":"\\"):($e-1==$x+$y?"/":($y==$n?"-":($x==$n?"|":" ")));echo$x==$e-1?"\n":"";}}?>


Here is the un-golfed code with comments:

<?php
function s($n) {$e=2*$n+1; //edge length for($i=0;$i<$e*$e;$i++) {
$x =$i%$e; // current x coordinate$y = floor($i/$e); // current y coordinate

if ($y==$n&&$x==$n) {
// center of square
echo'O';
}
else if ($y==$n) {
// horizontal line
echo'-';
}
else if ($x==$n) {
// vertical line
echo'|';
}
else if ($y==$x) {
// diagonal line from top-left to bottom right
echo'\\';
}
else if (($y-$n)==($n-$x)) {
// diagonal line from bottom-left to top-right
echo'/';
}
else {
// empty space
echo' ';
}
if ($x==$e-1) {
// add new line for the end of the row
echo"\n";
}
}
}?>
<pre>
<?php s(10); ?>
</pre>


Edited with code by royhowie

• Hi :-) Good first effort. You can shrink your code in quite a few places though. For example if(($y-$h)==($x-$h)) does the same as if(($y==$x). You can save another character by replacing if($x==y$)foo();else bar(); with if($x^$y)bar();else foo();. You should also try using ternary operators instead of if .. else statements. – r3mainer May 7 '15 at 23:57
• ternary operators is a good tip – nick May 8 '15 at 2:33
• 174 bytes: function s($n){$e=2*$n+1;for($i=0;$i<$e*$e;$i++){$x=$i%$e;$y=floor($i/$e);echo$y==$x?($x==$n?"O":"\\"):($e-1==$x+$y?"/":($y==$n?"-":($x==$n?"|":" ")));echo$x==$e-1?"\n":"";}} – royhowie May 8 '15 at 8:30 • 1. there's no need for $r; just use echo ($r.= is the same amount of bytes as echo). 2. used ternary operator (saves a lot of characters). 3. $h was useless since it equaled $n. 4. You didn't need to use floor for $x = floor($i%$e);, since a modulus on an integer won't need to be rounded down. – royhowie May 8 '15 at 8:32
• @squeamishossifrage I never thought of that. Thanks for the tips! – Kodos Johnson May 8 '15 at 16:45

Python 2, 99

n=input()
R=range(-n,n+1)
for i in R:print''.join("O\|/ -"[[R,i,0,-i,j].index(j)^(i==0)]for j in R)


Prints line by line, creating each line by checking whether the coordinate (i,j) (centered at (0,0)) satisfies j==-i, j==0, j==i, or none, with a hack to make the center line work.

• I think you can use R instead of .5 to save 1 byte. – randomra May 9 '15 at 21:46
• @randomra That's clever, thanks. Down to two digits! – xnor May 10 '15 at 0:04

CJam, 48 45 43 41 38 bytes

This is still too long and I am still doing some redundant things, but here goes:

ri:R{_S*"\|/"@R-~S**1$N}%'-R*'O1$W$sW%  Try it online here SpecBAS - 117 bytes 1 INPUT s: LET t=s*2: FOR y=0 TO t: PRINT AT y,y;"\";AT y,t/2;"|";AT t-y,y;"/";AT t/2,y;"-": NEXT y: PRINT AT s,s;"O"  This prints the slashes and dashes in one loop, and then plonks the "O" in the middle. Output using 1, 2 and 9 • An anonymous user suggested to change "-": NEXT y: PRINT AT s,s;"O" to "-";AT s,s;"O": NEXT y to save two bytes. – Martin Ender Jun 12 '15 at 13:45 JavaScript (ES6) 97 98 This seems different enough ... // GOLFED f=n=>(y=>{for(t='';++y<n;t+='\n')for(x=-n;++x<n;)t+='-O /\\|'[y?x?x-y?x+y?2:3:4:5:+!x]})(-++n)||t // Ungolfed F=n=>{ ++n; t = ''; for (y = -n; ++y < n; t += '\n') for (x = -n; ++x < n; ) if (y != 0) if (x != 0) if (x != y) if (x != -y) t += ' ' else t += '/' else t += '\\' else t += '|' else if (x != 0) t += '-' else t += 'O' return t; } // TEST function test(){ OUT.innerHTML = f(N.value|0); } test() input { width: 4em } N: <input id=N value=5><button onclick="test()">Go</button> <pre id="OUT"></pre> • Beautiful. I should have thought of a closure to use normal for loops. – nderscore May 8 '15 at 16:18 • I like this one. I had tried writing one using a string and accessing a specific index, but yours is much shorter. – royhowie May 9 '15 at 8:46 OS/2 Classic Rexx, 102... or 14 for "cheater's version" Take out the linefeeds to "golf" it. w='%1' o=center('O',w,'-') m='center(space("\|/",w),%1)' do w w=w-1 interpret "o="m"|o|"m end l say o  Cheater's version, name the script whatever source code you want under 255 characters (requires HPFS disk): interpret '%0'  EDIT: Just to be clear, cheater's version isn't intended to count! It's just to be silly and show an old dog can still do tricks. :) e.g. For real fun and games, an implementation of Java-8/C11 style "lambda" expressions on a list iterator. Not tested, but ought to run on a circa 1979 IBM mainframe. ;) ForEachInList( 'Months.January.Days', 'Day' -> 'SAY "You have an appointment with" Day.Appointment.Name "on" Day.Appointment.Date' ) EXIT ForEachInList: SIGNAL ON SYNTAX PARSE ARG MyList "," MyVar "->" MyCommand INTERPRET ' MyListCount = ' || MyList || '.Count' DO ListIndex = 1 TO MyListCount INTERPRET MyVar || ' = ' || MyList || '.' || ListIndex INTERPRET MyCommand END RETURN SYNTAX: SAY MyCommand ' is not a valid expression. ' EXIT  -- Calling code assumes you already made a stem (array), naturally. • For your cheater version: if the filename of a program is not arbitrary, it has to be included in the byte count. – Martin Ender May 9 '15 at 9:51 • Fair enough. Cheater's version wasn't intended as at all serious! :) ...which is why I posted the "real" answer at 102. It was just for novelty's sake. – lisa May 9 '15 at 14:38 • @lisa except that its not novel at all ;) . Also, it would break the leaderboard script if used in this challenge. – Optimizer May 10 '15 at 10:55 Haskell, 10998 96 bytes Thanks to nimi and Mauris for their help! 0#0='O' 0#_='-' _#0='|' i#j|i==j='\\'|i== -j='/'|1<2=' ' f n=unlines[map(i#)[-n..n]|i<-[-n..n]]  Explanation: The operator # specifies which character appears at coordinates (i,j), with the sun centered at (0,0). Function f builds the result String by mapping # over all pairs of coordinates ranging from -n to n. Usage: ghci> putStr$ f 2
\ | /
\|/
--O--
/|\
/ | \

• You can save a few bytes by using an infix operator instead of s, e.g. 0#0='O', 0#_='-', etc. and 1<2 instead of True. – nimi May 9 '15 at 0:05
• Maybe map(i#)[-n..n] to save two bytes. – Lynn May 11 '15 at 17:17

R, 177 149 bytes

Mickey T. is the man! He helped me fix my originally incorrect solution and save 28 bytes. Thanks, Mickey!

m=matrix(" ",(w=2*(n=scan()+1)-1),w);m[row(m)==rev(col(m))]="/";diag(m)="\\";m[,n]="|";m[n,]="-";m[n,n]="O";m[,w]=paste0(m[,w],"\n");cat(t(m),sep="")


Ungolfed + explanation:

# Create a matrix of spaces, read n from stdin, assign w=2n+1
m <- matrix(" ", (w <- 2*(n <- scan() + 1) - 1), w)

# Replace the opposite diagonal with forward slashes
m[row(m) == rev(col(m))] <- "/"

# Replace the diagonal with backslashes
diag(m) <- "\\"

# Replace the vertical center line with pipes
m[, n] <- "|"

# Replace the horizontal center line with dashes
m[n, ] <- "-"

# Put an O in the middle
m[n, n] <- "O"

# Collapse the columns into single strings
m[, w] <- paste0(m[, w], "\n")

# Print the transposed matrix
cat(t(m), sep = "")


Any further suggestions are welcome!

• Sorry Alex, you missed the vertical rays. There is a few things that could be changed to shorten this without changing the general process. The scan doesn't really need the w=. It can also be shifted deeper into the commands. The if can be ditched if you change the way the matrix is handled in a couple of instances. Applying these I get m=matrix(" ",(w=2*(n=scan()+1)-1),w);m[row(m)-rev(col(m))==0]='/';diag(m)="\\";m[,n]='|';m[n,]="-";m[n,n]="O";m[,w]=paste0(m[,w],'\n');cat(t(m),sep=''). Further golfing possible I think. – MickyT May 7 '15 at 23:44
• @MickyT: That's fantastic. Thank you so much for noticing my mistake and proving a much better solution! I edited the answer. – Alex A. May 8 '15 at 1:05

C#, 230 226 bytes

string g(int n){string r="";int s=n*2+1;for(int h=0;h<s;h++){for(int w=0;w<s;w++){if(h==w){if(w==n){r+="O";}else{r+="\\";}}else if(w==s-h-1){r+="/";}else if(w==n){r+="|";}else if(h==n){r+="-";}else{r+=" ";}}r+="\n";}return r;}


As requested, the ungolfed version: string ug(int n) {

        // The sting we'll be returning
string ret = "";

// The width and height of the output
int s = n * 2 + 1;

// for loop for width and height
for (int height = 0; height < s; height++)
{
for (int width = 0; width < s; width++)
{
// Matches on top-left to bottom-right diagonal line
if (height == width)
{
// If this is the center, write the 'sun'
if (width == n)
{
ret += "O";
}
// If this is not the center, add the diagonal line character
else
{
ret += "\\";
}
}
// Matches on top-right to bottom-left diagonal line
else if (width == s - height - 1)
{
ret += "/";
}
// Matches to add the center line
else if (width == n)
{
ret += "|";
}
// Matches to add the horizontal line
else if (height == n)
{
ret += "-";
}
// Matches all others
else
{
ret += " ";
}
}
// Add a newline to separate each line
ret += "\n";
}
return ret;
}


This is my first post so apologies if I've done something wrong. Any comments and corrections are very welcome.

• Also, s=2*n+1 rather than s=(n*2)+1 and w==s-h-1 rather than w==(s-h)-1 will make this a little shorter. – Alex A. May 8 '15 at 14:57
• nice, may steal your string building method. it annoys me that linq is longer than for loops :( – Ewan May 8 '15 at 15:17
• I've added the ungolfed version :) – Transmission May 8 '15 at 15:59

Ruby: 98 92 characters

Proc that returns a string with the Sun.

f=->n{x=(0..m=n*2).map{|i|s=?|.center m+1
s[i]=?\\
s[m-i]=?/
s}
x[n]=?O.center m+1,?-
x*?\n}


Sample run:

irb(main):001:0> f=->n{x=(0..m=n*2).map{|i|s=?|.center m+1;s[i]=?\\;s[m-i]=?/;s};x[n]=?O.center m+1,?-;x*?\n}
=> #<Proc:0x000000020dea60@(irb):1 (lambda)>
irb(main):002:0> (0..3).each {|i| puts f[i]}
O
\|/
-O-
/|\
\ | /
\|/
--O--
/|\
/ | \
\  |  /
\ | /
\|/
---O---
/|\
/ | \
/  |  \
=> 0..3


Rust, 215 characters

fn a(n:usize){for i in 0..n{println!("{}\\{}|{1}/{0}",s(i),s(n-i-1))}println!("{}O{0}",vec!["-";n].concat());for i in(0..n).rev(){println!("{}/{}|{1}\\{0}",s(i),s(n-i-1))}}fn s(n:usize)->String{vec![" ";n].concat()}


I tried to use a string slicing method (by creating a string of n-1 spaces and slicing to and from an index) like so:

fn a(n:usize){let s=vec![" ";n-(n>0)as usize].concat();for i in 0..n{println!("{}\\{}|{1}/{0}",&s[..i],&s[i..])}println!("{}O{0}",vec!["-";n].concat());for i in(0..n).rev(){println!("{}/{}|{1}\\{0}",&s[..i],&s[i..])}}


But that's actually 3 chars longer.

Ungolfed code:

fn asciisun_ungolfed(n: usize) {
for i in 0..n {
println!("{0}\\{1}|{1}/{0}", spaces(i), spaces(n-i-1))
}
println!("{0}O{0}", vec!["-"; n].concat());
for i in (0..n).rev() {
println!("{0}/{1}|{1}\\{0}", spaces(i), spaces(n-i-1))
}
}
fn spaces(n: usize) -> String { vec![" "; n].concat() }


The part I like is how I shave a few chars off on the formatting strings. For example,

f{0}o{1}o{1}b{0}ar


is equivalent to

f{}o{}o{1}b{0}ar


because the "auto-incrementer" for the format string argument position is not affected by manually specifying the number, and acts completely independently.

Octave 85

Bulding matrices as always=) eye produces an identity matrix, the rest is self explanatory I think.

m=(e=eye(2*(k=input('')+1)-1))*92+rot90(e)*47;m(:,k)='|';m(k,:)=45;m(k,k)='o';[m,'']

• Still two bytes better than mine :( I actually tried something similar to this initially, but couldn't get it small enough - I didn't realize I could do "m(:,k)='|'". Nice submission! – Oebele May 11 '15 at 11:41

IDL 8.3, 135 bytes

Dunno if this can be golfed more... It's very straightforward. First we create a m x m array (m=2n+1) of empty strings; then, we draw the characters in lines (y=x, y=-x, y=n, and x=n). Then we drop the O in at point (n, n), and print the whole thing, formatted as m strings of length 1 on each line so that there's no extra spacing from printing the array natively.

pro s,n
m=2*n+1
v=strarr(m,m)
x=[0:m-1]
v[x,x]='\'
v[x,m-x-1]='/'
v[n,x]='|'
v[x,n]='-'
v[n,n]='O'
print,v,f='('+strtrim(m,2)+'A1)'
end


Test:

IDL> s,4
\   |   /
\  |  /
\ | /
\|/
----O----
/|\
/ | \
/  |  \
/   |   \

• "Instead of a program, you may write a function that takes an integer. The function should print the sun design normally or return it as a string." – sirpercival May 8 '15 at 14:55
• hahaha no worries :) – sirpercival May 8 '15 at 15:07

Matlab, 93 87 bytes

Sadly the function header has to be so big... Apart from that I think it is golfed pretty well. I wonder if it could be done better with some of the syntax differences in Octave.

N=input('');E=eye(N)*92;D=rot90(E)*.52;H=ones(1,N)*45;V=H'*2.76;[E V D;H 79 H;D V E '']

• You can just make a program with N=input('') to save 2 characters. Other than that you can just write [E V D;H 79 H;D V E ''] for converting the whole matrix into a char array, which will save you another byte or two. ( I just submitted an Octave program with a slightly different approach, but before I found yours=) – flawr May 8 '15 at 21:15
• I actually had the input line first, but for some reason I mistakenly thought it wasn't allowed... Thanks for the other tip though! – Oebele May 11 '15 at 11:36

Javascript (ES7 Draft) 115

f=l=>[['O |/\\-'[y^x?z+~x^y?y^l?x^l?1:2:5:3:x^l&&4]for(x in _)].join('')for(y in _=[...Array(z=2*l+1)])].join('\n')

// Snippet demo: (Firefox only)
for(var X of [0,1,2,3,4,5])
document.write('<pre>' + f(X) + '</pre><br />');

Pyth - 52 bytes

The hard part was figuring out how to switch the slashes for each side. I settled for defining a lambda that takes the symbols to use.

KdMms[*Kt-QdG*Kd\|*KdH)_UQjbg\\\/p\O*Q\-*\-Qjb_g\/\\


Can likely be golfed more, explanation coming soon.

Perl, 94

There are a lot of nested ternary operators in here, but I think the code is reasonably straightforward.

$n=<>;for$x(-$n..$n){for$y(-$n..$n){print$x^$y?$x+$y?$x?$y?$":'|':'-':'/':$x?'\\':'O'}print$/}


Try it out here: ideone.com/E8MC1d

• 88B: for$x(-($n=<>)..$n){map{print$x^$_?$x+$_?$x?$_?$":'|':'-':'/':$x?'\\':O}-$n..$n;print$/} - A couple of tweaks: convert inner for to map and change $y to$_; inline ($n=<>). – alyx-brett May 8 '15 at 10:09 C# - 291 (full program) using System;using System.Linq;class P{static void Main(string[] a){Func<int,int,int,char>C=(s,x,i)=>x==(2*s+1)?'\n':i==s?x==s?'O':'-':x==s?'|':x==i?'\\':x==2*s-i?'/':' ';int S=int.Parse(a[0])*2;Console.Write(Enumerable.Range(0,(S+1)*(S+1)+S).Select(z=>C(S/2,z%(S+2),z/(S+2))).ToArray());}}  • working on it!! – Ewan May 8 '15 at 14:58 JavaScript (ES6), 139135 140 + 1 bytes (+1 is for -p flag with node in the console) fixed: t=(n,m)=>(m=2*n+1,(A=Array).from(A(m),(d,i)=>A.from(A(m),(e,j)=>i==j?j==n?"O":"\\":m-1==j+i?"/":i==n?"-":j==n?"|":" ").join("")).join("\n"))  usage: t(3) /* \ | / \ | / \|/ ---O--- /|\ / | \ / | \ */  ungolfed: var makeSun = function (n, m) { m = 2 * n + 1; // there are 2*n+1 in each row/column return Array.from(Array(m), function (d, i) { return Array.from(Array(m), function (e, j) { // if i is j, we want to return a \ // unless we're at the middle element // in which case we return the sun ("O") if (i == j) { return j == n ? "O" : "\\"; // the other diagonal is when m-1 is j+i // so return a forward slash, / } else if (m - 1 == j + i) { return "/"; // the middle row is all dashes } else if (i == n) { return "-"; // the middle column is all pipes } else if (j == n) { return "|"; // everything else is a space } else { return " "; } }).join(""); }).join("\n"); }  • You appear to be missing two rays. – user12166 May 8 '15 at 2:31 • Oh, darn, I forgot to add that back in… – royhowie May 8 '15 at 2:32 • (A=Array).from(A(m)) – Shmiddty May 8 '15 at 2:42 • @MichaelT I fixed it, but I think I can golf it some more – royhowie May 8 '15 at 3:17 • @Shmiddty thanks for the suggestion! that saved a lot of characters – royhowie May 8 '15 at 3:27 Python 3, 193 186 bytes Golfed def f(n): s,b,e,d,g=' \\/|-';p,r,i='',int(n),0 while r:print(s*i+b+s*(r-1)+d+s*(r-1)+e);r-=1;i+=1 print(g*n+'O'+g*n);r+=1;i=n-1 while r<n+1:print(s*i+e+s*(r-1)+d+s*(r-1)+b);r+=1;i-=1  Output >>> f(3) \ | / \ | / \|/ ---O--- /|\ / | \ / | \ >>> f(5) \ | / \ | / \ | / \ | / \|/ -----O----- /|\ / | \ / | \ / | \ / | \  Ungolfed def f(n): s, b, e, d, g = ' \\/|-' p, r, i = '', int(n), 0 while r: print(s*i + b + s*(r-1) + d + s*(r-1) + e) r -= 1 i += 1 print(g*n + 'O' + g*n) r += 1 i = n-1 while r < n+1: print(s*i + e + s*(r-1) + d + s*(r-1) + b) r += 1 i -= 1  • There's a few things to be golfed here, but the biggest one is your default arguments. s=' ',b='\\',f='/',d='|',g='-' is very long, so you'd be better off moving it by adding s,b,f,d,g=" \/|-" to the second line. – Sp3000 May 8 '15 at 18:28 • I meant " \/|-" as a single string, rather than splitting it up into individual chars. You can unpack from a string like x,y,z="123", which makes x="1", y="2" and z="3". – Sp3000 May 8 '15 at 18:34 • Edited again. Thanks @Sp3000 – Zach Gates May 8 '15 at 18:39 CJam, 59 55 bytes ri:A,W%{_S*"\|/"\*\A\-(S*_@@++}%_Wf%W%['-A*_'O\++]\++N*  This won't win any awards as-is but I was happy enough it worked! Thanks to Sp3000 for golfing tips. • Nice work! Here's a few tips: 1) You can use S instead of the ' version for space and 2) For '-A*'O'-A you can do '-A*_'O\ instead because generating it twice is long – Sp3000 May 8 '15 at 19:46 Python, 175 129 127 125 Bytes s,q,x=' ','',int(input()) for i in range(x):d=(x-i-1);q+=(s*i+'\\'+s*d+'|'+s*d+'/'+s*i+'\n') print(q+'-'*x+'O'+'-'*x+q[::-1])  Try it online here. Ruby - 130 bytes def f(n);a=(0...n).map{|i|' '*i+"\\"+' '*(n-1-i)+'|'+' '*(n-1-i)+'/'+' '*i};puts(a+['-'*n+'O'+'-'*n]+a.reverse.map(&:reverse));end  usage: irb(main):002:0> f(3) \ | / \ | / \|/ ---O--- /|\ / | \ / | \  • Applied a couple of old trick: f=->n{a=(0...n).map{|i|(s=' ')*i+?\\+s*(m=n-1-i)+?|+s*(m)+?/+s*i};puts(a+[?-*n+'O'+?-*n]+a.reverse.map(&:reverse))} (See Tips for golfing in Ruby for some more.) – manatwork May 8 '15 at 16:22 Perl 85919089 86B map{$_=$r||O;s/^|$/ /mg;s/ (-*O-*) /-$1-/;$r="\$s|s/ _ /s|s\\";s.="}1..<>;sayr  Ungolfed: # usage: echo 1|perl sun.pl map { _ = r || O; # no strict: o is "o". On the first run r is not defined s/^|/ /mg; # overwriting _ saves characters on these regexes s/ (-*O-*) /-1-/; r = "\$s|$s/$_
/$s|$s\\";         # Embedded newlines save 1B vs \n. On the first run $s is not defined.$s .= $" } 1..<>; say$r


Prolog, 219 bytes

No, it's not much of a golfing language. But I think this site needs more Prolog.

s(N,N,N,79).
s(R,R,_,92).
s(R,C,N,47):-R+C=:=2*N.
s(N,_,N,45).
s(_,N,N,124).
s(_,_,_,32).
c(_,C,N):-C>2*N,nl.
c(R,C,N):-s(R,C,N,S),put(S),X is C+1,c(R,X,N).
r(R,N):-R>2*N.
r(R,N):-c(R,0,N),X is R+1,r(X,N).
g(N):-r(0,N).


Tested with swipl on Linux. Invoke like so: swipl -s asciiSun.prolog; then query for your desired size of sun:

?- g(3).
\  |  /
\ | /
\|/
---O---
/|\
/ | \
/  |  \
true .


Ungolfed:

 % Args to sym/4 are row, column, N and the character code to be output at that location.
sym(N,N,N,79).
sym(R,R,_,'\\').
sym(R,C,N,'/') :- R+C =:= 2*N.
sym(N,_,N,'-').
sym(_,N,N,'|').
sym(_,_,_,' ').

% Args to putCols/3 are row, column, and N.
% Recursively outputs the characters in row from col onward.
putCols(_,C,N) :- C > 2*N, nl.
putCols(R,C,N) :- sym(R,C,N,S), put_code(S), NextC is C+1, putCols(R,NextC,N).

% Args to putRows/2 are row and N.
% Recursively outputs the grid from row downward.
putRows(R,N) :- R > 2*N.
putRows(R,N) :- putCols(R,0,N), NextR is R+1, putRows(NextR,N).

putGrid(N) :- putRows(0,N).


JavaScript (ES6), 142140134 117 bytes

n=>(g=x=>x?${t= [r=repeat](n-x--)}\${s= [r](x)}|{s}/{t} +g(x):-[r](n))(n)+O+[...g(n)].reverse().join  Try It f= n=>(g=x=>x?{t= [r=repeat](n-x--)}\${s= [r](x)}|${s}/\${t}
+g(x):-[r](n))(n)+O+[...g(n)].reverse().join
o.innerText=f(i.value=1)
<input id=i type=number><pre id=o>