今天早上到现在看到了3篇关于FizzBuzzWhizz的问题,第一篇是@程序媛想事儿(Alexia)【最难面试的IT公司之ThoughtWorks代码挑战——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。

初看题目,很多人会以为就是求个算法,其实不然,说白了算法很简单,先判断第5规则,再判断第3,第4,其实3和4可以利用字符串拼接,无需重复来进行判断。我们逐一来看题目吧。

1、你首先说出三个不同的特殊数,要求必须是个位数,比如3、5、7

这是我们的输入,3个特殊数,必须为个位数。因为是根据报数,肯定n > 0,我们的特殊数m 也肯定必须>0,根据题目3,4,我觉得可以把1排除在外,当然也可以包含在其中,每个人理解不一样吧。因为是个位数,所以1<m<10。因为对m有要求,所以必须对我们3个特殊数进行一个验证。

2、让所有学生拍成一队,然后按顺序报数

这个简单,循环到100,我看到有朋友用了for(int i = 1;i<101;i++) ,不是不可以,但题目写了100个学生,为何你要去<101呢?<=100就可以了,尽量符合题目。

3、学生报数时,如果所报数字是第一个特殊数(3)的倍数,那么不能说该数字,而要说Fizz;如果所报数字是第二个特殊数(5)的倍数,那么要说Buzz;如果所报数字是第三个特殊数(7)的倍数,那么要说Whizz。

4. 学生报数时,如果所报数字同时是两个特殊数的倍数情况下,也要特殊处理,比如第一个特殊数和第二个特殊数的倍数,那么不能说该数字,而是要说FizzBuzz, 以此类推。如果同时是三个特殊数的倍数,那么要说FizzBuzzWhizz。

3和4的规则可以通过字符串拼接,合并在一起

if (m % num1 == 0) str += “Fizz”;

if (m % num2 == 0) str += “Buzz”;

if (m % num3 == 0) str += “Whizz”;

这些都是个人喜爱问题,你要一条条去验证判断,也没什么问题。

5、学生报数时,如果所报数字包含了第一个特殊数,那么也不能说该数字,而是要说相应的单词,比如本例中第一个特殊数是3,那么要报13的同学应该说Fizz。如果数字中包含了第一个特殊数,那么忽略规则3和规则4,比如要报35的同学只报Fizz,不报BuzzWhizz。

这条规则很特殊,所以我们的计算必须以if(5)else(3,4)进行,5的权重最高。

说完了规则,来看下其他的要求:

代码要求:

1,语言不限,Java, C#, Ruby, C++, Js, Python, Scala, objective-C统统可以,小语种也没问题,只要你擅长;

2,强烈建议写单元测试;

3,请展示出你超赞的面向对象/函数式编程功底;

4,建议尽量减少圈复杂度;

5,请提交可运行的代码,及相关构建脚本/说明文档(代码运行平台和环境);

2-4的要求非常重要,因为这是区别程序员级别的一个标准。测试代码尽量全面。

我对题目的做法

看到题目的时候,活动结束了,也没想细作,只能说个大概。我使用的是C#,使用的是面向对象的方法。我设计了一个Student类

  1. public class Student
  2. {
  3. private int Id { get; set; }
  4.  
  5. private IRule Rule { get; set; }
  6.  
  7. public Student(int id, IRule rule)
  8. {
  9. Id = id;
  10. Rule = rule;
  11. }
  12.  
  13. public void Say()
  14. {
  15. Console.WriteLine(Rule.RuleResult(Id));
  16. }
  17. }

100个学生,说明有100个对象,id为其所需要报的数,IRule则是其核心算法,解耦其算法,以免项目中会有算法变动。

  1. public interface IRule
  2. {
  3. string RuleResult(int number);
  4. }

如何实现IRule,则很简单了,这里说下第5个规则,如果含有第一个特殊数,比如第一个特殊数是3,则13,31,35都只报“Fizz”,第一篇的楼主用了indexof,把所需报的数变成了字符串,然后查找,不是不可,但你懂得,装箱拆箱不说,把数字变成了字符串就有点不符合题意了。我们可以使用加减的方法来进行判断。

13,23,33,43:n % 10 – m = 0

31,32,33,34: n - (m * 10) >= 0 && n –(m*10) < 10

