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\$
  • \$\begingroup\$ Is a leading newline allowed? Especially interesting for N=0. \$\endgroup\$ – Jakube May 7 '15 at 23:10
  • \$\begingroup\$ @Jakube No. Trailing only. \$\endgroup\$ – Calvin's Hobbies May 7 '15 at 23:12

37 Answers 37

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\$
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\$
  • 7
    \$\begingroup\$ "c++" in C ... heh! \$\endgroup\$ – bjb568 May 10 '15 at 0:54
  • \$\begingroup\$ I'm glad you ungolfed it. Those ternary ifs are insane! \$\endgroup\$ – ldam May 15 '15 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\$ – Johan du Toit May 8 '17 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\$
  • 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 '15 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 '15 at 9:54
  • \$\begingroup\$ It's still mighty impressive either way \$\endgroup\$ – JustSid May 8 '15 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\$ – undergroundmonorail May 8 '15 at 12:46
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\$
  • 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\$ – squeamish ossifrage May 7 '15 at 23:57
  • \$\begingroup\$ ternary operators is a good tip \$\endgroup\$ – nick May 8 '15 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 '15 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 '15 at 8:32
  • \$\begingroup\$ @squeamishossifrage I never thought of that. Thanks for the tips! \$\endgroup\$ – Kodos Johnson May 8 '15 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\$
  • \$\begingroup\$ I think you can use R instead of .5 to save 1 byte. \$\endgroup\$ – randomra May 9 '15 at 21:46
  • \$\begingroup\$ @randomra That's clever, thanks. Down to two digits! \$\endgroup\$ – xnor May 10 '15 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\$
  • \$\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\$ – Martin Ender Jun 12 '15 at 13:45
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\$
  • \$\begingroup\$ Beautiful. I should have thought of a closure to use normal for loops. \$\endgroup\$ – nderscore May 8 '15 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 '15 at 8:46
6
\$\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\$
  • \$\begingroup\$ For your cheater version: if the filename of a program is not arbitrary, it has to be included in the byte count. \$\endgroup\$ – Martin Ender May 9 '15 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 '15 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 '15 at 10:55
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\$
  • \$\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 '15 at 0:05
  • \$\begingroup\$ Maybe map(i#)[-n..n] to save two bytes. \$\endgroup\$ – Lynn May 11 '15 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\$
  • 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 '15 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 '15 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\$
  • \$\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 '15 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 '15 at 15:17
  • \$\begingroup\$ I've added the ungolfed version :) \$\endgroup\$ – Transmission May 8 '15 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\$
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\$
  • \$\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 '15 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\$
  • \$\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\$ – sirpercival May 8 '15 at 14:55
  • \$\begingroup\$ hahaha no worries :) \$\endgroup\$ – sirpercival May 8 '15 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\$
  • \$\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 '15 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 '15 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\$
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
    \$\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\$ – alexander-brett May 8 '15 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\$
  • \$\begingroup\$ working on it!! \$\endgroup\$ – Ewan May 8 '15 at 14:58
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\$
  • 2
    \$\begingroup\$ You appear to be missing two rays. \$\endgroup\$ – user12166 May 8 '15 at 2:31
  • \$\begingroup\$ Oh, darn, I forgot to add that back in… \$\endgroup\$ – royhowie May 8 '15 at 2:32
  • \$\begingroup\$ (A=Array).from(A(m)) \$\endgroup\$ – Shmiddty May 8 '15 at 2:42
  • \$\begingroup\$ @MichaelT I fixed it, but I think I can golf it some more \$\endgroup\$ – royhowie May 8 '15 at 3:17
  • \$\begingroup\$ @Shmiddty thanks for the suggestion! that saved a lot of characters \$\endgroup\$ – royhowie May 8 '15 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\$
  • 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 '15 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 '15 at 18:34
  • \$\begingroup\$ Edited again. Thanks @Sp3000 \$\endgroup\$ – Zach Gates May 8 '15 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
    \$\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 '15 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
    \$\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 '15 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\$
1
\$\begingroup\$

JavaScript (ES6), 142 140 134 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``
i.addEventListener("input",_=>o.innerText=f(+i.value))
o.innerText=f(i.value=1)
<input id=i type=number><pre id=o>

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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