37
\$\begingroup\$

Draw the parabolic trajectory of a thrown ball.

The input is the ball's initial upward velocity, a positive integer v. Every second, the ball moves 1 space right and v spaces vertically, and then v decreases by 1 to due to gravity. So, the upward velocity eventually steps down from v to 0 and down to -v, finally falling back down to its initial height.

The ball's positions trace a parabola. At horizontal position x, its height is y=x*(2*v+1-x)/2, with (0,0) the ball's initial position at the bottom left.

Output ASCII art of the ball's trajectory with O's on the coordinates it ever occupies. The output should be a single multi-line piece of text, not an animation of the path over time.

The output should have no leading newlines and at most one trailing newline. The bottom line should be flush with the left edge of the screen, i.e. have no extra leading spaces. Trailing spaces are OK. You may assume the output line width fits in the output terminal.

v=1

 OO 
O  O

v=2

  OO  
 O  O 

O    O

v=3

   OO   
  O  O  

 O    O 


O      O

v=4

    OO    
   O  O   

  O    O  


 O      O 



O        O

v=10

          OO          
         O  O         

        O    O        


       O      O       



      O        O      




     O          O     





    O            O    






   O              O   







  O                O  








 O                  O 









O                    O

Related: Bouncing ball simulation


Leaderboard:

var QUESTION_ID=111861,OVERRIDE_USER=20260;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/111861/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

\$\endgroup\$
6
  • \$\begingroup\$ Can we ouput a list of lines? \$\endgroup\$
    – Riker
    Mar 2, 2017 at 3:26
  • \$\begingroup\$ @Riker Nope, string with newlines. \$\endgroup\$
    – xnor
    Mar 2, 2017 at 3:27
  • \$\begingroup\$ loosely related: codegolf.stackexchange.com/q/110410 \$\endgroup\$
    – Titus
    Mar 2, 2017 at 14:06
  • \$\begingroup\$ Do I only need to account for V > 0? \$\endgroup\$
    – nmjcman101
    Mar 2, 2017 at 17:56
  • \$\begingroup\$ Yes, v will be positive. \$\endgroup\$
    – xnor
    Mar 2, 2017 at 18:02

35 Answers 35

17
\$\begingroup\$

Charcoal, 18 16 13 bytes

-3 bytes thanks to @Neil!

F⊕N«←OM⊕ι↓»‖C

Explanation

F⊕N«        »    For ι (implicitly from 0) to (1 + input as number)
       ←O          Print O, with print direction rotated 180 degrees
         M⊕ι↓     Move 1+ ι units down
               
                ‖C Reflect (in the default direction, right), leaving original intact

Try it online! Link is to verbose code.

\$\endgroup\$
5
  • \$\begingroup\$ I like this one a lot, +1; Also OP's output uses uppercase "O". (Not that it matters at all lol) \$\endgroup\$ Mar 2, 2017 at 3:46
  • \$\begingroup\$ If you use ↘O then you can loop from 0 to N inclusive instead which saves you two bytes immediately. \$\endgroup\$
    – Neil
    Nov 2, 2018 at 9:35
  • \$\begingroup\$ @Neil Thanks! Also, this is a very old post :P (and I wonder if I should be using newer features. Probably not?) \$\endgroup\$
    – ASCII-only
    Nov 4, 2018 at 4:25
  • \$\begingroup\$ Strictly speaking I've only saved you 1 byte so far as the other two bytes were you replacing ⁺¹ with . However now that you've moved the from the ‖C to the O you can save another byte by writing ↙OMι↓, so I'm back up to a two byte saving again. \$\endgroup\$
    – Neil
    Nov 4, 2018 at 10:36
  • \$\begingroup\$ Also you forgot to update your TIO link. And technically I believe we now allow newer features, but I can't claim credit for those bytes. \$\endgroup\$
    – Neil
    Nov 4, 2018 at 10:39
6
\$\begingroup\$

C, 93 92

(Note, someone got to 87 in the comments)

y,n;f(s){for(y=0;y<=s;){printf("%*c%*c",s-y+1,79,y*2+1,79);for(n=++y;s+1-n&&n--;)puts("");}}

Try it online!


Readable:

y,n;f(s){
    for(y=0;y<=s;){
        printf("%*c%*c",s-y+1,79,y*2+1,79);
        for(n=++y;s+1-n&&n--;)puts("");
    }
}

Notes:

