ThoughtWorks代码挑战——FizzBuzzWhizz
很久没发表过文章了,今天看到一篇文章 最难面试的IT公司之ThoughtWorks代码挑战——FizzBuzzWhizz游戏(C#解法)
看到LZ的2B青年代码,实在是惨不忍睹,故写篇文章来探讨下这类问题的一般思考。
原题:
FizzBuzzWhizz
你是一名体育老师,在某次课距离下课还有五分钟时,你决定搞一个游戏。此时有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。
一道看似简单的题目,其实并没有那么简单,如果你直接写的话,那估计就是:
if, if , else if , if , for, [0] [1] [2]….
我们来理解下这道题:
1. 你首先说出三个不同的特殊数,要求必须是个位数,比如3、5、7。
不同的三个数,必须是个位数,这些都是验证条件,你注意到了吗?
2. 让所有学生拍成一队,然后按顺序报数。
生成顺序的数字。
3. 学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,而要说Fizz;如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz;如果所报数字是第三个特殊数(7)的倍数,那么要说Whizz。
规则:如果是某个特殊数的倍数,输出对应的值,否则输出数字。
4. 学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,比如第一个特殊数和第二个特殊数的倍数,那么不能说该数字,而是要说FizzBuzz, 以此类推。如果同时是三个特殊数的倍数,那么要说FizzBuzzWhizz。
规则:如果是多个特殊数的倍数,输出所有的对应值。
5. 学生报数时,如果所报数字包含了第一个特殊数,那么也不能说该数字,而是要说相应的单词,比如本例中第一个特殊数是3,那么要报13的同学应该说Fizz。如果数字中包含了第一个特殊数,那么忽略规则3和规则4,比如要报35的同学只报Fizz,不报BuzzWhizz。
规则:如果包含第一个特殊数字,则只输出第一个特殊数字所对应的值。
OK,思考下我们该怎样做?。。
我们来抽象的理解下题目: “给你输入一堆数字,然后你根据一定的规则进行parse,然后输出parse 的结果。”
所以这道题目想考察的是你如何定义这些规则,如何应用这些规则,该如何parse呢?
让我们看下规则Rule:
Rule,有优先级,然后可以对输入进行Parse,然后Parse又需要一个对应的字典。
所以Rule 像这样:
abstract class Rule
{
public abstract int Priority { get; } public Dictionary<int, string> SpecialDictionary { get; set; } public Rule(Dictionary<int, string> specialDictionary)
{
this.SpecialDictionary = specialDictionary;
} public bool ParseNum(int num, ref string result)
{
if ((SpecialDictionary != null) && (SpecialDictionary.Count > ))
{
return ParseNumCore(num, ref result);
}
else
{
return false;
}
} protected abstract bool ParseNumCore(int num, ref string result);
}
接着Rule3: 如果是某个特殊数的倍数,输出对应的值,否则输出数字,输出数字我放到最外层去处理了,当然如果需要也可以写个Rule2.
class Rule3 : Rule
{
public Rule3(Dictionary<int, string> specialDictionary)
: base(specialDictionary)
{
} public override int Priority
{
get { return ; }
} protected override bool ParseNumCore(int num, ref string result)
{
foreach (var special in SpecialDictionary)
{
if (num % special.Key == )
{
result = special.Value;
return true;
}
} return false;
}
}
Rule4:如果是多个特殊数的倍数,输出所有的对应值。
class Rule4 : Rule
{
public Rule4(Dictionary<int, string> specialDictionary)
: base(specialDictionary)
{
} public override int Priority
{
get { return ; }
} protected override bool ParseNumCore(int num, ref string result)
{
List<string> matches = new List<string>(); foreach (var special in SpecialDictionary)
{
if (num % special.Key == )
{
matches.Add(special.Value);
}
} if (matches.Count > )
{
result = string.Join("", matches);
return true;
}
else
{
return false;
}
}
}
Rule5:如果包含第一个特殊数字,则只输出第一个特殊数字所对应的值。
class Rule5 : Rule
{
public Rule5(Dictionary<int, string> specialDictionary)
: base(specialDictionary)
{
} public override int Priority
{
get { return ; }
} protected override bool ParseNumCore(int num, ref string result)
{
if (SpecialDictionary.Count > )
{
var firstSpecial = SpecialDictionary.First();
if (num.ToString().Contains(firstSpecial.Key.ToString()))
{
result = firstSpecial.Value;
return true;
}
} return false;
}
}
接下来:最重要的就是Parse 逻辑了,想一想应该怎样调用这些Rule呢(visitor ?):
foreach (var student in studentNums)
{
string parseResult = student.ToString();
foreach (Rule rule in rules)
{
if (rule.ParseNum(student, ref parseResult))
{
break;
}
} Console.WriteLine(parseResult);
}
下面是完整的代码:
private static void FizzBuzz()
{
bool isValidInput = false;
do
{
Console.WriteLine("please input three numbers which is units digit, use ',' division ");
string[] inputNums = Console.ReadLine().Split(','); if (ValidSpecialInput(inputNums))
{
isValidInput = true; // create special dictionary to parse the students nums.
Dictionary<int, string> special = new Dictionary<int, string>();
special.Add(Int32.Parse(inputNums[]), "Fizz");
special.Add(Int32.Parse(inputNums[]), "Buzz");
special.Add(Int32.Parse(inputNums[]), "Whizz"); // get students nums.
int studentsCount = ;
var studentNums = Enumerable.Range(, studentsCount); // create rules to parse.
var rules = new List<Rule>()
{
new Rule5(special),
new Rule4(special),
new Rule3(special),
}.OrderByDescending(r => r.Priority); // parse logic.
foreach (var student in studentNums)
{
string parseResult = student.ToString();
foreach (Rule rule in rules)
{
if (rule.ParseNum(student, ref parseResult))
{
break;
}
} Console.WriteLine(parseResult);
} Console.ReadLine();
}
else
{
Console.WriteLine("the input is not valid.");
}
}
while (isValidInput == false);
} private static bool ValidSpecialInput(string[] specialInputs)
{
bool result = false;
if (specialInputs.Length == )
{
return specialInputs.All(input =>
{
int num = ;
return Int32.TryParse(input, out num) && (num > ) && (num < );
});
} return result;
}
一些后续思考:
1:如果输入的不是三个,而是4个,5个 special, 应该怎么改?
2:如果学生数量不是100个,是1000个?
3:如果有限考虑Rule3,然后是Rule4,Rule5,应该怎么改?
4:如果还有另一个限制条件:比如如果数字是素数,把对应的值按反序输出,如何处理?
5:如果输入不是数字,而是字符串,应该如何处理?
完整源码下载:http://files.cnblogs.com/LoveJenny/FizzBuzz.7z
ThoughtWorks代码挑战——FizzBuzzWhizz的更多相关文章
- ThoughtWorks代码挑战——FizzBuzzWhizz游戏 通用高速版(C/C++ & C#)
最早看到这个题目是从@ 程序媛想事儿(Alexia) 的 最难面试的IT公司之ThoughtWorks代码挑战——FizzBuzzWhizz游戏 开始的,然后这几天陆陆续续有N个小伙伴发表了自己的文章 ...
- 最难面试的IT公司之ThoughtWorks代码挑战——FizzBuzzWhizz游戏
最近互联网招聘平台拉勾网在五一期间推出个“最难面试的IT公司”代码挑战活动,评选出了5个最难面试的IT公司,即:ThoughtWorks.Google.Unisys.Rackspace.Cypress ...
- 最艰难的采访IT公司ThoughtWorks代码挑战——FizzBuzzWhizz游戏
最近的互联网招聘平台拉勾网在五月推出了"最艰难的采访IT公司"码挑战活动,评选出了5个最难面试的IT公司,即:ThoughtWorks.Google.Unisys.Rackspac ...
- 最难面试的IT公司之ThoughtWorks代码挑战——FizzBuzzWhizz游戏(C#解法)
原题 看到那么多人看到前面这么糟粕的代码各种不忍直视后,楼主还是把最终实现放在页首吧. Console.WriteLine("说出三个不同的特殊数,用','隔开 &q ...
- 原生js代码挑战之动态添加双色球
var ballArr = []; //存放已有的红球,用来排除重复和排序window.onload = function(){ var btn = document.createElement(&q ...
- 关于今天很热的--FizzBuzzWhizz
今天早上到现在看到了3篇关于FizzBuzzWhizz的问题,第一篇是@程序媛想事儿(Alexia)[最难面试的IT公司之ThoughtWorks代码挑战--FizzBuzzWhizz游戏]其实题目不 ...
- 2014年5月份第1周51Aspx源码发布详情
郑州某高校学生考评系统源码 2014-5-5 [VS2008]功能介绍: 1.用户角色有部主任.教师.学生等. 2.可添加班级考评项目.学生考评项目. 3.可指定学生对班级.学生某考评项 ...
- 编译器是如何实现32位整型的常量整数除法优化的?[C/C++]
引子 在我之前的一篇文章[ ThoughtWorks代码挑战——FizzBuzzWhizz游戏 通用高速版(C/C++ & C#) ]里曾经提到过编译器在处理除数为常数的除法时,是有优化的,今 ...
- ThoughtWorks 面试备忘录
ThoughtWorks 面试备忘录 前言 前段时间 ThoughtWorks 在网上和拉勾网合作搞了一次网络招聘,名为抛弃简历!让代码说话!,可谓赚足了眼球,很多程序猿纷纷摩拳擦掌.踊跃提交代码,在 ...
随机推荐
- *** $CI =& get_instance() 用法:关于CodeIgniter中get_instance() 函数
使用场景: 注意 get_instance 的使用场景,这个方法并不是用在控制器中的.而是用在控制器外面,比如类库中,想操作 CI 超级对象的时候,超级对象实际上就是当前控制器的实例. 你随便下个CI ...
- APP产品交互设计分析总结(不断更新中...)
1.首页中的最下方的TAB和中部的TAB的区别 最下面的tab按钮应该是核心级模块级的大功能入口 中间的按钮应该是次核心级页面级的小功能入口 2.对于编辑是在单页内实现好还是跳转到新页面实现好 内容比 ...
- Delphi容器类之---TList、TObjectList、TComponentList、TClassList
转载自:http://blog.csdn.net/iseekcode/article/details/4922001 从Delphi5开始VCL中增加了新的Contnrs单元,单元中定义了8个新的类, ...
- react学习与简介
简介: React是Facebook开发的一款JS库 React解决了什么问题? 1).首先是以往mvc模式的缺陷,当代码库庞大时,mvc非常的复杂,每添加新的功能,项目的复杂度就几何倍的增长,导致代 ...
- Js 日期转换函数(UTC时间转换及日期想加减)
IOS上Js日期转换中new Date("yyyy-mm-dd")不能正常工作,必须使用new Date("yyyy/MM/dd"); 日期相加减: Date. ...
- 【leetcode】Add Two Numbers
题目描述: You are given two linked lists representing two non-negative numbers. The digits are stored in ...
- configuration error-could not load file or assembly crystaldecisions.reportappserver.clientdoc
IIS启动网站后报错: configuration error Could not load file or assembly 'crystaldecisions.reportappserver.cl ...
- Learn Git and GitHub without any code!
What is GitHub? GitHub is a code hosting platform for version control and collaboration.代码托管平台. repo ...
- Windows - 性能监控之磁盘剩余空间大小警报
开始 -> 运行 -> 键入命令 perfmon.msc 数据收集器(Data Collector Sets) -> 用户自定义(User Defined)
- vs2013中一: 无法查找或打开 PDB 文件解决办法 二:解决This function or variable may be unsafe
一 链接地址: https://www.baidu.com/s?wd=%E6%97%A0%E6%B3%95%E6%9F%A5%E6%89%BE%E6%88%96%E6%89%93%E5%BC%80 ...