13
\$\begingroup\$

Bob the Bowman

      o         
    /( )\                                         This is Bob. 
     L L                                          Bob wants to be an archer.
#############

    .
   / \          <--- bow                          So he bought himself a
  (c -)->       <--- arrow                        nice longbow and is about
  ( )/          <--- highly focused Bob           shoot at a target.
  L L           
#############

___________________________________________________________________________________________
sky

                     Bob is a smart guy. He already knows what angle and
                     velocity his arrow has / will have. But only YOU know
                     the distance to the target, so Bob doesn't know if he
                     will hit or miss. This is where you have to help him.

     .                                                                                  +-+
    / \                                                                                 | |
   (c -)->                                                                              | |
   ( )/                                                                                 +++
   L L                                                                                   |
###########################################################################################

Task

Your task is to render an ASCII art picture of Bob hitting or missing the target. For the calculation:

  • Your program will receive arrow_x,angle,velocity,distance as comma-separated input in any order you wish.
  • One ASCII character equals 1m.
  • The first character in the last line has the coordinates (0,0), so the ground (rendered as #) is at y=0.
  • Bob always stands on the ground, his y position does not change.
  • There is no max y. However, the arrows apex should fit within the rendered picture.
  • All input is provided as decimal integer.
  • During calculation, assume the arrow is a point.
  • The arrow origin is the arrow head > of a shooting Bob (see above). So given arrow_x, you have to calculate arrow_y. The left foot of Bob in the output has to match the x coord. of the shooting Bob.
  • distance is the x coordinate of the target's foot. (ie. the middle of the target).
  • All measurements are supplied in meters and degrees respectively.
  • Attention: The shooting Bob is never rendered, only used for calculations! See below for the two valid output-Bobs
  • Hitting the target means the arrows path crosses either one of the two leftmost target walls (|) (That is either (distance-1,3) or (distance-1,4). If at some point the arrow is within those 2m², place the X instead of the wall it hits. The target is always the same height and only its x position can change.). Corner hits or an arrow falling from the sky onto the target does not count.
  • Standard earth g applies (9.81 m/s^2).
  • distance+1 is the end of the field, after that, everything is a miss and no arrow should be rendered.
  • If the arrow hits the target in any other way (distance-1 etc.), no arrow should be rendered.

Miss

This is an example rendering of Bob missing (arrow enters ground at 34m, angle is 45°, time in air is 10s, velocity is ~50 - but there are a lot more possible inputs to cause this output. Just show your program uses the usual formulas to calculate physically "accurate" results.):

                                                                                        +-+
                                                                                        | |
  c\                                                                                    | |
/( )                              v                                                     +++
 L L                              |                                                      |
###########################################################################################

Hit

This is an example rendering of Bob scoring (arrow enters target (= crosses its path)):

                                                                                        +-+
                                                                                     >--X |
 \c/                                                                                    | |
 ( )                                                                                    +++
 L L                                                                                     |
###########################################################################################

Example

  • arrow_x is 7. arrow_y is always 3.
  • angle is 30° or 0.523598776 radians.
  • velocity is 13m/s.
  • distance is 20.

So in order to hit the target, the arrow has to cross (19,3) or (19,4). Everything else will be a miss. In this case, the arrow will enter the ground (means y will be <1.0) at 12.9358m = ~13m after 1.149s.


Limits & Scoring

  • This is , so the shortest solution wins. There are no bonuses.
  • Your program (as in not function) must accept input in the format described above, additional input is not permitted.
  • You don't have to handle wrong/pointless/impossible inputs.
  • Print to whatever is the shortest reasonable output for your language (std, file, ...).
  • I don't care about trailing whitespace.
  • Tip: Width of output is distance+2. The height is apex+1.
\$\endgroup\$
  • 5
    \$\begingroup\$ Can you add the input used to generate the output given please? \$\endgroup\$ – Blue Sep 20 '15 at 13:29
  • 3
    \$\begingroup\$ Why can't you post a function? \$\endgroup\$ – Loovjo Sep 20 '15 at 13:52
  • 2
    \$\begingroup\$ @Mhmd You have to draw him, as stated in the task. The left foot of Bob in the output has to match the x coord. of the shooting Bob. and See below for the two valid output-Bobs \$\endgroup\$ – mınxomaτ Sep 20 '15 at 17:56
  • 1
    \$\begingroup\$ And for those of us who haven't taken physics further than GCSE (or have just forgotten?) \$\endgroup\$ – Blue Sep 20 '15 at 19:11
  • 2
    \$\begingroup\$ @muddyfish Just google for the trajectory equations. \$\endgroup\$ – mınxomaτ Sep 20 '15 at 19:25
2
\$\begingroup\$

Ruby, 482

include Math
def f s,e,l
[s,' '*(l-s.size-e.size),e].join
end
alias p puts
X,o,V,d=$*[0].split(?,).map &:to_i
o*=PI/180
L=X+d
B='| |'
S=''
G=' L L'
p f S,'+-+',L
d.times{|x|y=3+x*tan(o)-(9.81*x**2)/(2*(V*cos(o))**2)
if x==d-1&&(3..5)===y
s='>--X |'
m=(3..4)===y
p f S,m ?B: s,L
p f ' \c/',m ?s: B,L
p f ' ( )',?+*3,L
p f G,'| ',L
elsif y<=1 || x==d-1
p f S,B,L
p f '  c\\',B,L
print f '/( )', y<1? 'V':' ',x
p f S,?+*3,L-x
print f G, y<1? '|':' ',x
p f S,'| ',L-x
break
end}
p ?#*L

Ungolfed

include Math
def fill s,e,l
   [s,' '*(l-s.size-e.size),e].join
end
arrow_x,angle,velocity,distance = $*[0].split(',').map(&:to_i)
angle *= PI/180
length=arrow_x+distance
loss = '| |'
puts fill '','+-+',length
distance.times { |x|
  y = 3 + x*tan(angle) - (9.81*x**2)/(2*(velocity*cos(angle))**2)
  if x == distance-1 && (3..5)===y
    puts fill '',(3..4)===y ? '| |':'>--X |',length
    puts fill ' \c/',(3..4)===y ? '>--X |':'| |',length
    puts fill ' ( )','+++',length
    puts fill ' L L','| ',length
  elsif y<=1 || x==distance-1
    puts fill '',loss,length
    puts fill '  c\\',loss,length
    print fill '/( )', y<1? 'v': ' ', x
    puts fill '','+++',length-x
    print fill ' L L', y<1? '|': ' ', x
    puts fill '',' | ',length-x
    break
  end
}
puts ?#*length

Method

The main equation here is:

trajectory equation

Note: image taken from https://en.wikipedia.org/wiki/Trajectory_of_a_projectile

Where,

y0: initial height (of arrow)  
Ө: the angle  
x: the position of the arrow  
g: gravity (9.81)
v: velocity

What I'm doing is to loop through numbers from 0 to (distance -1) and in every iteration check to see if the arrow hits the ground (or the target)

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