Быки и коровы

(модификация задачи А.А. Суханова)

Компьютер и ребенок играют в следующую игру. Ребенок загадывает последовательность из четырех (не обязательно различных) цветов, выбранных из шести заданных. Для удобства будем обозначать цвета цифрами от 1 до 6. Компьютер должен отгадать последовательность, используя информацию, которую он получает из ответов ребенка.

Компьютер отображает на экране последовательность, а ребенок должен ответить (используя для ввода ответа клавиатуру) на два вопроса:

· сколько правильных цветов на неправильных местах;

· сколько правильных цветов на правильных местах.

Компьютер Ответ ребенка 1234 1 0 5156 2 1 6165 2 1 5625 1 2 5653 1 2 4655 0 4

Пример. Предположим, что ребенок загадал последовательность 4655. Один из возможных способов отгадать последовательность такой:

 

Написать программу, которая всегда отгадывает последовательность не более чем за шесть вопросов, в худшем случае - за десять.

 

Правильный выбор структур данных - это уже половина решения. Итак, структуры данных и процедура их инициализации.

Const Pmax=6*6*6*6;

Type Post=String[4];

Var A:array[1..Pmax] of Post;

B:array[1..Pmax] of boolean;

cnt:integer;{счетчик числа ходов}

ok:boolean;{найдено решение}

procedure Init;

var i,j,k,l:integer;

begin

for i:=1 to 6 do

for j:=1 to 6 do

for k:=1 to 6 do

for l:=1 to 6 do A[(i-1)*216+(j-1)*36+(k-1)*6+l]:= Chr(i+Ord(‘0’))+Chr(j+Ord(‘0’))+Chr(k+Ord(‘0’))+Chr(k+Ord(‘0’));

for i:=1 to Pmax do B[i]:=true;

cnt:=0;ok:=false;

end;

Поясним на примере идею решета. Пусть длина последовательности равна двум, а количество цветов - четырем. Ребенок загадал 32, а компьютер спросил 24. Ответ ребенка 1 0, фиксируем его в переменных kr (1) и bk(0).

A B B (после анализа bk) B (после анализа kr) Результат
true   false false
true     true
true   false false
true false   false
true false   false
true false   false
true false   false
true false   false
true   false false
true     true
true   false false
true false   false
true     true
true   false false
true     true
true false   false

Итак, было 16 возможных вопросов, после первого осталось четыре - работа решета. Функция, реализующая анализ элемента массива А, по значениям переменных kr и bk, имеет вид:

function Pr(a,b:Post;kr,bk:integer):boolean;

var i,x:integer;

begin

{проверка по “быкам”}

x:=0;

for i:=1 to 4 do if a[i]=b[i] then inc(x);

if x<>bk then begin Pr:=false;exit;end;

{проверка по “коровам”}

x:=0;

for i:=1 to 4 do if (a[i]<>b[i]) and (Pos(b[i],a)<>0) then inc(x);

if x<>kr then begin Pr:=false;exit;end;

Pr:=true;

end;

Логика - “сделать отсечение” по значению хода h.

procedure Hod(h:Post);

var i,kr,bk:integer;

begin

inc(cnt);write(cnt:2,’.’,h,’-’);

readln(kr,bk);

if bk=4 then begin ok:=true;<вывод результата>;end

else for i:=1 to Pmax do if B[i] and Not Pr(A[i],h,kr,bk) then B[i]:=false;

end;

Общая логика.

.....

begin

clrscr;

init;

hod(‘1223’);

while not ok do begin

выбор очередного хода из А

 

 

hod(h);

end;

end.

Дальнейшая работа с задачей требует ответа на следующие вопросы:

· Зависит ли значение cnt от выбора первого хода? Установить экспериментальным путем.

· Как логика выбора очередного хода влияет на результат игры? Исследовать. Например, выбрать тот элемент А (соответствующий элемент В должен быть равен true), в котором количество несовпадающих цифр максимально.