I can collapse both for loops into just one for loop by iterating the total number of lines outputted, which is given by the formula: n*-~n/2+1

y,n,r;f(s){
    for(r=s,y=n=0;r<s*-~s/2+1;)
        y==n?printf("%*c%*c",s-y+1,79,y*2+1,79),y=0,++n:r++,y++,puts("");
}

But it ends up being even more bytes than just using two seperate for-loops

\$\endgroup\$
6
  • \$\begingroup\$ You can save one byte by incrementing s at the beginning, like this: y,n;f(s){++s;for(y=0;y<s;){printf("%*c%*c",s-y,79,y*2+1,79);for(n=++y;s-n&&n--;)puts("");}} \$\endgroup\$
    – Steadybox
    Mar 2, 2017 at 11:12
  • \$\begingroup\$ @Steadybox won't compile for me. Also I got 90 bytes when I counted that (after removing whitespace characters) \$\endgroup\$ Mar 2, 2017 at 11:21
  • \$\begingroup\$ All I did was adding the ++s; at the beginning and then changing y<=s to y<s and s-y+1 to s-y and s+1-n to s-n, so it should compile (and should be 91 bytes). \$\endgroup\$
    – Steadybox
    Mar 2, 2017 at 11:35
  • \$\begingroup\$ It seems that there is something wrong with the encoding of the code block in my comment. Copying and pasting the code from the comment won't compile for me either. \$\endgroup\$
    – Steadybox
    Mar 2, 2017 at 11:36
  • 1
    \$\begingroup\$ 87 bytes \$\endgroup\$
    – ceilingcat
    Mar 7, 2019 at 9:48
5
\$\begingroup\$

Python 2, 65 bytes

f=lambda n,x=0:(n and f(n-1,x+1)or'')+'\n'*n+' '*x+'O'+'  '*n+'O'

Try it online!

\$\endgroup\$
5
\$\begingroup\$

GNU sed, 41

  • Score includes +1 from -r flags to sed.
s/$/OO/
:
s/(\s*) O( *)O$/&\n\1O \2 O/
t

Input is in unary, as a string of spaces - the length of string is the input.

Try it online.

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

Python 2, 76 bytes

x=input()
for i in range(x):print' '*(x-i),'O'+' '*i*2+'O'+'\n'*(i-x+1and i)

Pretty simple. The i-x+1and i is to prevent a bunch of trailing newlines.

\$\endgroup\$
1
  • \$\begingroup\$ Moving the newline to the beginning of the print, like '\n'*(i-1)saves 7 bytes while avoiding the trailing newlines. \$\endgroup\$
    – Emigna
    Mar 2, 2017 at 10:11
4
\$\begingroup\$

05AB1E, 18 14 bytes

Saved 4 bytes thanks to Adnan

ƒ¶N×'ONúRÂJ}.c

Try it online!

Explanation

ƒ                   # for N in [0 ... input]
 ¶N×                # push N newlines
    'O              # push "O"
      Nú            # pad with N spaces in front
        RÂ          # reverese and create a reversed copy
          J         # join everything to a string
           }        # end loop
            .c      # pad lines until centered 
\$\endgroup\$
3
  • \$\begingroup\$ For 14 bytes: ƒ¶N×'ONúRÂJ}.c :) \$\endgroup\$
    – Adnan
    Mar 2, 2017 at 10:51
  • \$\begingroup\$ @Adnan Thanks! I tried .c with a different version, but it didn't work well then. Forgot about trying it with this one and complete forgot that ú exists :) \$\endgroup\$
    – Emigna
    Mar 2, 2017 at 10:58
  • \$\begingroup\$ Definitely better than the zip method I chose, interesting approach vertically. \$\endgroup\$ Mar 2, 2017 at 19:29
4
\$\begingroup\$

Bash, 76 bytes

for((n=$1+1;--n;));{
yes ''|head -$n
r=$r›${n}AO
t=›${n}BO$t
}
echo O${r}O$t

Only works in a terminal since it uses ANSI escape sequences. represents the CSI byte (0x9b).

Test run

