-1

Given I have the vector and a target number

target.mountain <- 10

Roll_dice <- sample(1:6, 4, replace=TRUE)

With Roll_dice producing [1] 6, 5, 3, 2 as an example

How can I produce a list of all numbers in Roll_dice with all the ways of adding them together by combining either 2, 3 or 4 of the values in Roll_dice together in a list

For example [1] 2, 3, 5, 5, 6, 7, 11, ....

  • this sounds like a [XY-problem](https://en.wikipedia.org/wiki/XY_problem)... what is the problem (behind this question) you are trying to solve. What is the use of `target.mountain`? – Wimpel Mar 30 '21 at 13:10
  • Although I'm unfamiliar with what you mean by XY problem, I am trying to create an If statement which if the value of target.mountain can be created from the 4 dice rolls then complete a certain action and if not do something else. Ive tried to simplify the problem as i keep getting downvoted :( – KnowsNothingAboutCode Mar 30 '21 at 13:15
  • added a link inmy original comment. An XY-problem is when someone asks for X, becasue he believes it will help him solve Y... But this is not always the case.. better is to explain Y. – Wimpel Mar 30 '21 at 13:18
  • At the moment I have code which takes the given dice roll and then tries to create as many 'target.mountain' values as it can from the 4 values (with no replacement). If the values which aren't used in the forming of the 'target.mountain' value are not in the range 5:10 then sum them together to create a value in this range. If this is not possible then just return the created 'target.mountain' value and the values in Roll_dice which are not used – KnowsNothingAboutCode Mar 30 '21 at 13:24
  • It's from a game called Mountain goats where 4 dice are rolled to form numbers 5:10 which can then be used as 'moves'. So my code aims to target specific mountains (with given conditions which are prior to this problem). As you can move on multiple mountains at once if you can move on another mountain (as the other two values lie in the range 5:10) then do so. – KnowsNothingAboutCode Mar 30 '21 at 13:25

2 Answers2

2

I would like you to check out the RccpAlgos-package, which has some awesome (and fast!) functions for fast operations on combinations/permutations with constraints.

update

library(RcppAlgos)
library(vecsets)
library(data.table)

target.mountain <- 10
Roll_dice       <- c(5, 5, 3, 2)

L <- lapply( 2:4, function(x) {
  as.data.table(comboGeneral( Roll_dice, 
                x, 
                constraintFun = "sum", 
                comparisonFun = "==", 
                limitConstraints = target.mountain ),
                keep.rownames = TRUE )
})
# [[1]]
# V1 V2
# 1:  5  5
# 
# [[2]]
# V1 V2 V3
# 1:  2  3  5

#so 5-5 of 2-3-5 can be chosen to get to 10

#remaining dice
DT <- data.table::rbindlist( L, fill = TRUE )

remains <- lapply( transpose(DT), function(x) {
  v <- as.vector(x)
  v <- v[ !is.na(v) ]
  sum( vecsets::vsetdiff( Roll_dice, v) )
})

remains
#witrh leftovers:
# $V1
# [1] 5
# 
# $V2
# [1] 5

old answer

library(RcppAlgos)
target.mountain <- 10
Roll_dice <- c(6, 4, 5, 5)
sapply( 2:4, function(x) {
  comboGeneral( Roll_dice, 
                x, 
                constraintFun = "sum", 
                comparisonFun = "==", 
                limitConstraints = target.mountain )
})

# [[1]]
#      [,1] [,2]
# [1,]    4    6
# [2,]    5    5
# 
# [[2]]
# [,1] [,2] [,3]
# 
# [[3]]
# [,1] [,2] [,3] [,4]
Wimpel
  • 26,031
  • 1
  • 20
  • 37
  • Very nice, thank you so much for the pointers. So now we have the values of the dice roll which give my target.mountain value, how can I return the 'target.mountain' value (as many times as it can be created) along with the other values of the dice which aren't used. Ideally if the values of the leftover/unused dice lie don't lie in the range 5:10 then add the two (if there are 2) dice together so that they do. Sorry I'm asking so much, I'm just so so clueless! – KnowsNothingAboutCode Mar 30 '21 at 13:55
  • I updates my answer above, so you can see what sums you can make with the dice that are left.. – Wimpel Mar 30 '21 at 15:17
  • Wow, again thank you so much. Honestly some of these functions I've never even heard of but you're describing it really well. I've tested it within my model in which it works for most combinations bar a few, I'm going to have an attempt at fixing this based on what you've shown me. But thank you so so much for what you're doing! The problems occur when the remaining dice sum to >10 (which isn't allowed as they need to be in the range 5:10) and also when the target number appears in the roll >1 time (i.e. 5, 5, 6, 6 with a target of 6 would return 6 and 16) – KnowsNothingAboutCode Mar 31 '21 at 18:03
  • then you can repeat the comboGeneral-function on the remaining dice. So in stead of `sum( vecsets::vsetdiff( Roll_dice, v) )` you perform another comboGeneral with a constraint. – Wimpel Mar 31 '21 at 18:44
  • I've tried to change these over but I've run into a few problems again (sorry!). As far as I can tell your code combines to create 1 target.mountain (doesn't account for if 2 can be made). Then sums the remaining values not used to whatever they sum to (which is great if its in the range 5:10, but often its greater so has no use unfortunately). You mentioned it would work if I changed the sum(....) part over, but I don't get how to put the remain values in correctly to the new comboGeneral part. However none of this works if the dice rolls cannot create the target value – KnowsNothingAboutCode Mar 31 '21 at 23:20
  • If the target value cannot be created then all I'd want to do is just create as many values in the range 5:10 – KnowsNothingAboutCode Mar 31 '21 at 23:21
0

Something like this?

> sapply(
+   2:4,
+   function(k) combn(Roll_dice, k, sum)
+ )
[[1]]
[1] 11  9  8  8  7  5

[[2]]
[1] 14 13 11 10

[[3]]
[1] 16

Or do you need this?

> lapply(
+   setNames(2:4, 2:4),
+   function(k) target.mountain %in% combn(Roll_dice, k, sum)
+ )
$`2`
[1] FALSE

$`3`
[1] TRUE

$`4`
[1] FALSE
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81