# 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. Commented May 7, 2015 at 23:10
• @Jakube No. Trailing only. Commented May 7, 2015 at 23:12

# 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! Commented May 10, 2015 at 0:54
• I'm glad you ungolfed it. Those ternary ifs are insane!
– ldam
Commented May 15, 2015 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);}
– jdt
Commented May 8, 2017 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---
/|\
/ | \
/  |  \
$ • also, you actually can make that first bit a lot better using y: if we replace 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 with s/0//g;:w;y/987654321/87654321 /;s/[1-9]/& /g;tw it does the same thing Commented Apr 9 at 3:28 # 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. Commented May 7, 2015 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. :) Commented May 8, 2015 at 9:54 • It's still mighty impressive either way Commented May 8, 2015 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 :) Commented May 8, 2015 at 12:46 # 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  # 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. Commented May 7, 2015 at 23:57
• ternary operators is a good tip
– nick
Commented May 8, 2015 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":"";}} Commented May 8, 2015 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. Commented May 8, 2015 at 8:32
• @squeamishossifrage I never thought of that. Thanks for the tips! Commented May 8, 2015 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. Commented May 9, 2015 at 21:46
• @randomra That's clever, thanks. Down to two digits!
– xnor
Commented May 10, 2015 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. Commented Jun 12, 2015 at 13:45 # 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. Commented May 9, 2015 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 Commented May 9, 2015 at 14:38 • @lisa except that its not novel at all ;) . Also, it would break the leaderboard script if used in this challenge. Commented May 10, 2015 at 10:55 # 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. Commented May 8, 2015 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. Commented May 9, 2015 at 8:46 # 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
Commented May 9, 2015 at 0:05
• Maybe map(i#)[-n..n] to save two bytes.
– lynn
Commented May 11, 2015 at 17:17

# 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


# 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. Commented May 7, 2015 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. Commented May 8, 2015 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. Commented May 8, 2015 at 14:57
• nice, may steal your string building method. it annoys me that linq is longer than for loops :(
– Ewan
Commented May 8, 2015 at 15:17
• I've added the ungolfed version :) Commented May 8, 2015 at 15:59

# 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! Commented May 11, 2015 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." Commented May 8, 2015 at 14:55
• hahaha no worries :) Commented May 8, 2015 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=) Commented May 8, 2015 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! Commented May 11, 2015 at 11:36

# 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 (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 />');

