Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.01.2010, 01:04   #1
pif
Пользователь
 
Регистрация: 26.11.2008
Сообщений: 37
По умолчанию быки и коровы

помогите найти оптимальный алгоритм решения игры "Быки и коровы", ну те алгоритм Кнута, и его программную реализацию, можно просто программу не обязательно код, но лучше с кодом.
pif вне форума Ответить с цитированием
Старый 03.01.2010, 18:46   #2
Veselyn
Форумчанин
 
Аватар для Veselyn
 
Регистрация: 29.01.2009
Сообщений: 175
По умолчанию

Код:
#include <conio.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>

bool is_valid(char a[4],int size,char c)
{
	int no=size;
	for (int i=0;i<size;i++)
		if (a[i]!=c)
			no--;
	if (!no)
		a[size]=c;
	return !no;
}
int main(int argc, char* argv[])
{
	char my[4];
	int b,k,digits=0;
	char numbers[11]="0123456789";
	srand( (unsigned)time( NULL ) );
	while (digits<4)
		if (is_valid(my,digits,numbers[rand()%10]))
			digits++;
	//printf("my number is %c%c%c%c\n",my[0],my[1],my[2],my[3]);
	char enter[4],c(' ');
	b=k=digits=0;
	printf("Enter four digits or q for quit\n");
	while (c != 'q' && c != 'Q')
		if (isdigit(c=_getch()))
			if (is_valid(enter,digits,c))
			{
				printf("%c",c);
				for (int i=0;i<4;i++)
					if (my[i]==c)
						if (i==digits)
							b++;
						else
							k++;
				digits++;
				if (digits==4)
				{
					printf("\t\tb=%d k=%d\n",b,k);
					if (b==4){
						printf("U WON!");
						break;
					}
					b=k=digits=0;
				}
			}
	printf("\npress any key\n");
	_getch();
	return 0;
}
Все люди делятся на 10 типов: те, кто понимают двоичную систему счисления и те, кто нет.
Veselyn вне форума Ответить с цитированием
Старый 03.01.2010, 20:54   #3
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

2 Veselyn: вроде как надо, чтобы прога отгадывала, а не юзер.
Кнута он или нет, не знаю, но суть такая: сначала считаем подходящими все правильные числа; спрашиваем про какое-нибудь число и, исходя из ответа, убираем из рассмотрения числа, на которые ответ был бы другим, так до тех пор, пока не угадаем.
Код:
#include <iostream>
#include <cstring>
#include <limits>

using namespace std;

void Split(int x, int& a, int& b, int& c, int& d)
{
	d = x % 10; x /= 10;
	c = x % 10; x /= 10;
	b = x % 10; x /= 10;
	a = x % 10;
}

bool IsValid(int x)
{
	int a, b, c, d;
	Split(x, a, b, c, d);
	return
		(a >= 1) && (a <= 9) &&
		(a != b) && (a != c) && (a != d) && (b != c) && (b != d) && (c != d);
}

bool Matches(int n1, int n2, int bulls, int cows)
{
	int a1, b1, c1, d1, a2, b2, c2, d2;
	Split(n1, a1, b1, c1, d1);
	Split(n2, a2, b2, c2, d2);
	return
		bulls == (
			(a1 == a2) + (b1 == b2) + (c1 == c2) + (d1 == d2)
		) &&
		cows == (
			(a1 == b2) + (a1 == c2) + (a1 == d2) +
			(b1 == a2) + (b1 == c2) + (b1 == d2) +
			(c1 == a2) + (c1 == b2) + (c1 == d2) +
			(d1 == a2) + (d1 == b2) + (d1 == c2)
		);
}

const int setSize = 10000;
bool badNum[setSize];

