본문 바로가기
Algorithms/simulation

4 Problem C : 숫자 야구2

by OKOK 2019. 11. 7.

- 랜덤 숫자

- 시뮬레이션

- 작은 숫자로 실행해보기

 

#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

댓글