a#b=2*a+0^b^2
f n|r<-[-n..n]=[[" /\\x-xOx|"!!mod(0#x#y#(x-y)#(x+y))9|x<-r]|y<-r]


Try it online!

# 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=<>). Commented May 8, 2015 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 Commented May 8, 2015 at 14:58 # Charcoal, 12 5 bytes Ｐ*⊕θO  -7 bytes thanks to @ASCII-only, by using the builtin :*. Explanation: Print the 8-armed lines with a length of the input+1 (the +1 is because the center is included), without moving the cursor position: MultiPrint(:*, Incremented(q)); Ｐ*⊕θ  Then print the "O" at the current location (still in the center, because we haven't moved due to the MultiPrint): Print("O"); O  • 5? Commented Jan 26, 2019 at 23:44 • @ASCII-only Thanks! Didn't even knew there was a :* builtin for this. Commented Jan 27, 2019 at 12:01 # Uiua, 46 44 … 35 34 bytes crossed out 44 is still regular 44 :( ⊏↧5/◇+\+{⇌,¤,⊞=.⟜=}⇡+1×2.:$  -\|/O


Try it! I submitted this on the day of the 2024 solar eclipse, which is fitting for a challenge about the sun. (Edit - the eclipse was beautiful! I saw it at around 85%-90% coverage)

Certainly my most well-golfed Uiua submission to-date. I have had a lot of different ideas and methods to save bytes and frequently switched much of the approach around a lot, but finally I have this at a state where I'd be happy if I don't find anything more.

Omnikar's very clever idea in the Uiua discord to use /+\+ instead of multiplying each term by a different factor helped me save 3 bytes! 38 → 35

## Explanation:

Note: This explanation is very slightly outdated, but the strategy is the same, just a few things shifted around.

Consider the input 3. We double this and add 1 to get the side length 7, and take the range from 0 up to it.

[0 1 2 3 4 5 6]


Underneath this we push a copy with a mask of where the original input appears, and a "fixed" (wrapped in an array) copy of that.

[0 0 0 1 0 0 0]    [[0 0 0 1 0 0 0]]    [0 1 2 3 4 5 6]


Using the range at the top of the stack, push the identity matrix and a reversed copy.

                                        [[1 0 0 0 0 0 0]   [[0 0 0 0 0 0 1]
[0 1 0 0 0 0 0]    [0 0 0 0 0 1 0]
[0 0 1 0 0 0 0]    [0 0 0 0 1 0 0]
[0 0 0 1 0 0 0]    [[0 0 0 1 0 0 0]]     [0 0 0 1 0 0 0]    [0 0 0 1 0 0 0]
[0 0 0 0 1 0 0]    [0 0 1 0 0 0 0]
[0 0 0 0 0 1 0]    [0 1 0 0 0 0 0]
[0 0 0 0 0 0 1]]   [1 0 0 0 0 0 0]]


Take their cumulative sums:

[[0 0 0 0 0 0 1]   [[1 0 0 0 0 0 1]   [[1 0 0 0 0 0 1]   [[1 0 0 1 0 0 1]
[0 0 0 0 0 1 0]    [0 1 0 0 0 1 0]    [0 1 0 0 0 1 0]    [0 1 0 1 0 1 0]
[0 0 0 0 1 0 0]    [0 0 1 0 1 0 0]    [0 0 1 0 1 0 0]    [0 0 1 1 1 0 0]
[0 0 0 1 0 0 0]    [0 0 0 2 0 0 0]    [1 1 1 3 1 1 1]    [1 1 1 4 1 1 1]
[0 0 1 0 0 0 0]    [0 0 1 0 1 0 0]    [0 0 1 0 1 0 0]    [0 0 1 1 1 0 0]
[0 1 0 0 0 0 0]    [0 1 0 0 0 1 0]    [0 1 0 0 0 1 0]    [0 1 0 1 0 1 0]
[1 0 0 0 0 0 0]]   [1 0 0 0 0 0 1]]   [1 0 0 0 0 0 1]]   [1 0 0 1 0 0 1]]


Notice that adding the fixed version of the list adds to each column, while the non-fixed version adds to each row.

Now, we sum the cumulative sums:

[[3 0 0 1 0 0 4]
[0 3 0 1 0 4 0]
[0 0 3 1 4 0 0]
[2 2 2 10 2 2 2]
[0 0 4 1 3 0 0]
[0 4 0 1 0 3 0]
[4 0 0 1 0 0 3]]


We’re going to index these numbers into a string to get each character, and that 10 is going to get in the way, so take the minimum of the results and 5:

[[3 0 0 1 0 0 4]
[0 3 0 1 0 4 0]
[0 0 3 1 4 0 0]
[2 2 2 5 2 2 2]
[0 0 4 1 3 0 0]
[0 4 0 1 0 3 0]
[4 0 0 1 0 0 3]]


Finally index these into a string so that 0 becomes a space, 1 becomes |, 2 becomes -, 3 becomes \, 4 becomes /, and 5 becomes O:

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


# 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
Commented May 8, 2015 at 2:31
• Oh, darn, I forgot to add that back in… Commented May 8, 2015 at 2:32
• (A=Array).from(A(m)) Commented May 8, 2015 at 2:42
• @MichaelT I fixed it, but I think I can golf it some more Commented May 8, 2015 at 3:17
• @Shmiddty thanks for the suggestion! that saved a lot of characters Commented May 8, 2015 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. Commented May 8, 2015 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". Commented May 8, 2015 at 18:34
• Edited again. Thanks @Sp3000 Commented May 8, 2015 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 Commented May 8, 2015 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.