$ # The terminal's encoding must be set to ISO-8859-1.
$
$ xxd -g 1 arc.sh
0000000: 66 6f 72 28 28 6e 3d 24 31 2b 31 3b 2d 2d 6e 3b  for((n=$1+1;--n;
0000010: 29 29 3b 7b 0a 79 65 73 20 27 27 7c 68 65 61 64  ));{.yes ''|head
0000020: 20 2d 24 6e 0a 72 3d 24 72 9b 24 7b 6e 7d 41 4f   -$n.r=$r.${n}AO
0000030: 0a 74 3d 9b 24 7b 6e 7d 42 4f 24 74 0a 7d 0a 65  .t=.${n}BO$t.}.e
0000040: 63 68 6f 20 4f 24 7b 72 7d 4f 24 74              cho O${r}O$t
$
$ bash arc.sh 1
 OO
O  O
$ bash arc.sh 2
  OO
 O  O

O    O
$ bash arc.sh 3
   OO
  O  O

 O    O


O      O
$ bash arc.sh 4
    OO
   O  O

  O    O


 O      O



O        O
\$\endgroup\$
4
  • \$\begingroup\$ You can use sed $nq to save a byte. \$\endgroup\$
    – zeppelin
    Mar 2, 2017 at 16:40
  • \$\begingroup\$ Sadly, no. I'd have to use sed ${n}q which is longer. \$\endgroup\$
    – Dennis
    Mar 2, 2017 at 17:49
  • \$\begingroup\$ Argh, I see, you can do sed $n\q instead, but that does not make much sense either, as it would be the same byte count as head ! \$\endgroup\$
    – zeppelin
    Mar 2, 2017 at 19:15
  • \$\begingroup\$ Suggest ((n=$1;n;--n)) for -1 byte \$\endgroup\$
    – c--
    Jun 22, 2023 at 6:23
4
\$\begingroup\$

JavaScript (ES6), 98 92 89 84 78 bytes

(-20 bytes thanks to Arnauld!)

f=(v,i=0)=>i>v?"":" "[r="repeat"](v-i)+0+" "[r](2*i)+0+`
`[r](i++<v&&i)+f(v,i)

A recursive solution. This is also my first ever answer in JavaScript, so please be gentle! I am still learning all this neat language has to offer, so golfing tips are very much appreciated. :)

Test Snippet

You may need to scroll to see the entire output.

f=(v,i=0)=>i>v?"":" "[r="repeat"](v-i)+0+" "[r](2*i)+0+`
`[r](i++<v&&i)+f(v,i)
<input id=i min=1 type=number><button onclick=alert(f(document.getElementById("i").value))>Submit</button>

\$\endgroup\$
6
  • \$\begingroup\$ Also, including variables inside backtick strings with ${} only saves bytes when the variable part is surrounded by static parts. As such, these strings should always start and end with static parts. \$\endgroup\$
    – Luke
    Mar 2, 2017 at 14:54
  • \$\begingroup\$ @Arnauld Thanks for all the tips! I really appreciate it! :) \$\endgroup\$
    – R. Kap
    Mar 2, 2017 at 18:52
  • \$\begingroup\$ @Luke Thanks for the advice. That will come in handy. :) \$\endgroup\$
    – R. Kap
    Mar 2, 2017 at 18:52
  • \$\begingroup\$ You can safely use 0 instead of "0". They'll be coerced to strings. And on second thought: i++<v&&i is actually one byte shorter than (i<v)*++i. \$\endgroup\$
    – Arnauld
    Mar 3, 2017 at 15:34
  • \$\begingroup\$ @Arnauld Thank you once again! :) \$\endgroup\$
    – R. Kap
    Mar 4, 2017 at 7:59
4
\$\begingroup\$

MATL, 19 17 bytes

Q:tqYsQ79Z?PtPv!c

Try it at MATL Online! Or verify all test cases.

Explanation

Q        % Implicitly input v. Add 1
:        % Push [1 2 ... v+1]
tq       % Duplicate and subtract 1: pushes [0 1 ... v]]
Ys       % Cumulative sum: gives [0 1 3 6 ...]
Q        % Add 1: gives [1 2 4 7 ...]
79       % Push 79 (ASCII for 'O')
Z?       % Create sparse matrix from column indices [1 2 3 4 ...],
         % row indices [1 2 4 7 ...], and data 79
P        % Flip vertically
tP       % Duplicate, flip vertically
v        % Concatenate the two matrices vertically
!        % Transpose
c        % Convert to char. Implicitly display. Char 0 is shown as space
\$\endgroup\$
3
\$\begingroup\$

RProgN 2, 37 bytes