规则3,4,利用字符串的拼接就可实现,大致的实现为:

  1. if (number % Number_1 == 0)
  2. {
  3. result += Num_Result_1;
  4. }
  5.  
  6. if (number % Number_2 == 0)
  7. {
  8. result += Num_Result_2;
  9. }
  10.  
  11. if (number % Number_3 == 0)
  12. {
  13. result += Num_Result_3;
  14. }

我的实现如下:

  1. public string RuleResult(int number)
  2. {
  3. var result = String.Empty;
  4. var isRuled = false;
  5. if ((number % 10 - Number_1) == 0 ||
  6. (number - (Number_1 * 10) >= 0 && number - (Number_1 * 10) < 10))
  7. {
  8. isRuled = true;
  9. result = Num_Result_1;
  10. }
  11. else
  12. {
  13. if (number % Number_1 == 0)
  14. {
  15. result += Num_Result_1;
  16. isRuled = true;
  17. }
  18.  
  19. if (number % Number_2 == 0)
  20. {
  21. result += Num_Result_2;
  22. isRuled = true;
  23. }
  24.  
  25. if (number % Number_3 == 0)
  26. {
  27. result += Num_Result_3;
  28. isRuled = true;
  29. }
  30. }
  31.  
  32. if (!isRuled)
  33. {
  34. result = number.ToString();
  35. }
  36.  
  37. return result;
  38. }

在不符合规则的情况下,返回number.ToString();

开始报数:

  1. IRule role = new FBWRule(numbers);
  2. for (var i = 1; i <= 100; i++)
  3. {
  4. var student = new Student(i, role);
  5. student.Say();
  6. }

基本就完成了,运行如下:

接下来就是写单元测试,我们只要针对IRule进行测试即可

  1. [Fact]
  2. public void RuleTest()
  3. {
  4. IRule rule = new FBWRule(3, 5, 7);
  5. Assert.Equal("Fizz", rule.RuleResult(30));
  6. Assert.Equal("Fizz", rule.RuleResult(35));
  7. Assert.Equal("FizzBuzz", rule.RuleResult(15));
  8. Assert.Equal("FizzBuzz", rule.RuleResult(45));
  9. Assert.Equal("BuzzWhizz", rule.RuleResult(70));
  10. }

写在最后

今天看到“ThoughtWorks”最难面试题,看了以后才发觉,很简单,但就是这么简单的题目,回答的答案都各有千秋,我相信考的不仅仅是算法,在代码中,思路中都能体现一个人的思想、行为,相信这是面试的关键吧。

刚试了下还能提交代码,写出来的目的也想看看的想法,接受任何批评和指点,谢谢。

关于今天很热的--FizzBuzzWhizz的更多相关文章

  1. 站在风口,你或许就是那年薪20w+的程序猿

    最近面试了一些人,也在群上跟一些群友聊起,发现现在的互联网真是热,一些工作才两三年的期望的薪资都是十几K的起,这真是让我们这些早几年就成为程序猿的情何以堪!正所谓是站在风口上,猪也能飞起来!我在这里就 ...

  2. Atitit 图像处理和计算机视觉的分类 三部分 图像处理 图像分析 计算机视觉

    Atitit 图像处理和计算机视觉的分类 三部分 图像处理 图像分析 计算机视觉 1.1. 按照当前流行的分类方法,可以分为以下三部分:三部分 图像处理 图像分析 计算机视觉1 1.2. 图像处理需要 ...

  3. 如何用Web技术开发Windows Form应用

    现在H5很热,很多互联网公司的产品都采用混合编程,其中各个平台客户端的“壳”为原生控件,但是内容很多都是Web网页,因此可以做出很多炫酷的效果.随着Node.js和Ionic等框架的出现,现在感觉Ja ...

  4. 【前端优化之渲染优化】大屏android手机动画丢帧的背后

    前言 上周我与阿里的宇果有一次技术的交流,然后对天猫H5站点做了一些浅层次的分析,后面点时间基本天天都会有联系,中途聊了一些技术细节.聊了双方团队在干什么,最后聊到了前端优化.因为我本身参与了几次携程 ...

  5. 防止sql注入和sqlmap介绍

    sql注入问题从WEB诞生到现在也一直没停过,各种大小公司都出现过sql注入问题,导致被拖库,然后存在社工库撞库等一系列影响. 防止sql注入个人理解最主要的就一点,那就是变量全部参数化,能根本的解决 ...

  6. Lesson 6 Percy Buttons

    Text I have just moved to a house in Bridge Street. Yesterday a bagger knocked at my door. He asked ...

  7. 微信小程序DEMO初体验

    小程序虽然被炒的很热,但是绝大部分人却从未亲自体验过,在2017年的上班第一天,献上一个小程序DEMO,您可以体验! 注意:由于微信限制,只能使用扫一扫来体验下方小程序DEMO. DEMO首页截图如下 ...

  8. 4年,如何从草根成长成为CTO-(第一篇)

    茫然的求索 那一年,刚好经济危机,毕业了.经过了很长时间的“网上海投”而杳无音讯之后,终于发现“经济危机真的和自己有点关系了” ,曾经以为经济危机和自己巴刚子打不着. 拿着简历,开始到处去跑招聘市场, ...

  9. 【webapp的优化整理】要做移动前端优化的朋友进来看看吧

    单页or多页 本文仅代表个人观点,不足请见谅,欢迎赐教. webapp 小钗从事单页相关的开发一年有余,期间无比的推崇webapp的网站模式,也整理了很多移动开发的知识点,但是现在回过头来看,weba ...

