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

47 Answers 47

1
2
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
    Commented 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
    Commented May 8, 2015 at 18:34
  • \$\begingroup\$ Edited again. Thanks @Sp3000 \$\endgroup\$
    – Zach Gates
    Commented 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
    Commented 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
    Commented May 8, 2015 at 16:22
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\$
1
\$\begingroup\$

Powershell, 108 97 93 bytes

filter f{try{$s=' '*--$_
"\$s|$s/"
$_|f|%{(" $_ ","-$_-")[$_-match'O']}
"/$s|$s\"}catch{'O'}}

Explanation:

  • the recursive algorithm throws an exception on $s=' '*--$_ when current number less then 1;
  • the output is a perfect rectangle with trailing spaces.

Less golfed test script:

filter f{
    try{
        $s=' '*--$_
        "\$s|$s/"
        $_|f|%{(" $_ ","-$_-")[$_-match'O']}
        "/$s|$s\"
    }catch{
        'O'
    }
}

@(

,(0,"O")
,(1,"\|/",
    "-O-",
    "/|\")
,(2,"\ | /",
    " \|/ ",
    "--O--",
    " /|\ ",
    "/ | \")
,(3,"\  |  /",
    " \ | / ",
    "  \|/  ",
    "---O---",
    "  /|\  ",
    " / | \ ",
    "/  |  \")

) | % {
    $n,$expected = $_
    $result = $n|f
    "$result"-eq"$expected"
    $result
}

Output:

True
O
True
\|/
-O-
/|\
True
\ | /
 \|/ 
--O--
 /|\ 
/ | \
True
\  |  /
 \ | / 
  \|/  
---O---
  /|\  
 / | \ 
/  |  \
\$\endgroup\$
1
\$\begingroup\$

Japt, 26 25 bytes

Pub golfing so, as usual, could probably be shorter.

Æ"\\|/"¬qXçÃÔp'OiUç-¹·ê û

Try it

Æ"\\|/"¬qXçÃÔp'OiUç-¹·ê û     :Implicit input of integer U
Æ                             :Map each X in the range [0,U)
 "\\|/"¬                      :  Split the string "\|/"
        q                     :  Join with
         Xç                   :    X spaces
           Ã                  :End map
            Ô                 :Reverse
             p                :Push
              'Oi             :  "O" prepended with
                 Uç-          :    "-" repeated U times
                    ¹         :End push
                     ·        :Join with newlines
                      ê       :Palindromise
                        û     :Centre pad each line with spaces to the length of the longest
\$\endgroup\$
1
\$\begingroup\$

C (GCC), 95 bytes

i;j;main(n){for(i=-++n;++i<n;puts())for(j=-n;++j<n;)putchar(i?j?i-j?i+j?32:47:92:124:j?45:79);}

Attempt This Online!

Takes input as argc. Note that argc can be zero on a POSIX system.

Two bytes can be saved (s/++n/n/) if the input is incremented by one, i.e. N+1 is given instead of N.

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

Jelly, 48 43 bytes

AS$_/SḢṪ5ƭ
Wẋ5Ç=0Ɗ€
ŒRµ,þµÇi1Ɗ€€ị“O\/|- ”Y

Through multiple modifications this basically reduced to be ports of similar answers: exploding the matrix and running a couple of checks through it. Figured I'd post anyway because 1) there was no other Jelly answer and 2) I finally figured out the 'tie' quick.

AS$_/SḢṪ5ƭ    # The collection of checks to run against each element
AS$           # Sum of absolute values -> [0,0], "O"
   _/         # Difference -> [-x,-x] or [x,x], "\"
     S        # Sum -> [-x,x] or [x,-x], "/"
      Ḣ       # First element -> [0,x], "-"
       Ṫ      # Last element -> [x,0], "|"
        5ƭ    # Tie all five of those together

Wẋ5Ç=0Ɗ€      # Helper makes 5 copies of each element,
              # one to run each of the previous checks through
Wẋ5           # Make five copies of the given array
   Ç=0        # Run the above helper and compare each result to 0
      Ɗ€      # Run the zero check against each element passed in
          
ŒRµ,þµÇi1Ɗ€€ị“O\/|- ”Y
ŒRµ                          # Explode the arg, 1 -> [-1, 0, 1]
   ,þµ                       # Make a table/matrix of all combos
         Ɗ€€                 # For each row, for each column
      Ç                      # Call above helper link
       i1                    # and find the first 1

            
Now all the values are [0..5] so they can be indexed:
            ị“O\/|- ”   # Index each element into this string
                        # with zero wrapping to the last element
                     Y  # Join with linefeeds for final display
\$\endgroup\$
4
  • \$\begingroup\$ +1 for the explanation, but I must say, this is pretty long — Jelly is a shorter version of J, and the J solution is 10 bytes shorter! \$\endgroup\$ Commented Apr 14 at 2:23
  • \$\begingroup\$ I know! I was surprised as well! I didn't want to review the J answer too in depth until I made mine (as to not just be porting it). Now I think my binary indexing is overly complicated, so time to golf that away. \$\endgroup\$
    – Aaron
    Commented Apr 14 at 18:22
  • \$\begingroup\$ You also might find success going off of my Uiua solution, though certain parts might not translate perfectly to Jelly. I’m planning to learn Jelly so maybe I’ll try this problem in it as well. \$\endgroup\$ Commented Apr 14 at 18:44
  • \$\begingroup\$ Yes, @noodleman, your answer led to my discovery of Uiua which I stayed up late starting to learn, so thanks for posting that! \$\endgroup\$
    – Aaron
    Commented Apr 14 at 18:48
1
\$\begingroup\$

Perl 5 -n, 71 69 bytes

70 68 bytes of code + 1 for -n (as was the style at the time)

//&say map$_?$_-$'?$_+$'?$'?$":'-':'/':'\\':$'?'|':O,@;for@;=-$_..$_

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ > as was the style at the time \$\endgroup\$ Commented Apr 25 at 8:09
  • 1
    \$\begingroup\$ @DomHastings I always keep a towel nearby and an onion on my belt. \$\endgroup\$
    – Xcali
    Commented Apr 25 at 18:08
1
\$\begingroup\$

sed -rn, 132 126 124 122 121 bytes

s/^0/O/p               # if input is 0, swap to O and print
t                      # if success, quit
s/[^ ]*/echo {1..&}/e  # swap to 'echo {1..N}' and execute
s///g                  # delete all but spaces (makes N-1 spaces)
s%.*%\\&|&/%p          # swap ALL for \MATCH|MATCH/ and print
:a                     # define label 'a'             (start of main loop)
s%(\\)? (/)?%\2 \1%gp  # move slashes and print                          |
h                      # copy PATTERN space to HOLD space                |
y/ /-/                 # change spaces to dashes                         |
s%\\\|/%-O-%p          # if there's a '\|/' change it to '-O-' and print |
x                      # swap HOLD and PATTERN spaces                    |
s%%/|\\%p              # reuse prev. pattern & change to '/|\' and print |
/^\//!ba               # branch to label 'a'            (end of main loop)

Try it online!

the real engine of this answer, s%(\\)? (/)?%\2 \1%gp, was taken from this sed answer. it finds any ' /' or '\ ' and swaps them out for '/ ' and ' \' respectively, moving the right slashes in the right directions. I was hoping to use \ch but apperently TIO does not support ^H as a backspace and prints out a literal \x08 char

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

Groovy - 113

f={n->s=2*n+1;(1..s).each{r->(1..s+1).each{c->print c==r?n+1==r?"O":"\\":c==s-r+1?"/":c==n+1?"|":c>s?"\n":" "}}}

I think the ternary logic could probably be cleaned up to give a shorter answer...

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

SmileBASIC, 87 bytes

INPUT N
FOR Y=-N TO N
FOR X=-N TO N?" \/|-     O"[(X==Y)+!(X+Y)*2+!X*3+!Y*4];
NEXT?NEXT
\$\endgroup\$
0
\$\begingroup\$

Canvas, 14 bytes

╵⌐|*⁸/+↔ω↶n┼O╋

Try it here!

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

Retina 0.8.2, 99 bytes

.+
$* X$&$*-
 ( *)X(-+)
$1\|/¶$2X$2¶$1/|\
+`^ ( *.)( *)
$1$2 | $2/¶$&
+` ( */)( *).+$
$&¶$1$2 | $2\

Try it online! Explanation:

.+
$* X$&$*-

Place the X and draw n -s to its right. This completes the output for n=0.

 ( *)X(-+)
$1\|/¶$2X$2¶$1/|\

If n>0 then copy the -s to the left, and add the first level of \|/ and /|\ around the X. This completes the output for n=1.

+`^ ( *.)( *)
$1$2 | $2/¶$&

Extend the \|/ upwards, removing a space of indent each time, adding it back on each side of the |.

+` ( */)( *).+$
$&¶$1$2 | $2\

Extend the /|\ downwards, removing a space of indent each time, adding it back on each side of the |.

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

Vyxal, 46 bytes

(\\n›↳⁰↲\|\/n›↲⁰↳Ṡ,)\O-?-,(\/n›↲⁰↳\|\\n›↳⁰↲Ṡ,)

Try it Online!

A mess that I can't be bothered fixing, at least for now.

\$\endgroup\$
1
2

Your Answer

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

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