본문 바로가기

알고리즘/프로그래머스

프로그래머스 - 숫자야구(Level 2)/Wanna Be 컴잘알

728x90

문제 출처 - https://programmers.co.kr/learn/courses/30/lessons/42841

 

코딩테스트 연습 - 숫자 야구 | 프로그래머스

[[123, 1, 1], [356, 1, 0], [327, 2, 0], [489, 0, 1]] 2

programmers.co.kr

 

- 문제 -

 

숫자 야구 게임이란 2명이 서로가 생각한 숫자를 맞추는 게임입니다.

각자 서로 다른 1~9까지 3자리 임의의 숫자를 정한 뒤 서로에게 3자리의 숫자를 불러서 결과를 확인합니다. 그리고 그 결과를 토대로 상대가 정한 숫자를 예상한 뒤 맞힙니다.

* 숫자는 맞지만, 위치가 틀렸을 때는 볼 * 숫자와 위치가 모두 맞을 때는 스트라이크 * 숫자와 위치가 모두 틀렸을 때는 아웃

예를 들어, 아래의 경우가 있으면

A : 123 B : 1스트라이크 1볼. A : 356 B : 1스트라이크 0볼. A : 327 B : 2스트라이크 0볼. A : 489 B : 0스트라이크 1볼.

이때 가능한 답은 324와 328 두 가지입니다.

질문한 세 자리의 수, 스트라이크의 수, 볼의 수를 담은 2차원 배열 baseball이 매개변수로 주어질 때, 가능한 답의 개수를 return 하도록 solution 함수를 작성해주세요.

 

- 접근 - 

 

1. 123~987까지 숫자들 중에 야구의 답이 될 수 있는 숫자들을  vector<vector> baseball에 있는 질문과 비교하여 모두 만족하는 숫자들을 추려낸다.

2. 숫자야구의 답이 될 수 있는 숫자는 0을 포함하지않아야하고 백의자리, 십의자리, 일의자리가 모두 달라야한다.

3. 세가지 함수를 만들었다. 1. 각 자리 숫자를 리턴해주는 함수, 2. 스트라이크 숫자를 리턴해주는 함수, 3. 볼 숫자를 리턴해주는 함수 

 

- 코드 -

 

c++

#include <string>
#include <vector>
#include <iostream>

using namespace std;

vector<int> jari_divide(int jari) {
	vector <int> v;
	int hundred = jari / 100;
	int ten = (jari - 100 * hundred) / 10;
	int one = (jari - 100 * hundred) % 10;
	v.push_back(hundred);
	v.push_back(ten);
	v.push_back(one);
	return v;
}

int cal_strike(vector<int> v, vector<int> input) {
	int cnt = 0;
	for (int i = 0; i < 3; i++) {
		if (v[i] == input[i])
			cnt += 1;
	}
	return cnt;
}

int cal_ball(vector<int> v, vector<int> input) {
	int cnt = 0;
	for (int i = 0; i < 3; i++) {
		for (int k = 0 ; k < 3; k++) {
			if (v[i] == input[k] && i!=k)
				cnt += 1;
		}
	}
	return cnt;
}

int solution(vector<vector<int>> baseball) {
	int answer = 0;

	bool flag = false;
	
	for (int k = 123; k < 1000; k++) {
		flag = false;
		vector <int> v;
		v = jari_divide(k);

		int hundred = v[0];
		int ten = v[1];
		int one = v[2];

		if (hundred == ten || hundred == one || ten == one || hundred==0 || ten==0 || one==0) {
	
		}
		else {
			for (int i = 0; i < baseball.size(); i++) {

				vector <int> input;
				int cur = baseball[i][0];
				int strike = baseball[i][1];
				int ball = baseball[i][2];

				input = jari_divide(cur);

				int strike_cnt = cal_strike(v, input);
				int ball_cnt = cal_ball(v, input);

				if (strike == strike_cnt && ball == ball_cnt) {
					flag = false;
				}
				else {
					flag = true;
					break;
				}
			}
			if (!flag)
				answer += 1;
		}
	}
	return answer;
}

 

python3 (추가 업로드)

#123~987까지 체크
vector=[]
check=[]
answer=0

def isPossible(baseball):
    global vector,answer

    for value in baseball:
        strike = 0
        ball = 0

        for i,v in enumerate(vector):
            three = int(value[0]/100)
            two = int((value[0]-three*100)/10)
            one = value[0]%10

            if three == v and i==0:
                strike+=1
            elif three == v and i!=0:
                ball+=1
            elif two == v and i==1:
                strike+=1
            elif two == v and i!=1:
                ball+=1
            elif one == v and i==2:
                strike+=1
            elif one == v and i!=2:
                ball+=1

        if value[1]!=strike or value[2]!=ball:
            return
    
    answer+=1

def solve(cnt,input,baseball):
    global vector,check
    
    if cnt==3:
        isPossible(baseball)
        return

    for value in input:
        if check[value]==False:
            check[value]=True
            vector.append(value)
            solve(cnt+1,input,baseball)
            vector.pop()
            check[value]=False

def solution(baseball):
    global vector,check,answer
    input=[1,2,3,4,5,6,7,8,9]
    check = [False for i in range(0,10,1)]
    solve(0,input,baseball)

    return answer
728x90