Abandon setups that are unlikely to win#58
Conversation
|
The results are non-monotonic; for example, on one file I tested, I see: However, it might be possible to do some sort of linear or quadratic fit to the first few points (run a full trial of 0, 1, and 2) and from there pick a ballpark that is even closer to the actual answer, and maybe run +- 5 from there to make sure the non-monotonic mess isn't hiding the real answer. |
d8c8c2d to
f008603
Compare
2018 day 24 is somewhat input sensitive; on my machine, my input file completed in 2.5ms at a boost of 42, but another one scraped from the megathread took 5.0ms and had to reach a boost of 90. With some tracing, I observed that the higher the boost got, the closer the ratio between baseline infect_hp/immune_eff vs. immune_hp/infect_eff. It is still possible to win even when the ratios are not equal (thanks to the group attributes tweaking actual damage), but appears that any difference larger than double is going to favor the infection - there simply won't be enough hit points to survive long enough for immune to win. Capture this as a heuristic to bypass low-value boosts, so that the time is spent on battles more likely to matter. For the files I tested, this cuts runtime on my machine to 2.0ms, regardless of whether the pre-patch file was 2.5ms or 5.0ms.
|
I'm not coming up with any more reliable approach for getting at the center of the non-monotonic sweet spot short of incrementing, but skipping non-plausible steps does provide a nice speedup on my machine (for my input: 2.7ms -> 2.3ms; for another input: 4.4ms -> 1.9ms). Any thoughts on this patch? |
I like the speed up, but need to first convince myself that the heuristic will never mispredict. Happy to leave this open, in the queue for now, to give it proper consideration. |
|
My reasoning for why I think the patch does not mispredict: if there were no weaknesses or immunities, then a ratio of own_hp/enemy_eff says roughly how many turns before the soonest the enemy can win, and enemy_hp/own_eff is roughly how many turns before the soonest the attacker can defeat the enemy. I say roughly, because some eff points are lost when killing off a group with more eff than the hp remaining in that group. Weaknesses complicate the problem a bit, but in the worst case, if weaknesses are perfectly paired, one group can defeat the other twice as fast. Thus, I picked a ratio of 2 (one team finishing twice as fast as the other) as the minimum viable starting point - any power level where the ratio is greater than two will probably need so many more turns for the immune system to defeat the infection that even double-attack from infection weaknesses won't sway the battle from the immune system finishing its turns first. But I also understand the desire to plot the various ratios over various power levels, to see the range in which it converges, and how the convergence of the attack ratios compares to the resulting score of whichever team wins, or when the battle becomes a draw. |
Description
2018 day 24 is somewhat input sensitive; on my machine, my input file completed in 2.5ms at a boost of 42, but another one scraped from the megathread took 5.0ms and had to reach a boost of 90. With some tracing, I observed that the higher the boost got, the closer the ratio between baseline infect_hp/immune_eff vs. immune_hp/infect_eff. It is still possible to win even when the ratios are not equal (thanks to the group attributes tweaking actual damage), but appears that any difference larger than double is going to favor the infection - there simply won't be enough hit points to survive long enough for immune to win.
Capture this as a heuristic to bypass low-value boosts, so that the time is spent on battles more likely to matter. For the files I tested, this cuts runtime on my machine to 2.0ms, regardless of whether the pre-patch file was 2.5ms or 5.0ms.
Type of change
Checklist
using the same naming conventions. Code should be portable, avoiding any architecture
specific intrinsics.
cargo testcargo fmt -- `find . -name "*.rs"`cargo clippy --all-targets --all-featuresFormatting and linting also can be executed by running
just(if installed) on the command line at the project root.