If I understand your question correctly, the mechanic you want to model is one where the player:
- has (or is given) a list of \$M\$ target numbers;
- rolls \$N \ge M\$ dice, all at once; and
- tries to match any \$M\$ of the rolled dice to the target list, so that each chosen die roll meets or exceeds the corresponding target number.
So, for example, if my target list was (5, 4, 3, 3) and I rolled (1, 3, 4, 5, 6) on 5d6, I could pick e.g. (6, 5, 4, 3) as my matching rolls and succeed, since each of the matching rolls meets or exceeds the corresponding target number.
If so, this AnyDice function should do what you want:
function: ROLL:s includes at least SEQ:s {
loop I over {1..#SEQ} {
if I@ROLL < I@SEQ { result: 0 }
}
result: 1
}
output [5d6 includes at least {5,4,3,3}]
named "chance of finding 5+, 4+ and two 3+ rolls in 5d6"
Note that this function expects both of its input sequences to be sorted in descending order. This is how AnyDice sorts the results of dice rolls by default, so the first parameter should be fine, but sorting the second parameter (i.e. the sequence of minimum rolls to be found) is up to the user. If you give the function a sequence that is not correctly sorted, it will still run and produce more or less valid-looking results, but they will probably not be what you really expect to get. You have been warned!
(To make the code a bit more foolproof at the expense of performance, we could add the line SEQ: [sort SEQ]
at the beginning of the function to automatically sort the input sequence.)
The reason it works is based on the observation that the player may always match their highest roll to the highest target number, their second-highest roll to the second-highest target number, and so on. If this will not result in a successful match, then neither will any other possible order of the rolled dice!
To convince yourself that this is the case, consider what happens if the player attempts this and finds that their \$K\$-th highest die does not meet the \$K\$-th highest target number. Clearly, none of the lower rolls can then meet that target number either — and, while one of the higher rolls could meet it, if the player chose to match their \$J\$-th highest roll (where \$J < K\$) with the \$K\$-th highest target, they'd then have to match the \$J\$-th highest target with one of the lower rolls, which will also fail.
Thus, all that the AnyDice code needs to do is to compare the sequence of rolled dice (sorted in descending order) with the target sequence (sorted the same way) and check that each roll meets or exceeds its corresponding target number. If any fail to do so, the function returns 0; otherwise it returns 1.
Ps. It's also possible to extend this function so that you can require some matches to be exact. The trick here is that we can first look for the exact matches and set aside any dice needed to satisfy those, and then check if the remaining dice can meet or exceed all of the "at least" targets.
For the first part, it would be convenient if AnyDice had a function for removing the elements of one sequence from another and returning the rest. Unfortunately it doesn't come with such a function built in, but we can write one:
function: remove SUBSEQ:s from SEQ:s {
REST: {}
J: 1
loop I over {1..#SEQ} {
if J <= #SUBSEQ & I@SEQ = J@SUBSEQ { J: J + 1 }
else { REST: {REST, I@SEQ} }
}
result: REST
}
function: ROLL:s includes EXACT:s and at least TARGET:s {
REST: [remove EXACT from ROLL]
if #REST != #ROLL - #EXACT | #REST < #TARGET { result: 0 }
loop I over {1..#TARGET} {
if I@REST < I@TARGET { result: 0 }
}
result: 1
}
output [4d6 includes {} and at least {3,3,2}]
named "chance of finding 3+, 3+, 2+ in 4d6"
output [4d6 includes {3,2,1} and at least {}]
named "chance of finding 3, 2, 1 in 4d6"
output [4d6 includes {6,2} and at least {4}]
named "chance of finding 6, 4+, 2 in 4d6"
(Note: Again, the functions assume that all input sequences are sorted in descending order, and will return incorrect results if they aren't. Also, the [remove SUBSEQ from SEQ]
function above is a bit finicky: if it doesn't find some number that it's trying to remove, it gets stuck on that number and won't actually remove any smaller numbers in SUBSEQ
from SEQ
either. However, for our purposes that's OK, since we're failing the roll unless all the exact targets are found and removed anyway.)