43
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ Is a leading newline allowed? Especially interesting for N=0. \$\endgroup\$
    – Jakube
    May 7, 2015 at 23:10
  • \$\begingroup\$ @Jakube No. Trailing only. \$\endgroup\$ May 7, 2015 at 23:12

39 Answers 39

26
\$\begingroup\$

C: 116 102 99 95 92 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'
    );
}
\$\endgroup\$
3
  • 7
    \$\begingroup\$ "c++" in C ... heh! \$\endgroup\$
    – bjb568
    May 10, 2015 at 0:54
  • \$\begingroup\$ I'm glad you ungolfed it. Those ternary ifs are insane! \$\endgroup\$
    – ldam
    May 15, 2015 at 7:54
  • \$\begingroup\$ 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);} \$\endgroup\$
    – jdt
    May 8, 2017 at 10:57
21
\$\begingroup\$

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
/\\$/q
p
s^\\\|/^-O-^;tn
s^(\\)? (/)?^\2 \1^g;ta
:n
y/ /-/
p
s^-O-^/|\\^
y/-/ /
ta

Explanation

  • The first line is an early exit for the N=0 case.
  • The next 15 lines (up to the :) convert N to a string of N spaces
  • s/ // removes one space
  • s^.*^\\&|&/^;ta converts N-1 spaces to: \ + N-1 spaces + | + N-1 spaces + /
  • Iterate, printing each iteration, and moving \ one space to the right and / one space to the left...
  • ...until we match \|/, which is replaced with -O- and jump to the n label
  • replace with - and print
  • replace -0- with /|\, and replace with - and jump back into the main loop
  • Iterate, printing each iteration, and moving \ one space to the right and / one space to the left...
  • ...until we match \$ which indicates were finished, and quit.

Output

 $ for i in {0..3}; do sed -rf asciisun.sed <<< $i ; done
 O
 \|/
 -O-
 /|\
 \ | /
  \|/ 
 --O--
  /|\ 
 / | \
 \  |  /
  \ | / 
   \|/  
 ---O---
   /|\  
  / | \ 
 /  |  \
 $
\$\endgroup\$
16
\$\begingroup\$

J, 37 34 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.

\$\endgroup\$
4
  • 5
    \$\begingroup\$ 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. \$\endgroup\$
    – JustSid
    May 7, 2015 at 22:56
  • \$\begingroup\$ @JustSid Well, the text wasn't up to date with the code but technically I never wrote that the code is ungolfed. :) \$\endgroup\$
    – randomra
    May 8, 2015 at 9:54
  • \$\begingroup\$ It's still mighty impressive either way \$\endgroup\$
    – JustSid
    May 8, 2015 at 10:05
  • 2
    \$\begingroup\$ @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 :) \$\endgroup\$ May 8, 2015 at 12:46
12
\$\begingroup\$

Pyth, 39 38 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
\$\endgroup\$
11
\$\begingroup\$

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

\$\endgroup\$
13
  • 3
    \$\begingroup\$ 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. \$\endgroup\$
    – r3mainer
    May 7, 2015 at 23:57
  • \$\begingroup\$ ternary operators is a good tip \$\endgroup\$
    – nick
    May 8, 2015 at 2:33
  • \$\begingroup\$ 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":"";}} \$\endgroup\$
    – royhowie
    May 8, 2015 at 8:30
  • \$\begingroup\$ 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. \$\endgroup\$
    – royhowie
    May 8, 2015 at 8:32
  • \$\begingroup\$ @squeamishossifrage I never thought of that. Thanks for the tips! \$\endgroup\$ May 8, 2015 at 16:45
9
+100
\$\begingroup\$

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.

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

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

\$\endgroup\$
7
\$\begingroup\$

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

enter image description here

\$\endgroup\$
1
  • \$\begingroup\$ An anonymous user suggested to change "-": NEXT y: PRINT AT s,s;"O" to "-";AT s,s;"O": NEXT y to save two bytes. \$\endgroup\$ Jun 12, 2015 at 13:45
7
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\begingroup\$ For your cheater version: if the filename of a program is not arbitrary, it has to be included in the byte count. \$\endgroup\$ May 9, 2015 at 9:51
  • \$\begingroup\$ 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. \$\endgroup\$
    – lisa
    May 9, 2015 at 14:38
  • \$\begingroup\$ @lisa except that its not novel at all ;) . Also, it would break the leaderboard script if used in this challenge. \$\endgroup\$
    – Optimizer
    May 10, 2015 at 10:55
7
\$\begingroup\$

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>

