Predict a Collision: Will the robber get away?

20

1

Think of a road as a number line, starting at 0 and continuing indefinitely:

.................................................................

There are two cars on the road: C and R. C is the cop who is trying to catch R, the robber. C starts at 0, and R starts somewhere on the road:

C.............................R..................................

The cop is already moving - he's chasing the robber. He has a constant speed. The robber just hopped into his car. He's accelerating. Each tick, the robber's speed increases by his acceleration.

Say the cop's speed is 7 and the robber's acceleration is 1. If the robber starts at 30, this is what the road would look like each tick:

C.............................R..................................
.......C.......................R.................................
..............C..................R...............................
.....................C..............R............................
............................C...........R........................
...................................C.........R...................
..........................................C........R.............
.................................................C........R......

After the last tick above, the robber's speed is equal to the cop's, and he's still ahead. Since the cop is moving at a constant speed and the robber is still speeding up, the robber escapes, so you output a truthy value. However, if the cop's speed had been 9...

C.............................R..................................
.........C.....................R.................................
..................C..............R...............................
...........................C........R............................
....................................C...R........................
.............................................X...................

... then the cop catches up to the robber before the robber can get away (marked by the X), so you output a falsey value.

Your Task

Given three inputs - the cop's speed, the robber's position, and the robber's acceleration - determine whether or not the robber will get away.

Rules

  • The cop always starts at 0.
  • All inputs will be positive integers.
  • The cop catches the robber if, after any tick, the cop's position is greater than or equal to the robber's position.
  • The robber gets away when he hasn't been caught yet and his speed is greater than the cop's.
  • Your program must terminate after output.
  • The robber accelerates before he moves each tick.

Test Cases

Cop Speed, Robber Position, Robber Acceleration -> Output

7, 30, 1 -> truthy
9, 30, 1 -> falsey
2, 1, 3 -> truthy
100, 100, 50 -> truthy
60, 60, 20 -> falsey
10, 1, 1 -> falsey
10, 50, 2 -> truthy
11, 50, 2 -> truthy
12, 50, 2 -> truthy
13, 50, 2 -> truthy
14, 50, 2 -> truthy
15, 50, 2 -> truthy
16, 50, 2 -> falsey
17, 50, 2 -> falsey
18, 50, 2 -> falsey
100, 451, 10 -> truthy

Reference Python 3 implementation that creates a visual also: Try it online!

This is , so shortest answer in bytes wins.

Stephen

Posted 2017-08-11T20:06:23.787

Reputation: 12 293

Sandbox (deleted) – Stephen – 2017-08-11T20:06:32.167

8Ohhhh... this isn't a cops and robbers challenge; that makes more sense. – Magic Octopus Urn – 2017-08-11T20:41:35.347

Is the input guaranteed to be in the given format, or can we take input in whatever format we want (like robber acceleration, cop speed, robber position instead)? – TehPers – 2017-08-11T20:47:18.317

@TehPers whatever you want (consistent each time), but if you're doing something different say so in your answer – Stephen – 2017-08-11T20:48:20.380