随机推荐

  1. Android-socket服务端断重启后,android客户端自动重连

    今天研究这个问题搞了整整一天啊!终于出来了,不过我没有多大的成就感,为什么呢?因为这不是我的劳动成果.同样的问题,我却没想出来!心塞的很啊…… 不过还是要给大家分享一下,希望给大家带来帮助! 先声明一 ...

  2. Fragment配合RadioGroup实现点击切换布局

    这里用了 compile 'com.jakewharton:butterknife:7.0.1' compile 'org.greenrobot:eventbus:3.0.0' MainActivit ...

  3. android-async-http AsyncHttpClient介绍

    前一阵子刚搬了家,加上公司要发新版本,所以一直比较忙,文章也好几周没更新了.难得这个周末有空,正好周内偶然间闲逛 发现这个很不错的第三方开源类库,针对Android开发中发送http请求的. 在And ...

  4. Java调用solrj5.5.3接口,查询数据

    前期准备 搭建solr服务 参考上一篇,搭建solr搜索服务. 添加依赖 maven工程的话,添加如下依赖, <!-- https://mvnrepository.com/artifact/or ...

  5. ORA-06502:PL/SQL :numberic or value error: character string buffer too small

    今天遇到一个错误提示:ORA-06502:PL/SQL :numberic or value error: character string buffer too small,一般对应的中文信息为:O ...

  6. Linux查看设置系统时区

    关于时区的概念,其实初中地理课已经涉及,很多人都多少了解一些,可能只是细节搞不太清楚.为什么会将地球分为不同时区呢?因为地球总是自西向东自转,东边总比西边先看到太阳,东边的时间也总比西边的早.东边时刻 ...

  7. 关于Java中枚举Enum的深入剖析

    在编程语言中我们,都会接触到枚举类型,通常我们进行有穷的列举来实现一些限定.Java也不例外.Java中的枚举类型为Enum,本文将对枚举进行一些比较深入的剖析. 什么是Enum Enum是自Java ...

  8. linux快速删除海量文件

    首先创建一个临时目录: /rubbish rsync --delete-before -a -H -v --progress --stats /rubbish /111 /111为目的目录 选项说明: ...

  9. [django]表格的添加与删除实例(可以借鉴参考)

    自己并未采用任何表格插件,参考网上例子,自己编写出来的django网页实例,请各位参考! 首先看图做事,表格布局采用bootstrap,俗话说bootstrap橹多了就会css了,呵呵,下面看图: 上 ...

  10. Java基础知识笔记(二:泛型和枚举)

    1.泛型 与面向对象的多态性相类似,应用泛型可以提高程序的复用性.与多态性不同的是,应用泛型可以减少数据的类型转换,从而提高代码的运行效率.泛型实际上是通过给类或接口增加类型参数实现的.不带泛型的类的 ...