1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
vA, vB, vC = 0, 0, 0 found = False limit = 0 # Calculate the separations between A, B and C for given speeds and time def pos(vA, vC, t): posA = t * vA % 400 posB = t * vA * 1.42 % 400 posC = t * vC % 400 dAB = min(abs(posA - posB), 400 - abs(posA - posB)) dAC = min(abs(posA - posC), 400 - abs(posA - posC)) dBC = min(abs(posB - posC), 400 - abs(posB - posC)) return [dAB, dAC, dBC] # Two loops to calculate the speeds for A, B and C for v in range(1, 10): for p in range(43, 100): vp = round(v * (1 + p / 100), 2) if sorted(pos(v, vp, 4625)) == [85, 85, 170]: vA, vB, vC = v, v * 1.42, vp # Report the speeds found print(f"A, B and C's speed are {vA}, {vB} and {vC} (m/s)") # Find the time where the separations are 90 m for t in range(4626, 10001): if sorted(pos(vA, vC, t)) == [90, 90, 180]: found = True print(f"A, B and C are separated 90 m after {t} seconds.") limit = t if not found: print(f"No solution found within {limit} seconds") |

Time 7250s Speeds: 4.0 5.68 6.44 positions 200 380.0 290.0 separation: 90

Time 29875s Speeds: 4.0 5.68 6.44 positions 300 90.0 395.0 separation: 95 overlap

Time 7500s Speeds: 4.0 5.68 6.44 positions 0 200.0 300.0 separation: 100 overlap

Time 5125s Speeds: 4.0 5.68 6.44 positions 100 310.0 205.0 separation: 105 overlap

Time 7750s Speeds: 4.0 5.68 6.44 positions 200 20.0 310.0 separation: 110 overlap

Time 29625s Speeds: 4.0 5.68 6.44 positions 100 270.0 385.0 separation: 115 overlap

Time 7000s Speeds: 4.0 5.68 6.44 positions 0 160.0 280.0 separation: 120 overlap

Time 5625s Speeds: 4.0 5.68 6.44 positions 100 350.0 225.0 separation: 125 overlap

Time 8250s Speeds: 4.0 5.68 6.44 positions 200 60.0 330.0 separation: 130 overlap

As you can see, everything over the original separation has a separation overlapping the start/finish line.

Thanks, Frits for suggesting Wing Personal. I downloaded it. Works fine including PEP 8 reformatting. I do prefer the simplicity of the IDLE user interface.

]]>somewhat unsatisfactory early exit using exit()). I have updated it but

I will soon go back to using exit() as Python’s facilities for breaking out

of nested loops (without adding flags) are not very good.

On your point about my prefix on ‘t’, it was ‘defensive programming’ since

I didn’t have a proof that it was unnecessary. EDIT: But the proof is easy

so either a prefix or a suffix is sufficient.

I think you forgot to use variables, i, j and k.

Do you need t[2] – 400 in your check function?

Adding t[0] + 400 seems to be sufficient.

Will you post an explanation of range(161, 162) ‘after a few days’?

It is correct though.

We could already check Ann’s and Beth’s distances on gap difference before looking at Chad but as range(1, 10) is quite limited this is not really an issue.

]]>In Wing Python IDE which Brian suggested to me there also is a “Reformat PEP8” option.

So far I like using Wing to test Python code.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
def trackrun(): ti = 4625 # Ann's speed in m/s for Ann in range(1, 10): # Beth's speed Beth = Ann * 1.42 # iterate through multipliers of Ann's speed. Chad is fastest for C in range(143, 200): # Chad's speed Chad = Ann * C / 100 # Calculate Ann's Beth's and Chad's track positions after 4625 seconds Annr = (ti * Ann) % 400 Chadr = (ti * Chad) % 400 Bethr = (ti * Beth) % 400 abc = sorted([Annr, Bethr, Chadr]) # test for 85m separation if (abc[2] - abc[1] == 85 and (abc[1] - abc[0] == 85 or abc[0] + 400 - abc[2] == 85)): print("Time is 4625s Speeds:", float(Ann), Beth, Chad, "positions", Annr, Bethr, Chadr) # iterate through times beyond 4625 seconds # testing for 90m separation solcount = 0 while True: ti += 1 # Calculate the trio's new track positions Annr = (ti * Ann) % 400 Bethr = (ti* Beth ) % 400 Chadr = (ti * Chad) % 400 abc = sorted([Annr, Bethr, Chadr]) if (abc[2] - abc[1] == 90 and (abc[1] - abc[0] == 90 or abc[0] + 400 - abc[2] == 90)): print("Time is", str(ti) + "s", "Speeds:", float(Ann), Beth, Chad, "positions", Annr, Bethr, Chadr) mins, secs=divmod(ti, 60) hrs, mins=divmod(mins, 60) print(hrs, "hrs", mins, "mins", secs, "secs") solcount += 1 if solcount == 5: return trackrun() |

You can publish the solution on the manual solutions site I manage here where the rule we apply there is ‘after a few days’.

I do sometimes publish manual solutions here when a teaser is not amenable to a Python solution but its not the norm and I don’t want to encourage this because the primary focus here is on Python rather than puzzles.

Moreover I want to encourage people to install Python and find the answers rather than just looking for answers here (even downloading and running the code published here is a start!).

You are right about missing some solutions. I originally had a complete check for gaps but I took it out when I found it made no difference. It was also a bit messy but I will probably put it back if I can find a more elegant version.

]]>You can check your code with ‘pydocstyle’, or if you want it done automatically, you can use ‘autopep8’ to do it. Both of these are Python applications that can be installed with pip if you know how to use it. If not I can talk you through the installation process via email (or other method) if you need help. I haven’t used either of these tools as I have just learnt the main rules – to be honest there is not much I feel the need to change in your code – in the main it is spaces around operators and spaces after commas, both of which make code easier to read. There is a nice exposition of PEP8 here which is worth a read.

]]>You seem to miss the situation when distances mod 400 are fi 10, 230, 320 at the end.

In this case they are also 90 meters apart.

Together with a friend I decided to do a manual solution this time which wasn’t easy. We even used primality. I assume I can publish it next Sunday.

]]>