2Test case request: 100, 451, 10. (The answers don't all agree on the result). – Neil – 2017-08-11T23:35:01.547

@Neil added, good test case since cop is next to robber twice – Stephen – 2017-08-11T23:51:27.607

Answers

2

Jelly, 9 bytes

_⁵Ḥ¤²÷÷8<

Try it online!

Port of Leaky Nun's Python 3 answer.

(full program) Takes arguments in order acceleration, position, speed.

Erik the Outgolfer

Posted 2017-08-11T20:06:23.787

Reputation: 38 134

16

Python 3, 29 bytes

lambda s,p,a:(a-2*s)**2<8*a*p

Try it online!

Explanation

The cop's position at time t is st.

The robber's position at time t is a(t)(t+1)/2 + p.

The signed distance from the cop to the robber is (a/2)t^2 + (a/2-s)t + p.

It never reaches zero if the discriminant is negative, the discriminant being (a/2 - s)^2 - 4(a/2)(p) = [(a-2s)^2-8ap]/4, which has the same sign as (a-2s)^2-8ap.

Leaky Nun

Posted 2017-08-11T20:06:23.787

Reputation: 45 011

Try it online! - Shameless port to 05AB1E for 9-bytes (you may take it, as I'm bad with Physics, and probably couldn't do a just explanation). – Magic Octopus Urn – 2017-08-11T21:29:09.877

1Doesn't this fail for the "100, 451, 10 -> truthy" test case? – Mark S. – 2017-08-13T16:15:09.407

Am I missing something, or should we also check if there's an integer between the solutions of the quadratic equation (a/2)t^2 + (a/2-s)t + p = 0 -> 10t^2 - 50t + 61 = 0? For example, for 60, 61, 20 the robber easily gets away (the equation solutions: 2.1 and 2.9 being both between 2 and 3). – mackoo13 – 2017-08-24T10:17:50.400

5

Japt, 13 bytes

²/W-V-U<o0W x

Test it online!

Explanation

U, V, and W are the implicit inputs. First, with Uo0W we create the range [0, W, 2*W, ...] until it reaches U. x then sums this, which gives how far the robber travels before reaching cop speed. We'll call this r.

Now, how far does the cop travel in this time? We can calculate this using U * (U // W - 1), which can be rearranged to (U * U) // W - U. We'll call this c.

Now for the final step: does the robber get away? All we need to do here is check if c < r + V, or rearranged, c - V < r.

ETHproductions

Posted 2017-08-11T20:06:23.787

Reputation: 47 880

5

Cubically, 61 bytes

$:7(U1R3U1F3D2*1-1/1)6+7$-77*6$(-77777777D2F1U3R1U3!0{<0%6&})

Try it online! For this to work in TIO, you may need to replace & with &1 due to a bug in the interpreter.

This is a shameless port of Leaky Nun's answer. Input is in the form a s p, where a is robber's acceleration, s is cop's speed, and p is robber's position.

If the acceleration is too high, this will fail. I don't know how high of an acceleration this program will support, but I know it isn't any higher than 1260. The limiting factor is that it stores the acceleration in the cube and checks if the cube is solved by checking only if the top face's sum is 0 (an incomplete check). It seems to work for acceleration = 50, but I haven't tested to see how high it can get.

How it works

$:7(U1R3U1F3D2*1-1/1)6
$:7                             Store the first number in the notepad
   (                )6          Loop until notepad is 0
    U1R3U1F3D2                  Rotate the cube a certain way
              *1-1/1            Subtract 1 from the notepad

+7$-77*6                
+7                              Add first input to the notepad
  $-77                          Subtract second input from the notepad twice
      *6                        Multiply the notepad by itself (square it)

$(-77777777D2F1U3R1U3!0{<0%6&})
$                               Get next input
 (                            ) Loop indefinitely
  -77777777                     Subtract third input 8 times
           D2F1U3R1U3           "Unrotate" the cube
                     !0{     }  If the top face is 0
                        <0        Check if notepad < 0, store in notepad
                          %6      Output notepad as number
                            &     End the program

TehPers

Posted 2017-08-11T20:06:23.787

Reputation: 899

1The 6 in %6 and *6 can be removed as they now can be called implicitly. – MD XF – 2017-10-08T21:51:55.507

4

Pyth, 11 bytes

This takes them in this order: Robber Acceleration, Cop Speed, Robber Position separated by a newline (as shown in the test suite).

<^-QyE2*8*E

Test Suite or Try it online!

Mr. Xcoder

Posted 2017-08-11T20:06:23.787

Reputation: 39 774

4

Pyke, 14 bytes

Port of totallyhuman's Python answer. Returns 1 for truthy and 0 for falsy.

hQee-XQ1@Qe*}<

Try it here!


Explanation

hQee-XQ1@Qe*}< - Full program with implicit input added in the beginning (which automatically splits the components)

h              - First input
 Qee           - Last Input halved (through integer division)
    -          - Subtact the above
     X         - Square.
             < - Is smaller than?
      Q1@      - The second input
         Qe*   - Multiplied by the last input
            }  - Doubled

Pyke, 15 bytes

My very first Pyke answer! Port of my Pyth solution, which is inspired by Leaky's Python submission. Returns 1 for truthy and 0 for falsy.

eQh}-XQe8*Q1@*<

Try it here!


Explanation

eQh}-XQe8*Q1@*< - Full program with implicit input added in the beginning (which automatically splits the components)

e               - End; last input in this case
 Qh             - The first input
   }            - Double
    -           - Subtact the above
     X          - Square.
              < - Is less than?
      Qe        - Last Input
        8*      - Times 8 
             *  - Multiplied by
          Q1@   - The second input.

Mr. Xcoder

Posted 2017-08-11T20:06:23.787

Reputation: 39 774

2

Python 2, 62 bytes

P=s=0;S,p,a=input()
while(s<S)*(P<p):s+=a;p+=s;P+=S
print s>=S

Try it online!

Mr. Xcoder

Posted 2017-08-11T20:06:23.787

Reputation: 39 774

2

Ruby, 29 27 25 bytes

->c,p,a{(a-c-c)**2<8*p*a}

Try it online!