int main()
{
	memset(badNum, 0, sizeof(badNum));
	for (int i = 0; i < setSize; i++)
		badNum[i] = !IsValid(i);
	while (true)
	{
		int bulls, cows;
		int question;
		for (question = 0; question < setSize && badNum[question]; question++);
		if (question >= setSize)
		{
			cout << "bye 8-|";
			break;
		}
		cout << question << " ???" << endl;
		cout << "bulls, cows: ";
		cin >> bulls >> cows;
		if (bulls == 4 && cows == 0)
		{
			cout << "that's it :-)";
			break;
		}
		for (int i = 0; i < setSize; i++)
			badNum[i] = badNum[i] || !Matches(i, question, bulls, cows);
	}
	cin.ignore(numeric_limits<streamsize>::max(), '\n');
	cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
Somebody вне форума Ответить с цитированием
Старый 16.04.2013, 19:49   #4
ddwrt
 
Регистрация: 16.04.2013
Сообщений: 3
По умолчанию

Цитата:
Сообщение от Somebody Посмотреть сообщение
2 Veselyn: вроде как надо, чтобы прога отгадывала, а не юзер.
Кнута он или нет, не знаю, но суть такая: сначала считаем подходящими все правильные числа; спрашиваем про какое-нибудь число и, исходя из ответа, убираем из рассмотрения числа, на которые ответ был бы другим, так до тех пор, пока не угадаем.
Код:
#include <iostream>
#include <cstring>
#include <limits>

using namespace std;

void Split(int x, int& a, int& b, int& c, int& d)
{
	d = x % 10; x /= 10;
	c = x % 10; x /= 10;
	b = x % 10; x /= 10;
	a = x % 10;
}

bool IsValid(int x)
{
	int a, b, c, d;
	Split(x, a, b, c, d);
	return
		(a >= 1) && (a <= 9) &&
		(a != b) && (a != c) && (a != d) && (b != c) && (b != d) && (c != d);
}

bool Matches(int n1, int n2, int bulls, int cows)
{
	int a1, b1, c1, d1, a2, b2, c2, d2;
	Split(n1, a1, b1, c1, d1);
	Split(n2, a2, b2, c2, d2);
	return
		bulls == (
			(a1 == a2) + (b1 == b2) + (c1 == c2) + (d1 == d2)
		) &&
		cows == (
			(a1 == b2) + (a1 == c2) + (a1 == d2) +
			(b1 == a2) + (b1 == c2) + (b1 == d2) +
			(c1 == a2) + (c1 == b2) + (c1 == d2) +
			(d1 == a2) + (d1 == b2) + (d1 == c2)
		);
}

const int setSize = 10000;
bool badNum[setSize];

int main()
{
	memset(badNum, 0, sizeof(badNum));
	for (int i = 0; i < setSize; i++)
		badNum[i] = !IsValid(i);
	while (true)
	{
		int bulls, cows;
		int question;
		for (question = 0; question < setSize && badNum[question]; question++);
		if (question >= setSize)
		{
			cout << "bye 8-|";
			break;
		}
		cout << question << " ???" << endl;
		cout << "bulls, cows: ";
		cin >> bulls >> cows;
		if (bulls == 4 && cows == 0)
		{
			cout << "that's it :-)";
			break;
		}
		for (int i = 0; i < setSize; i++)
			badNum[i] = badNum[i] || !Matches(i, question, bulls, cows);
	}
	cin.ignore(numeric_limits<streamsize>::max(), '\n');
	cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
извините пожалуйста, а вы не подскажете, что делает функция Split?
ddwrt вне форума Ответить с цитированием
Старый 16.04.2013, 20:04   #5
Izobara
Форумчанин
 
Аватар для Izobara
 
Регистрация: 26.12.2012
Сообщений: 227
По умолчанию

Общий алгоритм выглядит так (нам ведь отвечают больше-меньше, я помню):
Вначале берем средину числа (если 100, то берем 50). В зависимости от ответа отсекаем ненужную половину, а от оставшейся берем опять середину (51-100 - берем 75)... И дальше по фрактальной зависимости.
"I believe I can fly" - C++, "What do you want from me" - Delphi, "Yesterday" - Pascal, "Let it be" - C#... Программисты-музыканты-полиглоты поймут
Izobara вне форума Ответить с цитированием
Старый 16.04.2013, 20:08   #6
ddwrt
 
Регистрация: 16.04.2013
Сообщений: 3
По умолчанию

Цитата:
Сообщение от Izobara Посмотреть сообщение
Общий алгоритм выглядит так (нам ведь отвечают больше-меньше, я помню):
Вначале берем средину числа (если 100, то берем 50). В зависимости от ответа отсекаем ненужную половину, а от оставшейся берем опять середину (51-100 - берем 75)... И дальше по фрактальной зависимости.
все равно немного не понял, мы же берем остаток от деления, а потом еще и делим на 10?
ddwrt вне форума Ответить с цитированием
Старый 16.04.2013, 22:59   #7
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Split просто разбивает число [abcd] на цифры.
Somebody вне форума Ответить с цитированием
Старый 16.04.2013, 23:21   #8
ddwrt
 
Регистрация: 16.04.2013
Сообщений: 3
По умолчанию

Цитата:
Сообщение от Somebody Посмотреть сообщение
Split просто разбивает число [abcd] на цифры.
Благодарю!
ddwrt вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Игра быки и коровы Денис56 Помощь студентам 6 21.12.2009 01:09
Быки и коровы Димарик Помощь студентам 5 01.12.2009 19:51
игра "быки и коровы на VB" Ыыыга Помощь студентам 1 21.05.2009 16:37
Игра "Быки и коровы"(Паскаль) bobby2008 Помощь студентам 33 12.05.2009 23:44