# Help with "Roll XD12, and keep each middle dice as an individual result"

I've been playing with the idea of using 3d12, keep the middle, for skills rolls in my skirmishes (sort of simulating the curve of a 3d6 roll). But now I what to play with the idea of folding multiple 3d12 middle rolls into one roll by making it "roll Xd12, keep middle dice", with each dice in the middle (i.e. all dice aside from the lowest and highest), representing an individual roll.

So for example, if I'm firing three shots from a machine gun, instead of making three individual 3d12 middle rolls, I would roll 5d12 and keep the middle three values as individual results. I know these two approaches would be mathematically different, I just want to know how much of a difference as you scale up the number of dice in the pool (4d12, 5d12...).

I've been able to model 3d12 middle in AnyDice, but doing something like Xd12, or "4d12, and keep the middle dice as individual results", doesn't really work AFAIK. If anyone can help me conceptualize or model this idea, that would be greatly appreciated.

• Hello and welcome to RPG.SE! Take the tour and maybe have a look at the help center if you need any guidance in posting Q&As here! It is not clear to me how many dice are you keeping whn rolling 4d12, 5d12 etc etc: are you discarding only the the max and the min values? So, if you roll 6d12 you are keeping the 4 middle ones? Commented Jul 3 at 10:17
• Note well that 3d12 and keep the middle will produce a quite differently shaped distribution than the sum of 3d6 does. The former makes extreme results much less likely, but middle results are not as tightly grouped around the average. Commented Jul 3 at 17:23

### Adding the middle dice together

If you just want to add the middle dice together, you can use the @ operator to select individual sorted positions and add them together:

output {2..4}@5d12


Or, perhaps more readably, the middle function:

output [middle 3 of 5d12]


### Counting successes

Unfortunately, the above methods lose information about the individual dice rolls, retaining only the sum. If you want to count the number of dice that met or exceeded a certain target number, fortunately the thresholding operation is commutative with respect to taking the middle dice; that is, we can apply the thresholding before @ or middle and get the correct result. For example, this takes the middle three of five dice and counts how many rolled at least a 7.

TN: 7
output [middle 3 of 5d(d12 >= TN)]


As a bonus, this is vastly more computationally efficient than fully expanding raw pools of d12s, easily handling even a hundred dice.

### General operations

However, not all operations commute with taking the middle dice, for example if you wanted to find the largest matching set or longest straight. Nor do @ or middle expand when sent to a function parameter of type sequence:

function: length S:s {
result: #S
}
output [length [middle 3 of 5d12]]


shows that [middle 3 of 5d12] expands into just 1 value for the sum of the 3 middle dice, rather than 3 values for the individual dice. If you really need to see each individual die, you'll have to send all the dice into a function and then ignore the highest and lowest yourself:

function: evaluate S:s {
loop I over {2..#S-1} {
X: I@S
\ do stuff \
}
}
output [evaluate 5d12]


### Asymptotic behavior

As the number of dice goes to infinity, the fraction of dice rolling each number will tend towards 1/12, and dropping the single highest and lowest die will become less and less impactful proportionally speaking. Picking a random die from the eligible set uniformly at random would therefore approach just rolling a flat d12 rather than the middle of 3d12.

TOTAL:5
MIDDLE: 3
REST: TOTAL-MIDDLE
DROP: REST/2
if 2*(REST/2) < REST {FUDGE: 1} else {FUDGE: 0}
START: 1+DROP
END: TOTAL-DROP-FUDGE
output {START..END}@TOTALd12


This should give you the results for the middle number dice out of total dice, and should work for any combination of odd or even total and middle dice, as long as there no more middle than total die.

By default, if there is an uneven number of die you drop (for example, when you pick 2 middle out of 5), it will pick the middle die skewed towerad the higher end (here the 3rd and 4th highest), but you can reverse this by preceding it with

set "position order" to "lowest first"


Most of the work is done by the output line, that will select the range out of the die ordered by how high they are. All we do before that is massage the start and end number, so it will work for all combinations of odd and even die.

Because Anydice rounds fractions to the nearest integer towards 0, if you have an uneven number of die to drop, after dividing by two to get the number at either end, you miss one (e.g. 3 dice not picked yields 1 at either end), so you have to fudge add that one back in - that is what the FUDGE part is for.

There may be more efficent ways to do this ... if you pick a lot of die out of a lot of die, this can run a long time.

X: 4
Y: X-X/2

output Y@Xd12


or, if you want the lower middle die

X: 4
Y: X-(X+1]/2

output Y@Xd12

• I can believe it's a correct answer, but explaining how it works could help op and future readers to create their own solutions instead of asking here. Commented Jul 2 at 23:36
• @Mołot: It appears to be a correct answer to a misreading of the question. Or, in other words, not correct at all. (Also, the second code snippet has a typo that makes it fail with a syntax error.) Commented Jul 3 at 6:38
• @IlmariKaronen I didn't vote up or down because I don't know the syntax well enough to understand it. Explanation how it works could also help catch errors. Commented Jul 3 at 8:26