# Rerolling and replacing the lowest result in Anydice

How can I script Anydice to reroll the lowest result, but keep the new result even if it is lower than the original? Until now I was using output [highest 2 of 3d12], which is very similar when you think about it, but this keeps the highest result among the rerolled dice.

I'm trying to model a situation that often happens in our home-made system that uses a mechanic similar to Rogue Games's 2d12. A character wants an ability that allows it to reroll one of the d12, but he must stick to the new result, even if it's worse than the original. I expect that to increase the average roll, but not as much as an D&D5 advantage (highest 1 of 2d20 there, highest 2 of 3d12 for us).

• Hello and welcome! You can take the tour for a quick site introduction (and a badge!). To clarify on the question, the situation you are trying to model is: first roll 2d12, then reroll the lowest of the d12 and then add both (the re-rolled and the not-re-rolled) d12 results together. Is this correct?
– Sdjz
Jul 16, 2018 at 18:09
• yes, that's right. for example: I first rolled 2d12 and got a 5 and a 10. now I roll the 5 again to get a 2. my end result is 12 and the original 5 is ignored. if the dice to be rerolled was random, I believe the probability wouldn't change at all compared to a regular 2d12 roll, but since it's always the lowest value that get's rerolled, it probably will. -- also thanks for the warm welcome, I've been stalking for a bit and I've already taken the tour, but I'll do so again to get the badge. hehe :3
– llk
Jul 16, 2018 at 18:25

Doppelgreener's answer is good if the player must always reroll their lowest die, no matter what they originally rolled. However, if using the ability is optional, the player will most likely choose not to use it if they roll, say, two twelves on their first 2d12 roll.

In general, it's hard to model such optional decision-making processes mathematically, since the rationally optimal decision may depend on what the player's specific goal is (not to mention that players are human, and thus often don't act rationally!). However, in this case, a fairly reasonable class of decision-making rules to consider are those where the player rerolls the lowest die only when it's less than some fixed threshold. In fact, if the player's goal is simply to maximize the expected average result of their roll, their optimal strategy is to reroll a die only when the original value of that die is less than the expected average of the reroll (which, for a d12, is (1+12)/2 = 6.5).

Here's a basic AnyDice script to model that decision-making strategy:

function: reroll lowest of ROLL:s as REROLL:d if less than MIN:n {
LOWEST: (#ROLL)@ROLL       \ the lowest die is sorted last \
if LOWEST >= MIN {
result: ROLL + 0
} else {
REST: {1..#ROLL-1}@ROLL  \ all but the lowest die \
result: REST + REROLL
}
}

output [reroll lowest of 2d12 as d12 if less than 7] named "2d12 replace lowest if < 7"


Note that the function in the code above is generic enough to allow arbitrary initial dice pool sizes (although only the lowest die is ever rerolled) and thresholds, and even provides the option for rerolling with a different die than the original pool had, should that be desired.

Looking at the output of the script, we can see that this "reroll lowest if less than 7" strategy significantly outperforms both "always reroll" and "never reroll":

Of course, we could also consider thresholds other than 7 (≈ 6.5). However, the summary statistics do reveal that, at least as far as the expected average outcome is concerned, 7 is indeed the optimal threshold for rerolling a d12.

All that said, other decision-making rules can still do even better in specific circumstances. For example, if the player is trying to roll to meet or exceed a particular target number, the natural and likely optimal rule is simply to reroll if the sum of their original roll is less than the target, and let the original roll stand otherwise.

Of course, we can model that in AnyDice as well:

function: roll ROLL:s vs TARGET:n with optional REROLL:d reroll {
SUM: ROLL + 0  \ force the sequence to be summed into a single number! \
if SUM >= TARGET {
\ no need to reroll, since we've already met the target \
result: 1
} else {
\ discard and reroll the lowest die \
REST: {1..#ROLL-1}@ROLL
result: REST + REROLL >= TARGET
}
}

loop TARGET over {2 .. 24} {
output 2d12 >= TARGET named "2d12 vs [TARGET]"
output [roll 2d12 vs TARGET with optional d12 reroll] named "2d12 vs [TARGET] with optional reroll"
}


In this case, we unfortunately don't get such nice graphs out, since each comparison against the target number just outputs 0 if the roll fails and 1 if it succeeds. Still, looking at the "transposed" view (which I've linked directly to above), we can see that allowing the reroll is slightly better than granting the player +3 to their roll. For example, an unmodified 2d12 roll has a 61.81% chance of meeting a target of 12, whereas 2d12 with an optional reroll has a 64.53% chance of meeting a target of 15, and a 56.71% chance of meeting a target of 16.

• I believe "7" is the best threshold due to 6.5 being a d12's average value. By that logic, using your function with other dice, here are the following optimal rerolls: d4 = <3; d6 = <4; d8 = <5; d10 = <6; d12 = <7; d20 = <11 (This is merely meant to expand upon your thought, without making a derivative answer based on yours, seeing as this isn't really directly relevant. More possibly beneficial side info.) Jul 17, 2018 at 7:58
• @SoraTamashii: Yes, that's correct. A slightly clearer way is to say that it's optimal (for maximizing the expect score) to reroll any time you roll below average, i.e. below 2.5 for a d4, below 3.5 for a d6, below 4.5 for a d8, and so on. However, AnyDice only works with whole numbers, so I can't write if LOWEST > 6.5. But since die rolls are also always whole numbers, if LOWEST >= 7 (or if LOWEST > 6) gives the same result. Jul 17, 2018 at 8:04

It sounds like you want to roll 2d12 and replace the lowest based on your Rogue Games example. You'll want to use this program to do it:

output [highest 1 of 2d12] + 1d12


Functionally, what you're doing is the following:

• Roll 2d12.
• Take the highest one and keep it.
• No matter what the other result is, we discard and ignore it.
• Roll a new d12 to replace the lowest result.

... so that's what the above program does.

This results in still getting 13 as the most common result, but you have a higher chance to get above average than lower. You can compare and visualise the two methods here: https://anydice.com/program/10bc0/graph/normal

• Your trick, while really clever and elegant, assumes that the player must always reroll their lowest roll, even if they happen to, say, roll a pair of 12s the first time. If the reroll is optional (but binding once taken), things get a bit more complicated. I've tried to analyze that case in my answer. Jul 17, 2018 at 7:30