3

Two pairs: If there are two pairs of dice with the same number, the player scores the sum of these dice. If not, the player scores 0. For example, 1, 1, 2, 3, 3 placed on "two pairs" gives 8.

examples: 1,1,2,3,3 results 8 1,1,2,3,4 results 0 1,1,2,2,2 results 6

How can find this efficiently?

I've been using following code to find a single pair

int max_difference = 0;
int val1 = 0 , val2 = 0;
Arrays.sort(dice);
for (int i = 0; i < dice.length - 1; i++) {
    int x = dice[i+1] - dice[i];
    if(x <= max_difference) {
        max_difference = x;
        val1 = dice[i];
        val2 = dice[i+1];

    }
}
pairScore = val1 + val2;
11
  • 1
    "two pairs" = 2 x 2 dice with the same value? So if I have 1, 1, 2, 3, 4 the result is 0? What about 1, 1, 1, 2, 2? And 1, 1, 1, 1, 2? Commented Jul 26, 2016 at 9:14
  • @Mark it should result sum of both that means 6(1+1+2+2) Commented Jul 26, 2016 at 9:16
  • In which case should it be 6? 1, 1, 1, 2, 2? So it doesn#t matter that there are 3 1s it still counts as a pair? Commented Jul 26, 2016 at 9:16
  • @Jonny where does it say he's rolling four dice? Commented Jul 26, 2016 at 9:18
  • 1
    The distinct values are limited. So use bucket sorting, or frequency map as @Thomas answered. Commented Jul 26, 2016 at 9:24

5 Answers 5

5

No need to make it that complicated, since you're only searching for the resulting number...

int prev = 0;
int result = 0;
int pairs = 0;

Arrays.sort(dice);
for (int i = 0; i < dice.length; i++) 
{
    int current = dice[i];
    if (current == prev) 
    {
        result += current*2;
        pairs++;
        prev = 0;
    } 
    else prev = current;
}

if (pairs == 2) return result;
else return 0;
Sign up to request clarification or add additional context in comments.

Comments

3

I'd use a frequency map, i.e. the number is the key and the value is a counter (so a Map<Integer, Integer>). However, since it is used for dices you could simplify that using an array with a length equal to the maximum dice value (6 for standard dice). Then check the frequencies for each number and get the number of pairs from it.

Example:

int[] diceFrequency = new int[6];

//assuming d is in the range [1,6]
for( int d : dice ) {
  //increment the counter for the dice value
  diceFrequency[d-1]++; 
}

int numberOfPairs = 0;
int pairSum = 0;

for( int i = 0; i < diceFrequency.length; i++ ) {
  //due to integer division you get only the number of pairs, 
  //i.e. if you have 3x 1 you get 1 pair, for 5x 1 you get 2 pairs
  int num = diceFrequency[i] / 2;

  //total the number of pairs is just increases
  numberOfPairs += num; 

  //the total value of those pairs is the dice value (i+1) 
  //multiplied by the number of pairs and 2 (since it's a pair)
  pairSum += (i + 1 ) * 2 * num;
}

if( numerOfPairs >= 2 ) {
  //you have at least 2 pairs, do whatever is appropriate
}

5 Comments

hey diceFrequency[d-1]++; what does this do?
diceFrequency[d-1]++; what does this do?
//increment the counter for the dice value. It's written in comments
diceFrequency[d-1]++ increases the value of the element at index d-1 by 1. Since the array index is 0-based but the dice value is 1-based you need to use d-1 instead of just d.
@RamanSahasi to be fair I added the comments after the question since I realized some more explanation is needed.
3

How about use hashmap as below?

public static void main(String[] args) {
    List<Integer> list = Lists.newArrayList(1, 1, 2, 3, 3, 4);
    Map<Integer, Integer> map = Maps.newHashMap();

    int result = 0;

    for (int i : list) {
        int frequency = (int) MapUtils.getObject(map, i, 0);

        if (frequency < 2) {
            map.put(i, ++frequency);
        }
    }

    for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
        if (entry.getValue() > 1) {
            result += entry.getKey() * entry.getValue();
        }
    }

    System.out.println(result);
}

4 Comments

AFAIK that kind of map is called a frequency map (just for future reference :) ). Besides that you could optimize the second loop by using entrySet() since you'd then not have to do additional lookups.
The keySet() is replaced by the entrySet() as @Thomas said. Thanks for advice.
When you have a full house (e.g. 2 2 2 3 3), your code counts all the dice, it probably should only count two of the 2s.
@Roland Illig You have a good point. It was fixed as above. thank you :)
1
public static void main(String[] args) {
    List<Integer> list = Lists.newArrayList(1, 1, 2, 3, 3);
    Map<Integer, Integer> map = new HashMap<>();

    int count= 0;

    for (int num : list)
        if(map.containsKey(num ))
            map.put(num , map.get(num )+1);
        else
            map.put(num , 1);

    for (int num  : map.keySet()) {
        if (map.get(num ) > 1) {
            count= count+ (num  * map.get(num ));
        }
    }

    System.out.println(count);
}

Comments

1

I hope, I could understand the problem. So we can use thiscode part.

    List<Integer> diceList = new ArrayList<Integer>();
    diceList.add(1);
    diceList.add(1);
    diceList.add(2);
    diceList.add(4);
    diceList.add(3);
    diceList.add(3);
    diceList.add(6);
    diceList.add(8);

    Integer prev = null, score = 0;

    boolean flag = false;
    for (Integer val : diceList) {
        if (prev == null || !prev.equals(val)) {
            if (flag) {
                score = score + prev;
                flag = false;
            }
            prev = val;

        } else if (prev == val) {
            score = score + prev;
            flag = true;
        }
    }
    System.out.println(score);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.