x=0xR{y@xy-` *`o` y2**`o...2y{[` };};

Getting in with my kind-of-golfy language before the proper golfy langauges jump in.

Explained

x=              # Set 'x' to the input
0xR{            # For everything between the input and 0
    y@          # Set the iteration value to y, for this function only.
    xy-` *      # Subtract y from x, repeat the string " " that many times.
    `o          # Push an "o" to the stack.
    ` y2**      # Push 2*y " "'s to the stack
    `o          # Push another "o" to the stack
    ...         # Concatenate the parts of this string together, giving us the two balls.
    2y{[` };    # For all numbers between 2 and y, add a newline.
};              #

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Retina, 29 19 bytes

 ?
$.`$*¶$&$'O$`$`O

Try it online!

Takes input in unary as a run of spaces. Port of my JavaScript answer. Edit: Saved 10 bytes thanks to @MartinEnder♦.

\$\endgroup\$
1
  • \$\begingroup\$ I´m only waiting for someone to come up with a Retina spin off called Retsina. \$\endgroup\$
    – Titus
    Mar 2, 2017 at 13:57
3
\$\begingroup\$

Retina, 35

  • 2 bytes saved thanks to @MartinEnder

Port of my sed answer:

.+
$* OO
+`(\s*) (O *)O$
$&¶$1O $2 O

Try it online.

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

R, 89 bytes

a=2*v+3
x=matrix(" ",a,v^2+1)
for(k in 0:v)x[c(1-k,k+2)+v,k^2+1]="o"
x[a,]="\n"
cat(x,sep="")
  • Create a matrix of spaces (the variable a is the width of this matrix, saving a couple of bytes)
  • Fill in "o"s at the required locations, working from the top of the arc downwards and outwards
  • Add a newline at the end of each matrix row
  • Collapse the matrix down to a single string and print

This is my first attempt at golfing, comments welcome...

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

Röda, 53 52 bytes

f n{seq 0,n|{|i|["
"*i," "*(n-i),"O"," "*i*2,"O"]}_}

Try it online!

Usage: main { f(5) }

Ungolfed version:

function f(n) {
    seq(0, n) | for i do
        push("\n"*i, " "*(n-i), "O", " "*i*2, "O")
    done
}
\$\endgroup\$
2
  • \$\begingroup\$ Can you use a literal newline instead of \n and save 1 byte? \$\endgroup\$
    – user41805
    Mar 12, 2017 at 15:42
  • \$\begingroup\$ @KritixiLithos That works. Thanks! \$\endgroup\$
    – fergusq
    Mar 12, 2017 at 15:48
2
\$\begingroup\$

Befunge, 75 73 bytes

<vp00:&
1<-1_:v#\+55:g01\-g01g00" O"1\*2g01" O"1p0
#@_\:v>$$:!
1\,:\_^#:-

Try it online!

The first line reads in the velocity, v, and saves a copy in memory. The second line then counts down from v to zero, with the index i, and on each iteration pushes a sequence of character/length pairs onto the stack.

Length  Character
-----------------
1       'O'
i*2     ' '
1       'O'
v-i     ' '
i       LINEFEED

This sequence represents a kind of run-length encoding of the required output in reverse. The last two lines then simply pop these character/length pairs off the stack, outputting length occurrences of each character, until the stack is empty.

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

Java 8, 129 124 109 bytes

Golfed:

v->{String s="",t="";for(int j,y=0;y<=v;++y){for(j=0;j<v;++j)s+=j<y?"\n":" ";s+="o"+t+"o";t+="  ";}return s;}

Try it online!

Ungolfed:

public class DrawTheArcOfABall {

  public static void main(String[] args) {
    for (int i = 1; i < 6; ++i) {
      System.out.println(f(v -> {
        String s = "", t = "";
        for (int j, y = 0; y <= v; ++y) {
          for (j = 0; j < v; ++j) {
            s += (j < y ? "\n" : " ");
          }
          s += "o" + t + "o";
          t += "  ";
        }
        return s;
      } , i));
      System.out.println();
      System.out.println();
    }
  }

  private static String f(java.util.function.IntFunction<String> f, int v) {
    return f.apply(v);
  }
}
\$\endgroup\$
4
  • \$\begingroup\$ Try it online! \$\endgroup\$
    – Poke
    Mar 2, 2017 at 20:23
  • \$\begingroup\$ For the second nested for loop, I think for(;j<v;++) would work, because at this point in time j==y. Also, you could remove the third by adding a second string variable inside the main for loop String t=""; (12) and t+=" "; (8) inside the first nested loop. Then the third loop just becomes s+="o"+t+"o"; \$\endgroup\$
    – nmjcman101
    Mar 2, 2017 at 20:57
  • \$\begingroup\$ Also, you can combine the first two nested loops to for(j=0;j<v;++j)s+=j<y?"\n":" "; although I'm not sure how this meshes with my previous comment about t \$\endgroup\$
    – nmjcman101
    Mar 2, 2017 at 20:59
  • \$\begingroup\$ You can initialize t="" alongside s in the beginning, and then add t+=" " each loop around after you do s+="o"+t+"o" \$\endgroup\$
    – nmjcman101
    Mar 2, 2017 at 21:12
2
\$\begingroup\$

Haskell, 69 bytes

r=replicate
f n=[0..n]>>= \a->r a '\n'++r(n-a)' '++'O':r(2*a)' '++"O"

Usage example: f 3 -> " OO\n O O\n\n O O\n\n\nO O". Try it online!.

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

VBA, 124 112 85 88 66 63 59 bytes

For i=0To[A1]:?Space([A1]-i)"O"Space(2*i)"O"String(i,vbCr):Next

Saved 29 bytes in total thanks to Taylor Scott

This must be run the in VBA Immediate window and print the result in the same.

Expanded / Formatted, it becomes:

For i=0 To [A1]
   Debug.Print Space([A1]-i) & "O" & Space(2*i) & "O" & String(i,vbCr)
Next

(It turns out that concatenation in a print command is automatic without an operator.)

\$\endgroup\$
10
  • \$\begingroup\$ b & s & Spaces alert! \$\endgroup\$ Mar 2, 2017 at 21:15
  • \$\begingroup\$ I tried and it erred the first time. Going back, I realized it'll expand b &s &String but not b&s&String. Also, at first I thought you meant to use the Space function which I totally should have and that ended up saving more bytes. \$\endgroup\$ Mar 2, 2017 at 21:24
  • \$\begingroup\$ You can condense for i=0 To v and debug.? b to for i=0To v and Debug.?b, respectively for -2 bytes. And just so you know, the community consensus is that for languages with autoformatting, you may count before it is autoformatted, meaning after you make these changes you should have a byte count of 85 Bytes \$\endgroup\$ Mar 28, 2017 at 23:03
  • \$\begingroup\$ On a second look, this is a snippet - not a function or subroutine; so it is not a valid solution. I believe that you could fix this by converting it an Excel VBA immediate window function and taking input from [A1] (v=[A1]) Also, I don't think you actually need the s variable. \$\endgroup\$ Sep 8, 2017 at 14:37
  • 1
    \$\begingroup\$ @TaylorScott That seems like an obvious improvement in retrospect but I did not know that concatenation did not require an operator in the immediate window. That'll save me some bytes in the future. I did have to add a ; to the end of the print command, though, because it kept adding an extra line break by default. Thanks! \$\endgroup\$ Sep 11, 2017 at 12:19
2
\$\begingroup\$

05AB1E, 18 13 bytes

ÝηRO«ð×'O«ζ»

Try it online!

Ý                # [0..n]
 €LRO            # [0.sum(), 0..1.sum(), ..., 0..n-1.sum(), 0..n.sum()]
     «          # Mirror image the array [0, 0..n.sum(), 0]
       ð×'O«     # Push that many spaces with an O appended to it.
            .B   # Pad small elements with spaces to equal largest element length.
              ø» # Transpose and print.
\$\endgroup\$
2
\$\begingroup\$

MATLAB, 114 Bytes

function p(v),for i=0:v,fprintf([repmat(' ',1,v-i),'o',repmat(' ',1,2*i),'o',repmat('\n',1,(i*(i~=v)+1))]);end,end

ungolfed:

function p(v)
   for i=0:v
       fprintf([repmat(' ',1,v-i),'o',repmat(' ',1,2*i),'o',repmat('\n',1,(i*(i~=v)+1))]);
   end
end
\$\endgroup\$
1
\$\begingroup\$

Jelly, 17 16 bytes

‘Ḷ+\Ṛ⁶ẋ;€”Om0z⁶Y

Try it online!

How?

‘Ḷ+\Ṛ⁶ẋ;€”Om0z⁶Y - Main link: v         e.g. 3
‘                - increment: v+1            4
 Ḷ               - lowered range             [0,1,2,3]
  +\             - reduce with addition      [0,1,3,6]
    Ṛ            - reverse                   [6,3,1,0]
     ⁶           - a space                   ' '
      ẋ          - repeat (vectorises)       ['      ','   ',' ','']
       ;€        - concatenate each with
         ”O      -     an 'O'                ['      O','   O',' O','O']
           m0    - concatenate reflection    ['      O','   O',' O','O','O','O ','O   ','O      ']
             z⁶  - transpose with space fill ['   OO   ','  O  O  ','        ',' O    O ','        ','        ','O      O']
               Y - join with line feeds      ['   OO   \n  O  O  \n        \n O    O \n        \n        \nO      O']
                 - implicit print
\$\endgroup\$
1
\$\begingroup\$

PHP, 76 bytes

for(;$argn>=0;$s.="  ")echo($r=str_repeat)("
",$i++),$r(" ",$argn--),o,$s,o;

Run with echo <v> | php -nR '<code>' or test it online.

loops $argn down from input to 0 and $i up from 0;
prints - in that order - in each iteration

  • $i newlines (none in the first iteration)
  • left padding: $argn spaces
  • left ball: o
  • inner padding: 2*$i spaces
  • right ball: o
\$\endgroup\$
1
\$\begingroup\$

V, 23 19 bytes

2éoÀñYço/^2á O
HPJ>

Try it online!

Explain

2éo            " Insert two 'o's
   Àñ          " <Arg> times repeat
     Y         " Yank the current (top) line.  This is always '\s*oo'
      ço/      " On every line that matches 'o'
         ^     " Go to the first non-whitespace character (the 'o')
          2á   " Append two spaces (between the two 'o's
             O " Add a blank line on top of the current one
H              " Go to the first line
 P             " Paste in front ('\s*oo')
  J            " Join this line with the blank line immediately after it
   >           " Indent once
\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 87 bytes

f=
n=>' '.repeat(n+1).replace(/./g,"$`#$'O$`$`O").replace(/ *#/g,s=>[...s].fill``.join`
`)
<input type=number min=0 oninput=o.textContent=f(+this.value)><pre id=o>

Nonrecursive solution. Indexing requirement was annoying, both in the above and the following 62-byte (I don't know whether it would result in a shorter Retina port) recursive solution:

f=n=>~n?` `.repeat(n)+`OO`+f(n-1).replace(/^ *O/gm,`
$&  `):``
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 48 bytes

47 bytes code + 1 for -n.

$_++;print$/x$-,$"x$_,O,$"x($-++*2),O while$_--

Try it online!

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

MathGolf, 17 bytes

r{n*íï- *'oï *+_x

Try it online!

Explanation

r                   range(0, n)
 {                  start block or arbitrary length
  n                 newline char, or map array with newlines
   *                pop a, b : push(a*b)
    í               get total number of iterations of for loop
     ï              index of current loop, or length of last loop
      -             pop a, b : push(a-b)
                    space character
        *           pop a, b : push(a*b)
         '          push single character
          o         print TOS without popping
           ï        index of current loop, or length of last loop
                    space character
             *      pop a, b : push(a*b)
              +     pop a, b : push(a+b)
               _    duplicate TOS
                x   reverse int/array/string
\$\endgroup\$
1
\$\begingroup\$

J, 29 bytes

[:|:@(,~|.)' O'#~1,.~i.+/\@,]

Try it online!

Turned out very similar to Razetime's APL answer, though solved independently. I tried about 3 other approaches before realizing this one would be shortest.

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

Stacked, 67 63 bytes

args 0#1+:@x:>{!n x\-1-' '*'O'+n 2*' '*+'O'+x 1-n!=n*LF*+out}"!

Initial attempt, 67 bytes

args 0# :@v 1+2*:>[:v:+1+\-2/*' '*'O'+''split]"!fixshape tr rev out

Full program. Generates something like:

('O'
 ' ' 'O'
 ' ' 'O'
 'O')

Which is the padded, transposed, reversed, and outputted.

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

Batch, 163 bytes

@set l=@for /l %%i in (1,1,%1)do @call
@set s=
%l% set s= %%s%%
@set t=
%l%:c&for /l %%j in (2,1,%%i)do @echo(
:c
@echo %s%O%t%O
@set s=%s:~1%
@set t=  %t%
\$\endgroup\$
0
\$\begingroup\$

Ruby, 52 bytes

->x{(0..x).map{|a|$><<$/*a+' '*(x-a)+?O+' '*a*2+?O}}

No trailing newline (allowed by the rules: "at most one trailing newline")

\$\endgroup\$

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.