Got from 29 to 27 by stealing the idea of multipliying both sides by 4. (Leaky Nun's python answer)

Got from 27 to 25 by removing parens around lambda parameters (thanks totallyhuman)

itdoesntwork

Posted 2017-08-11T20:06:23.787

Reputation: 121

2Welcome to PPCG! You can golf your answer a little bit by renaming your function from hit to h or similar. You may also be able to save some bytes by changing from a method to a proc, like so: ->c,p,a{(c-a*0.5)**2<2*p*a} – Conor O'Brien – 2017-08-11T20:46:11.433

1You also need to replace collision in your TIO link with the correct method name. – Leaky Nun – 2017-08-11T20:47:16.717

Pssst, look at their username. :P – totallyhuman – 2017-08-11T20:50:12.030

1I'm pretty sure you don't need the parentheses around c,p,a. – totallyhuman – 2017-08-11T21:08:36.167

2

C# (.NET Core), 33 bytes

(v,p,a)=>v/a*v<p+v/a*(1+v/a)*.5*a

Try it online!

I feel like this is off by one somewhere, but it passes for all test cases so it's possible that there simply aren't any test cases where the cop overtakes the robber for a single tick, or it might just work despite my reservations.

Kamil Drakari

Posted 2017-08-11T20:06:23.787

Reputation: 3 461

1

Python 2, 31 30 29 bytes

-1 byte thanks to Mr. Xcoder.

Started off as a port of the Ruby answer.

lambda c,p,a:(c-a/2)**2<2*p*a

Try it online!

totallyhuman

Posted 2017-08-11T20:06:23.787

Reputation: 15 378

1.5 instead of 0.5 >_> – Mr. Xcoder – 2017-08-11T20:59:45.470

Haha, I thought it'd be just that much to port. XD Thanks! – totallyhuman – 2017-08-11T21:00:36.330

a/2 uses integer division, could this go wrong? – itdoesntwork – 2017-08-11T21:03:46.403

It does use integer division. While I haven't worked out any math (to be honest, I'm not sure I could), it works for all the test cases. – totallyhuman – 2017-08-11T21:09:42.003

1

Swift 3, 55 bytes

Note that I declared the variable t because the expression would be too complex to be solved in reasonable time otherwise (Swift's fault!).

func f(a:Int,b:Int,c:Int){let t=c-2*a;print(t*t<8*c*b)}

Test Suite.

or 55 bytes, exact closure equivalent (I need the last part because it is a complex construct):

{let t=$2-2*$0;return t*t<8*$2*$1}as(Int,Int,Int)->Bool

Test Suite.

Swift 3, 57 bytes

func f(a:[Int]){let t=a[2]-2*a[0];print(t*t<8*a[2]*a[1])}

Test Suite.

Mr. Xcoder

Posted 2017-08-11T20:06:23.787

Reputation: 39 774

1

Python 2, 30 bytes

lambda c,p,a:c/a*(c-a+c%a)/2<p

Try it online! The cop has c/a ticks in which to catch the robber, after which it has out-accelerated the cop. At the first tick the cop gains c-a on the robber while on the last tick he only gains c%a. Thus the total that the cop can gain is the product of the number of ticks and the average distance per tick. This is simply compared to the initial lead the robber has.

Neil

Posted 2017-08-11T20:06:23.787

Reputation: 95 035

1

TI BASIC (TI-83/84 series), 18 bytes

Prompt C,R,A
(A-2C)²<8RA

Yet another port of itdoesntwork's influential Ruby solution.

Execution

Input order is cop speed, robber position, robber acceleration.

C=?7
R=?30
A=?1
               1

Jakob

Posted 2017-08-11T20:06:23.787

Reputation: 2 428

1

Recursiva, 19 16 bytes

>b*I/acIH+-ac%ac

Try it online!

officialaimm

Posted 2017-08-11T20:06:23.787

Reputation: 2 739

1

Retina, 79 bytes

\d+
$*
$
;
{`(1+);
$1;$1
,(1+;(1+))
$2,$1
1`(1+),\1
$1,
.*,,.*

^(1+),.*;\1.*
1

Try it online! Explanation:

\d+
$*

Convert input to unary.

$
;

Make room for the robber's speed.

{`(1+);
$1;$1

Accelerate the robber on each pass.

,(1+;(1+))
$2,$1

Move the robber away from the cop.

1`(1+),\1
$1,

Move the cop towards the robber.

.*,,.*

Has the cop caught the robber?

^(1+),.*;\1.*
1

Does the robber out-speed the cop?

Neil

Posted 2017-08-11T20:06:23.787

Reputation: 95 035