정보문화진흥원 정보 영재 동아리에서 동아리 활동을 하던 영수와 민혁이는 쉬는 시간을 틈타 숫자야구 게임을 하기로 했다.
영수는 민혁이가 말한 수가 몇 스트라이크 몇 볼인지를 답해준다.
현재 민혁이와 영수는 게임을 하고 있는 도중에 있다. 민혁이가 영수에게 어떤 수들을 물어보았는지, 그리고 각각의 물음에 영수가 어떤 대답을 했는지가 입력으로 주어진다. 이 입력을 바탕으로 여러분은 영수가 생각하고 있을 가능성이 있는 수가 총 몇 개인지를 알아맞혀야 한다.
아래와 같은 경우를 생각해보자.
민혁: 123 영수: 1 스트라이크 1 볼. 민혁: 356 영수: 1 스트라이크 0 볼. 민혁: 327 영수: 2 스트라이크 0 볼. 민혁: 489 영수: 0 스트라이크 1 볼.
이 때 가능한 답은 324와 328, 이렇게 두 가지이다.
영수는 동아리의 규율을 잘 따르는 착한 아이라 민혁이의 물음에 곧이곧대로 정직하게 답한다. 그러므로 영수의 답들에는 모순이 없다.
민혁이의 물음들과 각각의 물음에 대한 영수의 답이 입력으로 주어질 때 영수가 생각하고 있을 가능성이 있는 답의 총 개수를 출력하는 프로그램을 작성하시오.
첫째 줄에는 민혁이가 영수에게 몇 번이나 질문을 했는지를 나타내는 1 이상 100 이하의 자연수 N이 주어진다. 이어지는 N개의 줄에는 각 줄마다 민혁이가 질문한 세 자리 수와 영수가 답한 스트라이크 개수를 나타내는 정수와 볼의 개수를 나타내는 정수, 이렇게 총 세 개의 정수가 빈칸을 사이에 두고 주어진다.
첫 줄에 영수가 생각하고 있을 가능성이 있는 답의 총 개수를 출력한다.
4 123 1 1 356 1 0 327 2 0 489 0 1
2
24개의 풀이가 있습니다.
이렇게 찾는게 젤 빠릅니다.
import sys
for i in range(10):
print("%d00" % i)
ball_cnt = input("Ball Count? ")
if ball_cnt[0] == '3':
print("Strike Out!!!")
break
elif ball_cnt[0] == '2':
for j in range(1,10):
print ("%d%02d" % (i,j))
ball_cnt = input("Ball Count? ")
if ball_cnt[0] == '3':
print("Strike Out!!!")
sys.exit()
elif ball_cnt[0] == '2':
for k in range(1,10):
print ("%d%d%d" % (i,j,k))
ball_cnt = input("Ball Count? ")
if ball_cnt[0] == '3':
print("Strike Out!!!")
sys.exit()
elif ball_cnt[0] == '1':
for j in range(1,10):
print ("%d%d0" %(i,j))
ball_cnt = input("Ball Count? ")
if ball_cnt[0] == '3':
print("Strike Out!!!")
sys.exit()
elif ball_cnt[0] == '2':
for k in range(1,10):
print ("%d%d%d" % (i,j,k))
ball_cnt = input("Ball Count? ")
if ball_cnt[0] == '3':
print("Strike Out!!!")
sys.exit()
package rootcucu.codefight;
import java.util.*;
// http://codingdojang.com/scode/475
/*
2
1 2 3 1 1
3 5 6 1 0
3 2 7 2 0
4 8 9 0 1
*/
public class Baseball {
static class Pair {
Pair(){
ask = new int[3];
answer = new int[2];
}
int[] ask;
int[] answer; //order : S, B
boolean match(int[] numbers){
int s = 0, b = 0;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++){
if (numbers[i] == ask[j]){
if (i == j){
s++;
}
else {
b++;
}
}
}
boolean match = s == answer[0] && b == answer[1];
// System.out.println("ask - " + Arrays.toString(ask) +
// ", answer - " + Arrays.toString(answer) +
// ", numbers - " + Arrays.toString(numbers)
// + ", s = " + s + ", b = " + b + ", match = " + match);
return match;
}
@Override
public String toString() {
return "Pair [ask=" + Arrays.toString(ask) + ", answer="
+ Arrays.toString(answer) + "]";
}
}
Pair[] pairs;
public void getValues(){
Scanner scanner = new Scanner(System.in);
System.out.println("how many ask-answers do you have?");
int n = scanner.nextInt();
pairs = new Pair[n];
for (int i = 0; i < n; i++){
pairs[i] = new Pair();
Pair pair = pairs[i];
int[] ask = pair.ask;
int[] answer = pair.answer;
System.out.println("Enter ask-answer");
ask[0] = scanner.nextInt();
ask[1] = scanner.nextInt();
ask[2] = scanner.nextInt();
answer[0] = scanner.nextInt();
answer[1] = scanner.nextInt();
}
}
public List<int[]> solve(){
List<int[]> matchNumbers = new ArrayList<>();
int[] numbers = new int[3];
for (numbers[0] = 1; numbers[0] < 10; numbers[0]++)
for (numbers[1] = 1; numbers[1] < 10; numbers[1]++){
if (numbers[1] == numbers[0])
continue;
for (numbers[2] = 1; numbers[2] < 10; numbers[2]++){
if (numbers[2] == numbers[0] || numbers[2] == numbers[1])
continue;
if (testMatchAll(numbers)){
matchNumbers.add(Arrays.copyOf(numbers, 3));
}
}
}
return matchNumbers;
}
public void printPairs(){
for (Pair pair:pairs)
System.out.println(pair);
}
private boolean testMatchAll(int[] numbers){
for (Pair pair:pairs)
if (!pair.match(numbers))
return false;
return true;
}
public static void main(String[] args){
Baseball obj = new Baseball();
obj.getValues();
obj.printPairs();
List<int[]> matchNumbers = obj.solve();
for (int[] match:matchNumbers){
System.out.println("match = " + Arrays.toString(match));
}
System.out.println("count = " + matchNumbers.size());
}
}
입력 데이타
4
1 2 3 1 1
3 5 6 1 0
3 2 7 2 0
4 8 9 0 1
아웃풋
Pair [ask=[1, 2, 3], answer=[1, 1]]
Pair [ask=[3, 5, 6], answer=[1, 0]]
Pair [ask=[3, 2, 7], answer=[2, 0]]
Pair [ask=[4, 8, 9], answer=[0, 1]]
match = [3, 2, 4]
match = [3, 2, 8]
count = 2
파이썬 3버전입니다.
import random
numbers = list(range(1,9)) #숫자 1에서9 랜덤배열
random.shuffle(numbers)
sList, answer =[],""
for i in range(3): # 3개 고르기
sList += str(numbers[i])
answer+= str(numbers[i])
def check(guess):
strike, ball= 0,0
li= str(guess); Li= list()
for i in range(len(li)):
Li.append(li[i])
for i in range(3):
if Li[i] == sList[i]:
strike+=1
else:
if Li[i] in sList:
ball+=1
print("%d strike %d ball. The answer was %s"%(strike,ball,answer)) # 결과
a = input("guess>")
check(a)
1~9까지의 3자리 순열을 몽땅 리스트로 만들어서
주어진 데이터로 필터링했습니다.
from itertools import permutations as perm
def umpire(p,r):
p=str(p);r=str(r)
s=b=0
for i in range(len(p)):
if p[i] == r[i] : s+=1
elif p[i] in r : b+=1
return s,b
q = raw_input().split()[1:]
data=[]
while q:
num,s,b = q.pop(0),int(q.pop(0)),int(q.pop(0))
data.append((num,s,b))
bucket = [''.join(x) for x in perm('123456789',3)]
for d in data:
num,s,b = d
tmp_bucket=[]
while bucket:
m = bucket.pop()
if umpire(m,num) == (s,b) : tmp_bucket.append(m)
bucket = tmp_bucket
print len(bucket)
#파이썬3.5.1
class Numbase:
def __init__(self,number=''):
self.right = str(number)
def setright(self,n): #생각하는 숫자 세팅
self.right = str(n)
def solve(self,n): # 스트라이크와 볼 판별
Olist = list(self.right) #각 자릿수를 원소로 리스트만들기
nlist = list(n) #위와 똑같음
strike = 0
ball = 0
for i in range(len(nlist)):
if Olist[i] == nlist[i]: #만약 같은 위치에 같은 숫자가 있으면
strike += 1 #스트라이크 +1
elif nlist[i] in Olist: #만약 숫자가 위치에 안맞아도 들어가있으면
ball += 1 #볼 +1
return (strike, ball)
def guess(self,hints): # hints는 각 원소가 '숫자 스트라이크수 볼수'형태인 리스트로 입력받습니다
numlist = list(filter(lambda x: len(set(x))==3,
[str(x) + str(y) + str(z) for x in range(1, 10) for y in range(1, 10) for z in range(1, 10)]))
correct = [] # numlist; 각 자릿수가 1부터 9까지 3자리의 수중 숫자가 반복되지 않는 수들의 리스트
for n in numlist: #각 숫자에게 모두
o = 0 #조건을 충족하는 개수
for h in hints: #각 힌트마다
h = h.split()
if Numbase(n).solve(h[0]) == tuple(map(int,h[1:])): #만약 판별했을 때 스트라이크와 볼이 똑같으면
o += 1 # 1더하기
if o == len(hints): #모든 조건과 충족되면
correct.append(n) #return할 것에 넣기
return correct
n = Numbase()
hints = []
for i in range(int(input())):
hints.append(input())
print(n.guess(hints))
입력:
4
123 1 1
356 1 0
327 2 0
489 0 1
출력:
['324', '328']
1~9로 만들 수 있는 세자리 수는 총 9^3 개밖에 없고 또한 각 자릿수가 모든 다른 자릿수인 수들만 고려해주면 되므로 전체탐색으로도 고속으로 해결가능합니다. 아래는 C++ 코드입니다.
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> using namespace std;int arr[101],s[101],b[101];
int q[3],t[3]; // q: 무작위로 만들어낸 수, t: 물어본 숫자들 int N;int main(){
int sample,k = 0;
int strike = 0, ball = 0;
int cnt = 0;
scanf("%d",&N);
for (int i = 0; i < N; i++){ // 입력 받기 scanf("%d %d %d",&arr[i],&s[i],&b[i]);
} for (int i = 1; i <= 9; i++){ for (int j = 1; j <= 9; j++){ for (int p = 1; p <= 9; p++){ if (i != j && j != p && p != i){ // 만약 서로 다른 세자리수라면!! q[0] = i; q[1] = j; q[2] = p; for (int a = 0; a < N; a++){ sample = arr[a];
t[0] = sample/100;
sample %= 100;
t[1] = sample/10; t[2] = sample%10;
for (int n = 0; n < 3; n++){ for (int m = 0; m < 3; m++){ if (q[n] == t[m]){ if (n == m) ++strike;
else ++ball;
} } } if (strike == s[a] && ball == b[a]) ++k; strike = 0; ball = 0;
} if (k == N) ++cnt;
k = 0;
} } } } printf("%d\n",cnt);
return 0; }
C#으로 작성했습니다. 모든 숫자를 대입시켜 계산했습니다.
using System.Collections.Generic;
using System.Linq;
public static class Question082CountNumericBaseball
{
public static void Answer()
{
var inputs = new List<string>();
inputs.Add("123 1 1");
inputs.Add("356 1 0");
inputs.Add("327 2 0");
inputs.Add("489 0 1");
var count = CountNumericBaseball(inputs);
}
public static int CountNumericBaseball(List<string> inputs)
{
var count = 0;
for (int i = 123; i < 987; i++)
{
var curr = i.ToString();
var total = 0;
if (curr.Contains("0") || !(curr[0] != curr[1] && curr[1] != curr[2] && curr[0] != curr[2])) continue;
foreach (var input in inputs)
{
var split = input.Split(' ').ToList();
var ball = 0;
var strike = 0;
var temp = split[0].ToString();
for (int j = 0; j < 3; j++)
{
if (curr[j] == temp[j]) strike++;
else if (curr.Contains(temp[j])) ball++;
}
if (ball == int.Parse(split[2]) && strike == int.Parse(split[1])) total++;
}
if (total == 4)
count++;
}
return count;
}
}
Ruby
cnt = ->sb,a,b { sb[0]+=1 if a==b; sb[1]+=1 if a[0]==b[0] && a[1]!=b[1]; sb }
valid = ->n1,n2,st,ba do
ai, bi = [n1, n2.chars].map {|e| e.map.with_index.to_a }
ai.product(bi).reduce([0,0]) {|sb,(a,b)| cnt[sb,a,b]} == [st.to_i, ba.to_i]
end
guesses = proc { _,*tail = gets.split; tail.each_slice(3).to_a }
matched = proc {|all,guess| all.select {|e| valid[e, *guess] } }
answers = proc { p guesses[].reduce([*"1".."9"].permutation(3), &matched).size }
Test
$stdin = StringIO.new("4 123 1 1 356 1 0 327 2 0 489 0 1\n")
expect{ answers.() }.to output("2\n").to_stdout
Output
answers.()
4 123 1 1 356 1 0 327 2 0 489 0 1
2
javascript
var perms = function perms(xs, k){
if (k > xs.length || k <= 0)
return [[]];
var r=[];
for (var i=0;i<xs.length;i++){
var xs_ = xs.slice(),
x = xs_.splice(i, 1),
ps = perms(xs_, k - 1);
r.push(...ps.map(p=>x.concat(p)))
}
return r;
};
var thrown = function (v, i) {
var [pitcher, strike, ball] = i.split(" ");
var s = v.split("").reduce((a, b, i) => a + (b === pitcher[i] ? 1 : 0), 0);
var b = v.split("").reduce((a, b, i, array) => a + (b !== pitcher[i] && array.indexOf(pitcher[i]) > -1 ? 1 : 0), 0);
return strike === "" + s && ball === "" + b;
};
var play = function (inning) {
var candidate = perms([1, 2, 3, 4, 5, 6, 7, 8, 9], 3).map(v => v.join(""));
for (i of inning) {
candidate = candidate.filter(v => thrown(v, i));
}
return candidate.length;
}
var input = "4 123 1 1 356 1 0 327 2 0 489 0 1";
var inning = input.match(/(\d{3}\s*\d\s*\d)/g);
console.log(play(inning));
#4 123 1 1 356 1 0 327 2 0 489 0 1
a = [4,123,1,1,356,1,0,327,2,0,489,0,1]
count = 1
candid = []
for i in range(1,1000):
if i < 10:
candid.append('0'+'0'+str(i))
elif 10<=i<100:
candid.append('0'+str(i))
else:
candid.append(str(i))
#matching function
def matching(target,str_b):
tar = [int(aa) for aa in target]
b = [int(bb) for bb in str_b]
strike = 0
ball = 0
for i in range(len(b)):
for j in range(len(target)):
if b[i] == tar[i]:
strike += 1
break
elif i!=j and b[i]==tar[j]:
ball += 1
return [strike,ball]
for iter in range(a[0]):
newcandid = []
standard = 3*iter+1
stand = [int(i) for i in str(a[standard])]
for i in candid:
if matching(i,stand) == [a[3*iter+2],a[3*(iter+1)]]:
newcandid.append(i)
candid = newcandid[:]
print(candid)
파이썬 3.6
def inputdata(data):
tmp,q,a = [],[],[]
N = int(input(''))
for i in range(N):
q = list(input(''))
tmp.append(q)
a = input('').split(' ')
tmp.append(a)
data.append(tmp)
tmp = []
def baseball(data):
possible_answer,tmp,tmp_b,p = [],[],[],0
# 임의의 값을 요소로 하는 답변 리스트를 생성합니다.
numbers = [str(i) for i in range(1,10)]
q_all = []
answer = ['0','0','0']
for i,play in enumerate(data):
# 첫 번째 질문에 대한 답변 중 스트라이크나 볼이 있으면 모든 요소가 유효하므로 기억해둡니다.
if i == 0:
q_all.extend(play[0])
if play[1][0] != '0' or play[1][1] != '0':
tmp.extend(play[0])
# 두 번째 답변부터는 스트라이크가 있는지와 볼이 있는지를 체크하여 각 경우에 대해 요소 들의 유효성을 확인합니다.
if 0 < i <len(data):
q_all.extend(play[0])
# 스트라이크가 없고 볼만 있는 경우 답(answer)이 확실히 아님을 알 수 있는 순서에 대응하는 요소를 질문에서 제거하고 나머지 요소는 기억해둔다.
if play[1][0] == '0' and play[1][1] != '0':
for i,value in enumerate(answer):
if value == '0':
play[0].remove(play[0][i])
tmp.extend(play[0])
# 스트라이크가 있는 경우
elif play[1][0] != '0':
# 기억해둔 숫자들과 해당 질문과 공통된 숫자를 찾아
tmp_b = set(tmp) & set(play[0])
# 공통된 숫자들을 현재질문과 비교하여 현재질문에 해당 요소가 있는 경우 해당 인덱스 값과 동일한 위치의 답(answer)요소에 해당 숫자를 대입하고, 기억된 요소리스에서 해당 숫자를 제거한다.(가능한 질문 리스트와 중복 방지)
for num in tmp_b:
if num in play[0]:
p = play[0].index(num)
answer[p] = num
tmp.remove(num)
# 추가로, 이전 질문의 해당 위치의 숫자와 다른데 기억된 요소에 해당 숫자가 있는 경우 해당 숫자를 제거한다.(가능한 질문 리스트에서 불필요한 요소 제거)
if data[i-1][0][play[0].index(num)] != num and data[i-1][0][play[0].index(num)] in tmp:
tmp.remove(data[i-1][0][play[0].index(num)])
tmp_b = []
tmp.extend(list(set(numbers) - set(q_all)))
# 질문과 대답에 대한 판단결과를 이용하여 가능한 질문 리스트를 만듭니다.
for i,value in enumerate(tmp):
tmp_b.extend(answer)
while '0' in tmp_b:
for i in tmp:
if value not in tmp_b:
tmp_b[answer.index('0')] = value
possible_answer.append(tmp_b)
tmp_b =[]
print("\n")
print(len(possible_answer))
if __name__ == "__main__":
data = []
inputdata(data)
baseball(data)
*결과값
4
123
1 1
356
1 0
327
2 0
489
0 1
2
def baseball(l):
guess = list()
def match(m ,s, b):
result = list()
def play(m, n):
b = 0
s = sum([m[0] == n[0], m[1] == n[1], m[2] == n[2]])
if m[0] != n[0]:
if m[1] != n[1]:
if m[1] == n[0]:
b += 1
if m[0] == n[1]:
b += 1
if m[2] != n[2]:
if m[2] == n[0]:
b += 1
if m[0] == n[2]:
b += 1
if m[1] != n[1] and m[2] != n[2]:
if m[2] == n[1]:
b += 1
if m[1] == n[2]:
b += 1
return s, b
for i in range(1, 10):
a = list(range(1,10))
a.remove(i)
for j in a:
c = list(range(1, 10))
c.remove(i)
c.remove(j)
for k in c:
if play(m, '{0}{1}{2}'.format(i, j, k)) == (s, b):
result.append('{0}{1}{2}'.format(i, j, k))
return set(result)
for i in range(len(l)):
guess.append(match(l[i][0], l[i][1], l[i][2]))
guess[0] = guess[0] & guess[-1]
return len(guess[0]), sorted(list(guess[0]))
#include<iostream>
#include"stdafx.h"
void Make_Answer(string &str)
{
int num = 0;
num = 100 + rand() % 899;
str = to_string(num);
}
void Compare_Answer(string str1, string str2, int &strike, int &ball, string &ball_number)
{
for (int i = 0; i < 3; i++)
{
if (str1[i] == str2[i]) strike++;
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if ((str1[i] == str2[j]) && (i != j))
ball++, ball_number.push_back(str2[j]);
}
}
}
int main()
{
srand((unsigned int)time(NULL));
int count_ask = 0, strike = 0, ball = 0;
int max_strike = 0;
int max_ball = 0;
string str;//영수
string str2;//민혁
string ball_number;
Make_Answer(str);
cout << str << endl;
while (count_ask<100)
{
str2.clear();
strike = 0, ball = 0;
count_ask++;
Make_Answer(str2);
Compare_Answer(str, str2, strike, ball, ball_number);
if (strike >= max_strike)
max_strike = strike;
if (ball >= max_ball)
max_ball = ball;
if (max_strike == 3)break;
cout << "영수질문횟수:" << count_ask << " " << "물어본 수:" << str2;
cout << " " << "strike:" << strike << " " << "ball:" << ball << endl;
}
sort(ball_number.begin(), ball_number.end());
string::iterator iter;
iter = unique(ball_number.begin(), ball_number.end());
ball_number.erase(iter, ball_number.end());
if (max_strike == 3)
cout << "Strike" << endl;
else if (max_strike == 2)
{
cout << "Answer_is:" << ball_number.size() - 2 << endl;
}
else if(max_strike==1)
{
cout << "Answer_is:" << (ball_number.size() - 1) * 2 << endl;
}
else
{
cout << "Miss" << endl;
}
}
맞는지 정확히 모르겠습니다..
'''
x = []
for _ in range(int(input())):
x.append( tuple(map(int,input().split())) )
'''
x = [(123,1,1),(356,1,0),(327,2,0),(489,0,1)]
def bb_case(*x):
def ballcount(n1, n2):
r = [0,0]
n1,n2 = str(n1),str(n2)
for i in range(len(n1)):
if n1[i] == n2[i]: r[0] += 1
elif n1[i] in n2: r[1] += 1
return tuple(r)
r = []
for i in range(123,988):
for j in str(i):
if str(i).count(j) > 1: continue
mark = True
for j in x:
if ballcount(j[0], i) != j[1:]: mark = False; break
if mark: r.append(i)
return r
print(len(bb_case(*x)))
전부 다 하는 건 재미가 없어 보여서 조금 더 궁리해봤습니다.
기본 틀은 다른 분들과 같지만,
시작하기 전에 스트라이크가 가장 많은 문답 하나를 찾아서
그 조건에 맞는 후보들을 추려낸 후에 비교를 시작합니다.
만약 2스트라이크가 있으면 후보를 20개로 추리고 시작할 수 있습니다(0볼만 가능하기 때문에).
근데 1스트 0스트는 케바케로 다 쓰기 귀찮아서 비워 놨어요. 그래서 미완성
def parse(data):
data , tests = data.split()[1:], []
while data:
tests.append( {'num':data.pop(0), 'strike':int(data.pop(0)), 'ball':int(data.pop(0))} )
return tests
def gen_possible_answers(round):
if round['strike'] is 2:
n = round['num']
pnums = [n[0] + x + n[2] for x in set('0123456789') - set(n)] + \
[n[0] + n[1] + x for x in set('0123456789') - set(n)] + \
[x + n[1] + n[2] for x in set('123456789') - set(n)]
elif round['strike'] is 1:
pnums = []
else:
pnums = []
return pnums
def match(answer, guess):
strike, ball = 0, 0
for digit in guess:
if digit in answer:
if answer.index(digit) == guess.index(digit):
strike += 1
else:
ball += 1
return (strike, ball)
data = "4 123 1 1 356 1 0 327 2 0 489 0 1"
rounds = parse(data)
pnums = gen_possible_answers(max(rounds, key = lambda x: x['strike']))
for c in pnums[:]:
for r in rounds:
if match(c, r['num']) != (r['strike'], r['ball']):
pnums.remove(c)
break
print(len(pnums), pnums)
간단하게 풀었습니다 그리고 코드를 보시면, 좀 지저분한 점이 있는데, 리스트 형태로 조건에 충족하지 않는 요소들을 제거할려고 했으나 계속 이상한 버그가 발생하여 돌아갔습니다. 버그 사진을 같이 첨부하니 아시는 분은 댓글로 알려주시면 감사하겠습니다. (그림 파일을 어떻게 넣는지 몰라 URL를 같이 첨부합니다.) (http://cafe.daum.net/jyarkzNote/kkjF/1)
def checkState(_inputvalue,_statevalues):
_result = {'s':0,'b':0}
for i in range(3):
if _inputvalue[i] == _statevalues[i]:
_result['s']+=1
elif _inputvalue[i] in _statevalues:
_result['b']+=1
return _result
def play_():
col = '324' # 정답.
cir = int(input())
aa = [str(i) for i in range(123,987)]
li=set()
for i in aa:
if '0' in i:
continue
if i[0]==i[1] or i[0]==i[2] or i[2]==i[1]:
continue
li.add(i)
for c in range(cir):
_in = input()
col_state = checkState(col,_in)
print(col_state)
for ele in list(li):
if checkState(_in,ele) != col_state:
li.remove(ele)
print(li)
play_()
from itertools import permutations as perm
digits_pool = [''.join(x) for x in perm('123456789',3)]
def base_ball_case(game_num):
removal_list=[]
result = digits_pool[:]
game_active=1
while game_active <= game_num:
number = input("Number: ")
strike = int(input("strike: "))
ball = int(input("ball: "))
numbers=[number[i] for i in range(3)]
strike_count = 0 ; ball_count = 0 ; case_list=[]
for i in result:
comp_numbers=[str(i)[j] for j in range(3)]
case_list=[(numbers[n],comp_numbers[m]) for n in range(3) for m in range(3)]
for index, value in enumerate(case_list):
if index in [0,4,8]:
if value[0] == value[1]:
strike_count += 1
else:
if value[0] == value[1]:
ball_count+=1
if (strike != strike_count) or (ball != ball_count):
removal_list.append(i)
strike_count=0 ; ball_count=0 ; case_list=[]
for removal in removal_list:
result.remove(removal)
removal_list=[]
game_active+=1
return len(result)
def strikeball(a,b):
strike=0
ball=0
for i in str(a):
if i in str(b):
if str(a).index(i)==str(b).index(i):
strike+=1
else:
ball+=1
return [strike,ball]
oldlist=[]
newlist=[]
for i in range(100,1000):
if '0' in str(i) or len(set(str(i)))<3:
continue
else:
oldlist.append(i)
trial=int(input("How many trials? : "))
for i in range(trial):
newlist=[]
user=input("Input guess, number of strikes and balls, seperate them with space: ").split(' ')
guess=int(user[0])
strike=int(user[1])
ball=int(user[2])
for t in oldlist:
if strikeball(t,guess)==[strike,ball]:
newlist.append(t)
oldlist=newlist
print(len(oldlist))
class NumberBall:
def __init__(self):
L = []
for i in range(1, 10):
for j in range(1, 10):
for k in range(1, 10):
if i!=j and j!=k and k!=i:
L.append(str(i)+str(j)+str(k))
self.numbers = L[:]
self.answers = L[:]
def strike_ball(self, num, guess_num):
strike = 0
ball = 0
for i in range(3):
if num[i] == guess_num[i]:
strike += 1
for x in guess_num:
if x in num:
ball += 1
ball = ball - strike
return [str(strike), str(ball)]
def deduce_once(self, guess_num, strike, ball):
i = 0
while i < len(self.answers):
if self.strike_ball(self.answers[i], guess_num) != [strike, ball]:
del(self.answers[i])
continue
i += 1
def deduce(self, data):
for gn, s, b in data:
self.deduce_once(gn, s, b)
print(' '.join(self.answers))
def reset(self):
self.answers = self.numbers
n = int(input())
inp = input().split()
data = [inp[3*i:3*i+3] for i in range(n)]
P = NumberBall()
P.deduce(data)
Python 3.7
import itertools as it
def get_score(answer: int, guess: int): # 스트라이크, 볼 개수 반환
a_str, g_str = str(answer), str(guess)
balls = len([g for g in g_str if g in a_str])
strikes = len([g for i, g in enumerate(g_str) if a_str[i] == g])
balls -= strikes
return strikes, balls
def main():
# 3 자리 수의 정답 풀을 만든 후
ans_pool = [int("".join(lst)) for lst in it.permutations(str(123456789), 3)]
num_inq = int(input())
for _ in range(num_inq):
guess, strikes, balls = map(int, input().strip().split())
# 각 응답의 조건에 만족하는 경우만 남김
ans_pool = [n for n in ans_pool if get_score(n, guess) == (strikes, balls)]
print(f"{len(ans_pool)}: {ans_pool}")
if __name__ == "__main__":
main()
파이썬 3입니다.
입력으로 받은 숫자를 리스트에 저장한 다음,
한 입력에 해당하는 경우의 수를 집합으로 저장하고,
그 다음 입력에 해당하지 않은 경우를 집합에서 제거 하는 방식으로 집합의 크기를 줄인 다음,
마지막에는 집합의 크기를 출력했습니다.
N = int(input()) # 질문 횟수
Num = [] # 민혁이가 질문한 세 자리 수
SB_tup = [] # (스트라이크, 볼)
for i in range(N):
i_list = input().split()
Num.append(i_list[0])
SB_tup.append((int(i_list[1]), int(i_list[2])))
def sb_check(case, num): # 스트라이크와 볼의 개수
strike = int((case[0] == num[0]) + (case[1] == num[1]) + (case[2] == num[2]))
ball = (num[0] in case) + (num[1] in case) + (num[2] in case) - strike
return strike, ball
def set_renewal(case_set, num, sb): # 해당하는 경우에 대해 경우의 수 집합을 갱신
temp_set = set()
for case in case_set:
if sb_check(case, num) == sb:
continue
temp_set |= {case}
return case_set - temp_set
index = SB_tup.index(sorted(SB_tup)[-1]) # 적은 경우의 수를 가진 (스트라이크, 볼)의 위치 // 경향적으로만 맞다 (s,b) = (1,0), (0,3)에서는 반대 결과
Tot_cases = set()
for i in range(1, 10): # 전체 경우의 집합: 첫번째 입력을 만족하는 집합을 생성한다
for j in range(1, 10):
for k in range(1, 10):
if i == j or j == k or k == i or sb_check('{0}{1}{2}'.format(i, j, k), Num[index]) != SB_tup[index]:
continue
Tot_cases |= {'{0}{1}{2}'.format(i, j, k)}
num_of_cases = 504
for n in [i for i in range(N) if i != index]:
if num_of_cases == 1:
break
Tot_cases = set_renewal(Tot_cases, Num[n], SB_tup[n])
num_of_cases = len(Tot_cases)
print(num_of_cases)
import random
nn = 0
a1 = []
nm = []
n = []
def player():
p = input('숫자 입력: ')
try:
p = int(p)
return p
except:
print('ERROR.please input number')
player()
def select():
a = random.randint(0,9)
b = random.randint(0,9)
c = random.randint(0,9)
e = str(a)+str(b)+str(c)
e = int(e)
return e
def listdo(a):
b = []
for n in range(0,len(str(a))):
b.append(int(str(a)[n]))
return b
def isin(number,a):
global nm
nm = [0,0,0]
for p in number:
if p in a:
n = a.index(p)
n2 = number.index(p)
n1 = a[n]
if p == n1:
nm[0] = nm[0] + 1
else:
nm[1] = nm[1] + 1
else:
nm[2] = nm[2] + 1
return nm
def start():
while True:
global a1
global n
global nn
nn += 1
answer = select()
pl = player()
p1 = listdo(pl)
a1 = listdo(answer)
if p1 == a1:
break
n = isin(p1,a1)
print('스트라이크:'+str(n[0]))
print('볼:'+str(n[1]))
print('아웃:'+str(n[2]))
start()
print('순서:'+str(nn))
import random
numbers = str(random.randrange(100,1000))
answer = [int(numbers[0]),int(numbers[1]),int(numbers[2])]
#print(answer)
a = 0
while True:
Strike = 0
Ball = 0
question = input()
questions = [int(question[0]),int(question[1]),int(question[2])]
for i in range(len(answer)):
if i==2:
a==1
else:
a=i
for j in range(a,len(questions)):
if answer[i]==questions[j] and i == j:
#print(i, j)
Strike +=1
elif answer[i]==questions[j] and i != j :
Ball += 1
print("{} Strike {} Ball".format(Strike, Ball))
if Strike == 3:
print("Success")
break
total= []
for k in range(1,10):
for i in range(1,10):
for j in range(1,10):
num=k*100+i*10+j
total.append(str(num))
def ball (arr,answer,s,b):
result =[]
for j in arr:
if len(set(answer) & set(j))==(s+b):
result.append(j)
return result
def strike (arr,answer,s):
result =[]
for k in arr:
n=0
for j in range(3):
if answer[j]==k[j]:
n+=1
if n == s:
result.append(k)
return result
def baseball (arr,answer,s,b):
result1 = ball(arr,answer,s,b)
result2 = strike(result1,answer,s)
return result2
n = int(input("테스트 케이스수:"))
case =[]
for k in range(n):
inp = list(map(int,input('질문숫자 스트라이크 볼 입력:').split(' ')))
case.append([str(inp[0]),inp[1],inp[2]])
for k in case:
total = baseball(total,k[0],k[1],k[2])
print(total)
print('가능한경우의 수는, 'len(total))
111~999 까지의 배열을 만들어두고 각 테스트 케이스에서 가능한 케이스들을 소거하여 남기는 방식입니다. 함수 ball 과 strike를 따로 짰고, 테스트 케이스에 따라 진행할수록 소거된 배열안에서 만족하는 경우의 수를 찾도록 했습니다