- 랜덤 숫자
- 시뮬레이션
- 작은 숫자로 실행해보기
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 4
#define MAX_COUNT 2520
#define _CRT_SECURE_NO_WARNINGS
static int baseballNumbers[MAX];
static int numbersCheck[10];
static int T;
extern void tryBest(int suppose[]); ////************
static int queryCallCount;
static const int queryLimit = 110;
static int scoreTable[MAX_COUNT + 5];
typedef struct Data {
int strike;
int ball;
} Data;
// suppose 가 가능한지 안한지 체크하는 함수
static bool isAble(int suppose[]) {
int supposeCheck[10];
for (int count = 0; count < 10; ++count) supposeCheck[count] = 0;
for (int idx = 0; idx < MAX; ++idx) {
if (suppose[idx] < 0 || suppose[idx] >= 10 || supposeCheck[suppose[idx]] > 0) return false;
supposeCheck[suppose[idx]]++;
}
return true;
}
Data query(int suppose[]) {
Data result;
// max 보다 더 넣었을 때
if (queryCallCount > MAX_COUNT) {
result.strike = -1;
result.ball = -1;
return result;
}
queryCallCount++;
if (!isAble(suppose)) {
result.strike = -1;
result.ball = -1;
return result;
}
result.strike = 0;
result.ball = 0;
// strike, ball 새는 것
for (int idx = 0; idx < MAX; ++idx)
if (suppose[idx] == baseballNumbers[idx])
result.strike++;
else if (numbersCheck[suppose[idx]] > 0)
result.ball++;
return result;
}
// 새로운 값을 생성하는 것
static void initialize() {
for (int count = 0; count < 10; ++count) numbersCheck[count] = 0;
for (int idx = 0; idx < MAX;) {
int c = rand() % 10;
if (numbersCheck[c] == 0)
{
baseballNumbers[idx] = c;
numbersCheck[c]++;
idx++;
}
}
queryCallCount = 0;
}
//
static bool check(int suppose[]) {
for (int idx = 0; idx < MAX; ++idx)
{
if (suppose[idx] != baseballNumbers[idx])
return false;
}
return true;
}
void initScoreTable() {
int i;
for (i = 0; i <= 10; ++i) scoreTable[i] = 100;
for (; i <= queryLimit; ++i) scoreTable[i] = 110 - i;
}
int main() {
int total_score = 0;
//freopen("sample_input.txt", "r", stdin);
setbuf(stdout, NULL);
//scanf("%d", &T);
T = 100;
initScoreTable();
srand((unsigned int)time(NULL));
for (int testcase = 1; testcase <= T; ++testcase) {
initialize();
int suppose[MAX];
tryBest(suppose);
if (!check(suppose)) {
queryCallCount = MAX_COUNT;
total_score = 0;
break;
}
printf("#%d %d : ", testcase, queryCallCount);
for (int i = 0; i < 4; ++i) printf("%d", suppose[i]);
puts("");
if (queryCallCount > queryLimit)
queryCallCount = queryLimit;
//total_score += scoreTable[queryCallCount];
total_score += queryCallCount;
}
//printf("Total Score = %d\n", total_score / T);
printf("Total Score = %d\n", total_score);
return 0;
}
typedef struct Data {
int strike;
int ball;
} Data;
int chk[10000];
extern Data query(int supose[]);
// 4자리 숫자를 입력 받아서 배열로 저장함
void encode(int num, int arr[])
{
for (int i = 3; i >= 0; i--) {
arr[i] = num % 10;
num /= 10;
}
}
// 내가 예상한 숫자와 다른 숫자들을 비교
Data myquery(int a[], int b[])
{
Data result = { 0, 0 };
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (a[i] == b[j]) {
if (i == j) result.strike++;
else result.ball++;
}
}
}
return result;
}
int confirm(int num)
{
int arr1[4], arr2[4], cnt = 0, ans;
encode(num, arr1);
Data result1 = query(arr1), result2;
if (result1.strike == 4) return num; // 찾음
for (int i = num + 1; i <= 9876; i++) { // 해당 숫자 + 1 부터 끝까지 검사 시작
if (chk[i]) continue;
encode(i, arr2);
result2 = myquery(arr1, arr2);
if (result1.strike != result2.strike || result1.ball != result2.ball) chk[i] = 1; // 안되는 것 체크하기
else { // 가능한 숫자가 몇개인가
cnt++; // cnt == 1 이면 가능한 것이 1개 이므로 끝남
ans = i;
}
}
if (cnt == 1) return ans;
return -1; // 못찾음
}
void tryBest(int suppose[]) {
int i, j, k;
for (i = 123; i <= 9876; i++) {
chk[i] = 0;
encode(i, suppose);
for (j = 0; j < 3; j++) for (k = j + 1; k < 4; k++) {
if (suppose[j] == suppose[k]) chk[i] = 1;
}
}
for (i = 123; i <= 9876; i++) {
if (chk[i]) continue;
k = confirm(i);
if (k >= 0) break;
}
encode(k, suppose);
}
'Algorithms > simulation' 카테고리의 다른 글
1 Problem F : 연속부분합 찾기 (0) | 2019.11.07 |
---|---|
1 Problem B : 못생긴 수 (0) | 2019.11.07 |
4 Problem B : 타일 채우기 (0) | 2019.11.07 |
4 Problem A : 책 복사하기 (0) | 2019.11.07 |
3 Problem C : 테트리스 (0) | 2019.11.06 |
댓글