4

In a game the only scores which can be made are 2,3,4,5,6,7,8 and they can be made any number of times

What are the total number of combinations in which the team can play and the score of 50 can be achieved by the team.

example 8,8,8,8,8,8,2 is valid 8,8,8,8,8,4,4,2 is also valid. etc...

user804979
  • 913
  • 1
  • 6
  • 9
  • What would this specifically have to do with Java? You could solve this problem in any language. – Makoto Dec 05 '12 at 03:03
  • This is DP with 2 params (current sum, index (up to which has been considered)). – nhahtdh Dec 05 '12 at 03:07
  • @RavindraBagale - No that is not the answer as its not a permutation problem. – user804979 Dec 05 '12 at 03:22
  • @nhahtdh: Dynamic programming, well yes i agree on that ..but what is the cache which you would maintain, would you maintain a cache of all combinations to make sure you don't repeat them with the next index..or can you explain me the state that you will maintain understand your answer better. – user804979 Dec 05 '12 at 03:31
  • 1
    Please clarify whether you intend order to be significant (e.g. is 8,8,8,8,8,8,2 different from 8,8,8,8,8,2,8?) – j_random_hacker Dec 05 '12 at 16:13
  • possible duplicate of [DP - Counting coin change](http://stackoverflow.com/questions/11861038/dp-counting-coin-change) – Raymond Chen Dec 06 '12 at 07:34

4 Answers4

2

The problem can be solved with dynamic programming, with 2 parameters:

  • i - the index up to which we have considered
  • s - the total score.

f(i, s) will contain the total number of ways to achieve score s.

Let score[] be the list of unique positive scores that can be made.

The formulation for the DP solution:

f(0, s) = 1, for all s divisible to score[0]
f(0, s) = 0, otherwise

f(i + 1, s) = Sum [for k = 0 .. floor(s/score[i + 1])] f(i, s - score[i + 1] * k)
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
  • Looks nice, but the bottom row should start `f(i, s) = ...` (or both appearances of `score[i]` should be replaced with `score[i + 1]`). – j_random_hacker Dec 05 '12 at 16:11
1

This looks like a coin change problem. I wrote some Python code for it a while back.

Edited Solution:

from collections import defaultdict

my_dicto = defaultdict(dict)

def row_analysis(v, my_dicto, coins):
    temp = 0
    for coin in coins:
        if v >= coin:
            if v - coin == 0: # changed from if v - coin in (0, 1):
                temp += 1
                my_dicto[coin][v] = temp
            else:                
                temp += my_dicto[coin][v - coin]
                my_dicto[coin][v] = temp
        else:
            my_dicto[coin][v] = temp
    return my_dicto

def get_combs(coins, value):
    '''
    Returns answer for coin change type problems.
    Coins are assumed to be sorted.

    Example:
        >>> get_combs([1,2,3,5,10,15,20], 50)
        2955
    '''
    dicto = defaultdict(dict)

    for v in xrange(value + 1):
        dicto = row_analysis(v, dicto, coins)

    return dicto[coins[-1]][value]

In your case:

>>> get_combs([2,3,4,5,6,7,8], 50)
3095
Akavall
  • 82,592
  • 51
  • 207
  • 251
1

It is like visit a 7-branches decision tree.

The code is:

class WinScore{
static final int totalScore=50;
static final int[] list={2,3,4,5,6,7,8};
public static int methodNum=0;

static void visitTree( int achieved , int index){
        if (achieved >= totalScore ){
                return;
        }
        for ( int i=index; i< list.length; i++ ){
                if ( achieved + list[i] == totalScore ) {
                        methodNum++;
                }else if (  achieved + list[i] < totalScore ){
                        visitTree( achieved + list[i], i );
                }
        }
}
public static void main( String[] args ){
        visitTree(0, 0);
        System.out.println("number of methods are:" + methodNum );

}
}
output:
number of methods are:3095
Richard
  • 546
  • 4
  • 6
  • 1
    There are duplicates in your result, since 2,2,...,3 and 2,3,2,...2 are counted separately, which is incorrect since the order is not important. – nhahtdh Dec 05 '12 at 05:14
  • 1
    This is the corrected version: http://ideone.com/dxLHRd You will not reconsider a score if you have chosen a higher one. – nhahtdh Dec 05 '12 at 05:20
  • Well i think the duplicates are actually different ways in which plays can happen to achieve a result, so they should be ok..according to the definition of the problem. – user804979 Dec 05 '12 at 05:39
  • 1
    @user804979: You should be clear about it, since the solution may differ. – nhahtdh Dec 05 '12 at 06:26
  • @nhahtdh: I think the number can be duplicate any times and in any order. Can you clarify it? Suggest the total score is 7, what is the possible answer? I think there are 7 methods: {2,2,3},{2,3,2},{2,5}, {3,2,2},{3,4},{5,2}, {7} – Richard Dec 05 '12 at 07:51
  • 1
    You take order into consideration, so 2,2,3 and 2,3,2 are different. I consider them to be the same and count once. The question actually asks for the number of combinations, not permutation, so the order shouldn't be taken into consideration. – nhahtdh Dec 05 '12 at 08:21
  • I edited the code as you suggested, taking 2,2,3 and 2,3,2 are the same. – Richard Dec 06 '12 at 07:32
0

Just stumbled on this question - here's a c# variation which allows you to explore the different combinations:

static class SlotIterator
{
    public static IEnumerable<string> Discover(this int[] set, int maxScore)
    {
        var st = new Stack<Slot>();
        var combinations = 0;
        set = set.OrderBy(c => c).ToArray();
        st.Push(new Slot(0, 0, set.Length));
        while (st.Count > 0)
        {
            var m = st.Pop();
            for (var i = m.Index; i < set.Length; i++)
            {
                if (m.Counter + set[i] < maxScore)
                {
                    st.Push(m.Clone(m.Counter + set[i], i));
                }
                else if (m.Counter + set[i] == maxScore)
                {
                    m.SetSlot(i);
                    yield return m.Slots.PrintSlots(set, ++combinations, maxScore);

                }
            }
        }
    }

    public static string PrintSlots(this int[] slots, int[] set, int numVariation, int maxScore)
    {
        var sb = new StringBuilder();
        var accumulate = 0;
        for (var j = 0; j < slots.Length; j++)
        {
            if (slots[j] <= 0)
            {
                continue;
            }
            var plus = "+";
            for (var k = 0; k < slots[j]; k++)
            {
                accumulate += set[j];
                if (accumulate == maxScore) plus = "";
                sb.AppendFormat("{0}{1}", set[j], plus);
            }
        }

        sb.AppendFormat("={0} - Variation nr. {1}", accumulate, numVariation);
        return sb.ToString();
    }
}
public class Slot
{
    public Slot(int counter, int index, int countSlots)
    {
        this.Slots = new int[countSlots];
        this.Counter = counter;
        this.Index = index;
    }

    public void SetSlot(int index)
    {
        this.Slots[index]++;
    }

    public Slot Clone(int newval, int index)
    {
        var s = new Slot(newval, index, this.Slots.Length);
        this.Slots.CopyTo(s.Slots, 0);
        s.SetSlot(index);
        return s;
    }

    public int[] Slots { get; private set; }

    public int Counter { get; set; }

    public int Index { get; set; }
}

Example:

    static void Main(string[] args)
    {

        using (var sw = new StreamWriter(@"c:\test\comb50.txt"))
        {
            foreach (var s in new[] { 2, 3, 4, 5, 6, 7, 8 }.Discover(50))
            {
                sw.WriteLine(s);
            }
        }
    }

Yields 3095 combinations.

Anthill
  • 1,219
  • 10
  • 20