\$\endgroup\$
2
  • \$\begingroup\$ Beautiful. I should have thought of a closure to use normal for loops. \$\endgroup\$
    – nderscore
    May 8, 2015 at 16:18
  • \$\begingroup\$ I like this one. I had tried writing one using a string and accessing a specific index, but yours is much shorter. \$\endgroup\$
    – royhowie
    May 9, 2015 at 8:46
6
\$\begingroup\$

Haskell, 109 98 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--
 /|\ 
/ | \
\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$
    – nimi
    May 9, 2015 at 0:05
  • \$\begingroup\$ Maybe map(i#)[-n..n] to save two bytes. \$\endgroup\$
    – Lynn
    May 11, 2015 at 17:17
4
\$\begingroup\$

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!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – MickyT
    May 7, 2015 at 23:44
  • \$\begingroup\$ @MickyT: That's fantastic. Thank you so much for noticing my mistake and proving a much better solution! I edited the answer. \$\endgroup\$
    – Alex A.
    May 8, 2015 at 1:05
4
\$\begingroup\$

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.

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

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
\$\endgroup\$
4
\$\begingroup\$

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.

\$\endgroup\$
0
4
\$\begingroup\$

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,'']
\$\endgroup\$
1
  • \$\begingroup\$ 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! \$\endgroup\$
    – Oebele
    May 11, 2015 at 11:41
4
\$\begingroup\$

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----
   /|\   
  / | \  
 /  |  \ 
/   |   \
\$\endgroup\$
2
  • \$\begingroup\$ "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." \$\endgroup\$ May 8, 2015 at 14:55
  • \$\begingroup\$ hahaha no worries :) \$\endgroup\$ May 8, 2015 at 15:07
3
\$\begingroup\$

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 '']
\$\endgroup\$
2
  • \$\begingroup\$ 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=) \$\endgroup\$
    – flawr
    May 8, 2015 at 21:15
  • \$\begingroup\$ I actually had the input line first, but for some reason I mistakenly thought it wasn't allowed... Thanks for the other tip though! \$\endgroup\$
    – Oebele
    May 11, 2015 at 11:36
3
\$\begingroup\$

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

\$\endgroup\$
0
2
\$\begingroup\$

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.

Try it online here.

\$\endgroup\$
2
\$\begingroup\$

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

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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=<>). \$\endgroup\$
    – alyx-brett
    May 8, 2015 at 10:09
2
\$\begingroup\$

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());}}
\$\endgroup\$
1
  • \$\begingroup\$ working on it!! \$\endgroup\$
    – Ewan
    May 8, 2015 at 14:58
2
\$\begingroup\$

Haskell, 80 bytes

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!

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 139 135 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");
}
\$\endgroup\$
5
  • 2
    \$\begingroup\$ You appear to be missing two rays. \$\endgroup\$
    – user12166
    May 8, 2015 at 2:31
  • \$\begingroup\$ Oh, darn, I forgot to add that back in… \$\endgroup\$
    – royhowie
    May 8, 2015 at 2:32
  • \$\begingroup\$ (A=Array).from(A(m)) \$\endgroup\$
    – Shmiddty
    May 8, 2015 at 2:42
  • \$\begingroup\$ @MichaelT I fixed it, but I think I can golf it some more \$\endgroup\$
    – royhowie
    May 8, 2015 at 3:17
  • \$\begingroup\$ @Shmiddty thanks for the suggestion! that saved a lot of characters \$\endgroup\$
    – royhowie
    May 8, 2015 at 3:27
1
\$\begingroup\$

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
\$\endgroup\$
3
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Sp3000
    May 8, 2015 at 18:28
  • \$\begingroup\$ 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". \$\endgroup\$
    – Sp3000
    May 8, 2015 at 18:34
  • \$\begingroup\$ Edited again. Thanks @Sp3000 \$\endgroup\$
    – Zach Gates
    May 8, 2015 at 18:39
1
\$\begingroup\$

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.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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 \$\endgroup\$
    – Sp3000
    May 8, 2015 at 19:46
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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---
  /|\
 / | \
/  |  \
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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.) \$\endgroup\$
    – manatwork
    May 8, 2015 at 16:22
1
\$\begingroup\$

Perl 85 91 90 89 86B

map{$_=$r||O;s/^|$/ /mg;s/ (-*O-*) /-$1-/;$r="\\$s|$s/
$_
/$s|$s\\";$s.=$"}1..<>;say$r

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
\$\endgroup\$
1
\$\begingroup\$

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).
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.