Skip to content

Abandon setups that are unlikely to win#58

Open
ebblake wants to merge 1 commit into
maneatingape:mainfrom
ebblake:2018-24
Open

Abandon setups that are unlikely to win#58
ebblake wants to merge 1 commit into
maneatingape:mainfrom
ebblake:2018-24

Conversation

@ebblake

@ebblake ebblake commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

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

  • Performance improvement
  • Bug fix
  • Other

Checklist

  • Pull request title and commit messages are clear and informative.
  • Documentation has been updated if necessary.
  • Code style matches the existing code. This one is somewhat subjective, but try to "fit in" by
    using the same naming conventions. Code should be portable, avoiding any architecture
    specific intrinsics.
  • Tests pass cargo test
  • Code is formatted cargo fmt -- `find . -name "*.rs"`
  • Code is linted cargo clippy --all-targets --all-features

Formatting and linting also can be executed by running just
(if installed) on the command line at the project root.

@ebblake

ebblake commented Mar 20, 2026

Copy link
Copy Markdown
Contributor Author

The results are non-monotonic; for example, on one file I tested, I see:

86
After 1059 rounds, 6263 infect units remain
87
After 1082 rounds, 5909 infect units remain
88
Stalemate after 5622 rounds
89
Stalemate after 1142 rounds
90
After 5438 rounds, 434 immune units remain
91
Stalemate after 5423 rounds
92
Stalemate after 5304 rounds
93
Stalemate after 5239 rounds
94
After 2937 rounds, 515 immune units remain
95
After 2889 rounds, 450 immune units remain
96
After 2874 rounds, 473 immune units remain

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.

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.
@ebblake

ebblake commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

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?

@maneatingape

Copy link
Copy Markdown
Owner

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.
This will need some space for me to think and experiment, which has been in short supply lately!

Happy to leave this open, in the queue for now, to give it proper consideration.

@ebblake

ebblake commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants