47
\$\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

46 Answers 46

1
2
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\$

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\$

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\$

Vyxal, 20 bytes

`|/-\\`d•\Op8ʁ8j?›ø∧

Try it Online!

                  ø∧ # Draw on the canvas with
            8ʁ8j     # Directions [0, 8, 1, 8, 2, 8 ... 6, 8, 7]
                     # - ↑, center, ⇗, center ... ⇐, center, ⇖
`|/-\\`d             # Text: "|/-\|/-\"
        •            # Each char repeated by the input
         \Op         # With an O prepended
                ?›   # Line length: Input + 1
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 25 bytes

>I…-\|×{1ú68780.Λ¨'O«.º.∊

Try it online.

Explanation:

Step 1: Draw the top-right corner:

>                 # Increase the (implicit) input-integer by 1
 …-\|             # Push string "-\|"
     I×           # Repeat it the input amount of times
       {          # Sort it, so it's in the order "--\\||" again
        1ú        # Pad a leading space
          68780   # Push 68780
               .Λ # Use the Canvas builtin with these three arguments

Try just step 1 online.
See this 05AB1E tip of mine to understand how the Canvas builtin and its arguments works.

Step 2: Fix the center O:

¨                 # Remove the trailing character
 'O«             '# Append an "O" instead

Try just the first two steps online.

Step 3: Mirror it in both directions, and output the result:

.º                # Intersected mirror it horizontally
  .∊              # Intersected mirror it vertically
                  # (after which the result is output implicitly)
\$\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\$

sed 4.2.2 -r, 132 126 124 122 bytes

s/^0/O/                # if input is 0, swap to O
/O/q                   # if PATTERN is O, quit (implicitly prints)
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
:                      # define label ''              (start of main loop)
/^\//Q                 # if PATTERN begins with / quit without printing  |
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 |
b                      # branch to label ''             (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 \x0008 char

it has no trailing spaces or newlines except with 0, which has a trailing newline that could be removed at the cost of one byte by changing lines 1-2 to s/^0/O/p;/O/Q (newline and ; are basically equivalent)

a few sed commands have s/// flag versions that execute upon a sucessful swap, and now I really want a flag version of t and q. the current t command on its own is just too expensive to use, but a flag version could have potential; and a q flag would save me 4 bytes on line 2

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

Perl 5 -n, 71 bytes

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

map{//;say map$_?$_-$'?$_+$'?$'?$":'-':'/':'\\':$'?'|':O,@a}@a=-$_..$_

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
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.