주사위 고르기
A와 B가 n
개의 주사위를 가지고 승부를 합니다. 주사위의 6개 면에 각각 하나의 수가 쓰여 있으며, 주사위를 던졌을 때 각 면이 나올 확률은 동일합니다. 각 주사위는 1 ~ n
의 번호를 가지고 있으며, 주사위에 쓰인 수의 구성은 모두 다릅니다.
A가 먼저 n / 2
개의 주사위를 가져가면 B가 남은 n / 2
개의 주사위를 가져갑니다. 각각 가져간 주사위를 모두 굴린 뒤, 나온 수들을 모두 합해 점수를 계산합니다. 점수가 더 큰 쪽이 승리하며, 점수가 같다면 무승부입니다.
A는 자신이 승리할 확률이 가장 높아지도록 주사위를 가져가려 합니다.
https://school.programmers.co.kr/learn/courses/30/lessons/258709
import java.util.*;
/**
* 생성한 정점의 번호, 도넛 모양 그래프의 수, 막대 모양 그래프의 수, 8자 모양 그래프의 수를 순서대로 1차원 정수 배열에 담아 return 하도록 solution 함수를 완성해 주세요.
* [생성한 정점의 번호, 도넛 모양 그래프, 막대 모양 그래프, 8자 모양 그래프]
*/
public class Main4 {
public static void main(String[] args) {
int[][] dice_1 = {{1, 2, 3, 4, 5, 6}, {3, 3, 3, 3, 4, 4}, {1, 3, 3, 4, 4, 4}, {1, 1, 4, 4, 5, 5}};
int[][] dice_2 = {{1, 2, 3, 4, 5, 6}, {2, 2, 4, 4, 6, 6}};
int[][] dice_3 = {{40, 41, 42, 43, 44, 45}, {43, 43, 42, 42, 41, 41}, {1, 1, 80, 80, 80, 80}, {70, 70, 1, 1, 70, 70}};
solution(dice_1);
}
public static int[] solution(int[][] dice) {
Dice.initDice(dice);
List<List<List<Dice>>> allDistributionCase = Dice.allDistributionCase();
double maxWinning_persent = 0;
List<Dice> maxWinning_Dice = new ArrayList<>();
for (List<List<Dice>> list : allDistributionCase) {
List<Dice> user_A = list.get(0);
List<Integer> user_A_result = new ArrayList<>();
Dice.generateSums(user_A, 0, 0, user_A_result);
List<Dice> user_B = list.get(1);
List<Integer> user_B_result = new ArrayList<>();
Dice.generateSums(user_B, 0, 0, user_B_result);
double result = calculateProbability(user_A_result, user_B_result);
if (maxWinning_persent < result) {
maxWinning_persent = result;
maxWinning_Dice = user_A;
}
System.out.println(result);
}
System.out.println(maxWinning_Dice);
System.out.println(maxWinning_persent);
List<Integer> result = new ArrayList<>();
for (Dice temp : maxWinning_Dice) {
for (int i = 0; i < Dice.allDice.size(); i++) {
if (temp == Dice.allDice.get(i)) {
result.add(i+1);
}
}
}
Collections.sort(result);
System.out.println(result);
return result.stream().mapToInt(Integer::intValue).toArray();
}
public static double calculateProbability(List<Integer> a, List<Integer> b) {
int aGreaterCount = 0;
int totalCount = a.size() * b.size();
for (int numA : a) {
for (int numB : b) {
if (numA > numB) {
aGreaterCount++;
}
}
}
return (double) aGreaterCount / totalCount;
}
}
class Dice {
static List<Dice> allDice = new ArrayList<>();
int[] diceNumber;
Dice(int[] diceNumbers) {
this.diceNumber = diceNumbers;
}
@Override
public String toString() {
return "Dice{" +
"diceNumber=" + Arrays.toString(diceNumber) +
'}';
}
static List<Dice> initDice(int[][] diceData) {
for (int[] diceNumbers : diceData) {
allDice.add(new Dice(diceNumbers));
}
return allDice;
}
/**
* 분배 경우의 수
*/
static List<List<List<Dice>>> allDistributionCase() {
int allDiceCount = allDice.size();
int choiceCount = allDiceCount / 2; // 선택 개수
List<List<Object>> result_combination = new ArrayList<>();
generateCombinations(Dice.allDice.toArray(), choiceCount, 0, new ArrayList<>(), result_combination);
List<List<List<Dice>>> result = result_combination.stream().map(objects -> {
List<Dice> a = objects.stream().map(o -> (Dice) o).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
List<Dice> b = Dice.allDice.stream().filter(dice -> !a.contains(dice)).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
List<List<Dice>> temp = new ArrayList<>();
temp.add(a);
temp.add(b);
return temp;
}).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
return result;
}
static void generateCombinations(Object[] arry, int count, int start, List<Object> current, List<List<Object>> result) {
if (current.size() == count) {
result.add(new ArrayList<>(current));
return;
}
for (int i = start; i < arry.length; i++) {
current.add(arry[i]);
generateCombinations(arry, count, i + 1, current, result);
current.remove(current.size() - 1); // 마지막 요소 제거 (백트래킹)
}
}
static void generateSums(List<Dice> dice, int index, int currentSum, List<Integer> result) {
if (index == dice.size()) {
result.add(currentSum);
return;
}
for (int value : dice.get(index).diceNumber) {
generateSums(dice, index + 1, currentSum + value, result);
}
}
static void generateSums(int[][] dice, int index, int currentSum, Set<Integer> result) {
if (index == dice.length) {
result.add(currentSum);
return;
}
for (int value : dice[index]) {
generateSums(dice, index + 1, currentSum + value, result);
}
}
}
이번에 경우의 수 케이스를 구하는 로직을 짜는게 좀..