由学生按某规则依次报数的游戏引发的问题

前段时间Q群里有提问如下,编写程序解决一个学生按规则依次报数的体育游戏问题。编程语言不限,Java, C#, Ruby, C++, Js, Python, Scala, objective-C统统可以,小语种也没问题。

学生按某规则依次报数的游戏

一、问题描述:

你是一名体育老师,在某次课距离下课还有五分钟时,你决定搞一个游戏。此时有100名学生在上课。游戏的规则是:
1. 你首先说出三个不同的特殊数,要求必须是个位数,比如3、5、7。
2. 让所有学生拍成一队,然后按顺序报数。
3. 学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,而要说Fizz;如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz;如果所报数字是第三个特殊数(7)的倍数,那么要说Whizz。
4. 学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,比如第一个特殊数和第二个特殊数的倍数,那么不能说该数字,而是要说FizzBuzz, 以此类推。如果同时是三个特殊数的倍数,那么要说FizzBuzzWhizz。
5. 学生报数时,如果所报数字包含了第一个特殊数,那么也不能说该数字,而是要说相应的单词,比如本例中第一个特殊数是3,那么要报13的同学应该说Fizz。如果数字中包含了第一个特殊数,那么忽略规则3和规则4,比如要报35的同学只报Fizz,不报BuzzWhizz。

现在,我们需要你完成一个程序来模拟这个游戏,它首先接受3个特殊数,然后输出100名学生应该报数的数或单词。比如,

输入
3,5,7
输出(片段)

1
2
Fizz
4
Buzz
Fizz
Whizz
8
Fizz
Buzz
11
Fizz
Fizz
Whizz
FizzBuzz
16
17
Fizz
19
Buzz

一直到100

二、解决方法:

这个问题主要是要理解提到的游戏规则,然后为每个学生对应的序号匹配出对应的rule模式,这样问题就解决了。下面是自己用C写的解决方法:

main.c
/**
 * 游戏体育老师写3个个位数,100名同学按一定规则报数的问题
 * @filename: game.c
 * @author  : vfhky  2014.10.25  https://typecodes.com
 */

#include "stdio.h"
#include "string.h"
#define TotalNum 100

/**
 * 获取一个1000范围内的整形数据的各个位
 * @param [in]  number	学生序号
 * @param [in/out]  highnum 将每个位依次保存到数组
 * return 0: 成功; -1:整数超出范围
 */
int gethighnum( int number, char highnum[] )
{
	if( number < 10 )
	{
		*highnum = number + 48;
		return 1;
	}
	else if( number < 100 )
	{
		*highnum = number/10 + 48;
		*(highnum+1) = number%10 + 48;
		return 1;
	}
	else if( number < 1000 )
	{
		*highnum = number/100 + 48;
		*(highnum+1) = ( number - (number/100)*100 )/10 + 48;
		*(highnum+2) = number%100 + 48;
		return 1;
	}
	else
		return -1;
}


/**
 * 将学生序号按照规则3/4/5处理: 最后匹配出对应的字符串
 * @param [in]  inputa	老师输入的第一个数字
 * @param [in]  inputb	老师输入的第二个数字
 * @param [in]  inputc	老师输入的第三个数字
 * @param [in]  number	学生序号
 * @param [in/out]  matchstr	匹配的字符串
 * @param [in/out]  flag		是否包含了匹配数字, 0:未包含   1: 包含
 * return -1: 该学生序号不合法;  0:未包含第一个数字;  1:包含第一个数字;
 */
int rules( int inputa, int inputb, int inputc, int number, char matchstr[], int * flag )
{
	int result;
	char highnum[4] = { 0 };	//整数的各个位
	*flag = 0;
	result = gethighnum( number, highnum );		//获取该整数的所有高位字符highnum
	if( result != 1 )
		return -1;

	/* 检测是否包含第一个特殊数字 */
	for( result=0; result<strlen(highnum); result++ )
	{
		if( inputa == highnum[result] - 48 )
			return 1;
	}

	memset( matchstr, 0x30, 4 );
    if( number % inputa == 0 )
    {
	    *matchstr = 0x31;
	    *flag = 1;
    }
    
    if( number % inputb == 0 )
    {
	    *(matchstr+1) = 0x32;
	    *flag = 1;
    }
    
    if( number % inputc == 0 )
    {
	    *(matchstr+2) = 0x33;
	    *flag = 1;
    }

	return 0;
}


int main( int argc, char * argv[] )
{
	int stuinx = 1;		//学生序号, 从1开始报数
	int a, b, c;		//老师输入的三个整型数据
	int result;			//临时数据

	/* 初始化对应的三个字符串数据 */
	char arr1[5] = "Fizz";
	char arr2[5] = "Buzz";
	char arr3[6] = "Whizz";
	char arr[14];

	/* 老师输入3个整形数据 */
	printf( "Please input three integer number:\n eg. 3, 5, 7\n" );
	scanf( "%d, %d, %d", &a, &b, &c );
	if( a>0xa || b>0xa || c>0xa )
	{
		printf( "You should inpute three integer number!\n" );
		return -1;
	}
	printf( "You have inputed three integer number:[%d], [%d], [%d]\n", a, b, c );

	int flag, *p;
	p = &flag;
	char matchstr[4] = { 0 };

	/* 学生开始依次报数 */
	for( ; stuinx<TotalNum+1; stuinx++ )
	{
		/* 每次循环重新初始化数据 */
		flag = 0;
		memset( arr, 0x00, sizeof(arr) );
		memset( matchstr, 0x30, sizeof(matchstr) );

		/* 根据规则获取匹配字符串matchnum以及是否包含匹配字符的标志*p */
		result = rules( a, b, c, stuinx, matchstr, p );
		if( result == -1 )
			printf( "The total number of students can not be more than 1000!\n" );
		else if( result )
		{
			strcpy( arr, arr1 );
			printf( "No.[%d] says [%s]\n", stuinx, arr );
			continue;
		}
		if( *p )
		{
		    /* 如果包含了非第一个特殊数字 */
			for( result=0; result<strlen(matchstr); result++ )
			{
				if( matchstr[result] == 0x31 )
					strcat( arr, arr1 );
				else if( matchstr[result] == 0x32 )
					strcat( arr, arr2 );
				else if( matchstr[result] == 0x33 )
					strcat( arr, arr3 );
			}
			printf( "No.[%d] says [%s]\n", stuinx, arr );
		}
		else
			printf( "No.[%d] says [%d]\n", stuinx, stuinx );
	}

	return 0;
}

三、测试结果

GCC编译后执行,结果如下图所示。但发现没有任何一位学生在报数时,需要报包含FizzBuzzWhizz全部这三个单词的组合,例如不会出现题目规则4中所述的FizzBuzzWhizz。原因可以直接从前面的几条规则中推导出来。

测试结果

评论

评论加载中…