问题描述

FizzBuzz问题:一个大于0的自然数能整除3,将输出“Fizz”;能整除5,将输出“Buzz”;能整除3和5,将输出“FizzBuzz”;否则输出自己。

逆FizzBuzz问题最短序列:已知一个FizzBuzz问题的非数字输出序列,求能获得该序列的最短连续数字序列。如“Fizz”的最短序列是“3”,“Fizz Buzz”的最短序列是“9 10”,而不是“3 4 5”。

编程实现

  1. <?php
  2.  
  3. /**
  4. * @author cenze
  5. *
  6. * 反FizzBuzz问题求最短序列
  7. *
  8. * $inverseFizzBuzz = new InverseFizzBuzz([
  9. * 'fizz',
  10. * 'fizz',
  11. * 'buzz',
  12. * ]);
  13. * $inverseFizzBuzz->sequence():
  14. * Array ( [0] => 6 [1] => 7 [2] => 8 [3] => 9 [4] => 10 )
  15. */
  16. class InverseFizzBuzz
  17. {
  18. // FizzBuzz问题赋值
  19. const FizzBuzz = [
  20. 'fizz' => 3,
  21. 'buzz' => 5,
  22. 'fizzbuzz' => 15
  23. ];
  24.  
  25. // 预定义问题区间
  26. private $range = [
  27. 1,
  28. 100
  29. ];
  30.  
  31. // 待求序列
  32. private $list = [];
  33.  
  34. // 待求序列包含项数统计
  35. private $listItemsCount = 0;
  36.  
  37. public function __construct($list = [], $range = [])
  38. {
  39. $this->init($list, $range);
  40. }
  41.  
  42. /**
  43. * 待求序列、区间初始化
  44. *
  45. * @param array $list
  46. * 待求序列
  47. * @param array $range
  48. * 问题区间
  49. * @param bool $check
  50. * 是否检查属性已完成初始化
  51. *
  52. * @return void
  53. */
  54. private function init($list = [], $range = [], $check = false)
  55. {
  56. if ($list) {
  57. $this->list = $this->inverseList($list);
  58. $this->listItemsCount = count($this->list);
  59. if (! $this->listItemsCount) {
  60. exit('Invalid list.');
  61. }
  62. }
  63.  
  64. if ($range) {
  65. $this->range = $range;
  66. }
  67.  
  68. if ($check) {
  69. if (! $this->list) {
  70. exit('Property list uninitialized.');
  71. }
  72. }
  73. }
  74.  
  75. /**
  76. * 将待求解序列反转
  77. *
  78. * @param array $list
  79. * 待求解序列
  80. *
  81. * @return mixed
  82. */
  83. private function inverseList($list)
  84. {
  85. $inverseList = [];
  86. foreach ($list as $item) {
  87. if (! array_key_exists($item, self::FizzBuzz)) {
  88. return null;
  89. }
  90. $inverseList[] = self::FizzBuzz[
  91. $item
  92. ];
  93. }
  94.  
  95. return $inverseList;
  96. }
  97.  
  98. /**
  99. * 搜索最短序列是否存在
  100. *
  101. * @param array $list
  102. * 待求序列
  103. * @param array $range
  104. * 问题区间
  105. *
  106. *
  107. * @return mixed
  108. */
  109. public function sequence($list = [], $range = [])
  110. {
  111. $this->init($list, $range, true);
  112.  
  113. $sequences = $this->findSequences();
  114. if (! $sequences) {
  115. return 'Found no sequences.';
  116. }
  117.  
  118. $sequence = $this->findShortestSequence($sequences);
  119. // 将最短序列序列化后返回
  120. return range($sequence[0], $sequence[$this->listItemsCount - 1]);
  121. }
  122.  
  123. /**
  124. * 搜索最短序列(未序列化)
  125. *
  126. * @param array $sequences
  127. * 序列集合,包含最短序列
  128. *
  129. * @return array
  130. */
  131. private function findShortestSequence($sequences)
  132. {
  133. // 默认第一条为最短
  134. $shortestSequence = $sequences[0];
  135. // 把每一个序列看做一条路径,都有对应的长度。记录最短的序列长度
  136. $shortestSequenceLength = $sequences[0][$this->listItemsCount - 1] - $sequences[0][0];
  137. // 为array_reduce()定义一个callback,用来搜索最短序列
  138. $findShortestSequence = function ($shortestSequence, $currentSequence) use(&$shortestSequenceLength) {
  139. $currentSequenceLength = $currentSequence[$this->listItemsCount - 1] - $currentSequence[0];
  140. if ($currentSequenceLength < $shortestSequenceLength) {
  141. $shortestSequenceLength = $currentSequenceLength;
  142. return $currentSequence;
  143. } else {
  144. return $shortestSequence;
  145. }
  146. };
  147.  
  148. return array_reduce($sequences, $findShortestSequence, $shortestSequence);
  149. }
  150.  
  151. /**
  152. * 从指定位置开始搜索指定项目的序列
  153. *
  154. * @param int $item
  155. * 指定项目
  156. * @param int $start
  157. * 起始搜索位置
  158. *
  159. * @return int
  160. */
  161. private function findItemSequenceFromPosition($item, $start)
  162. {
  163. if ($start % $item == 0) {
  164. return $start;
  165. }
  166.  
  167. return $start + ($item - $start % $item);
  168. }
  169.  
  170. /**
  171. * 从指定位置开始搜索首个序列
  172. *
  173. * @param int $start
  174. * 起始搜索位置
  175. *
  176. * @return mixed
  177. */
  178. private function findSequenceFromPosition($start)
  179. {
  180. $listSequence = [];
  181. for ($i = 0; $i < $this->listItemsCount; $i ++) {
  182. $itemSequence = $this->findItemSequenceFromPosition($this->list[$i], $start);
  183. if ($itemSequence > $this->range[1]) {
  184. return null;
  185. } else {
  186. $listSequence[] = $itemSequence;
  187. $start = $itemSequence + 1;
  188. }
  189. }
  190.  
  191. return $listSequence;
  192. }
  193.  
  194. /**
  195. * 找到多个序列,其中包括最短序列
  196. *
  197. * @return void
  198. */
  199. private function findSequences()
  200. {
  201. $sequences = [];
  202. // 以第一个项为初始搜索位置在预定区间中搜索,且以第一个项为递增步长向后逐步搜索
  203. for ($start = $this->list[0]; $start <= $this->range[1]; $start += $this->list[0]) {
  204. // 只需找到指定位置开始的第一个序列即可
  205. if ($sequence = $this->findSequenceFromPosition($start)) {
  206. $sequences[] = $sequence;
  207. }
  208. }
  209.  
  210. return $sequences;
  211. }
  212. }

逆FizzBuzz问题求最短序列的更多相关文章

  1. hdu 1394 zoj 1484 求旋转序列的逆序数(并归排序)

    题意:给出一序列,你可以循环移动它(就是把后面的一段移动到前面),问可以移动的并产生的最小逆序数. 求逆序可以用并归排序,复杂度为O(nlogn),但是如果每移动一次就求一次的话肯定会超时,网上题解都 ...

  2. hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数 && 归并排序求逆序数)

    题目链接 题意: 给一个n个数的序列a1, a2, ..., an ,这些数的范围是0-n-1, 可以把前面m个数移动到后面去,形成新序列:a1, a2, ..., an-1, an (where m ...

  3. 动态规划求一个序列的最长回文子序列(Longest Palindromic Substring )

    1.问题描述 给定一个字符串(序列),求该序列的最长的回文子序列. 2.分析 需要理解的几个概念: ---回文 ---子序列 ---子串 http://www.cnblogs.com/LCCRNblo ...

  4. [zz]求一维序列的信息熵(香浓熵)的matlab程序实例

    对于一个二维信号,比如灰度图像,灰度值的范围是0-255,因此只要根据像素灰度值(0-255)出现的概率,就可以计算出信息熵.    但是,对于一个一维信号,比如说心电信号,数据值的范围并不是确定的, ...

  5. poj 2001:Shortest Prefixes(字典树,经典题,求最短唯一前缀)

    Shortest Prefixes Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 12731   Accepted: 544 ...

  6. 39. 求分数序列前N项和

    求分数序列前N项和 #include <stdio.h> int main() { int i, n; double numerator, denominator, item, sum, ...

  7. 20. 求阶乘序列前N项和

    求阶乘序列前N项和 #include <stdio.h> double fact(int n); int main() { int i, n; double item, sum; whil ...

  8. 19. 求平方根序列前N项和

    求平方根序列前N项和 #include <stdio.h> #include <math.h> int main() { int i, n; double item, sum; ...

  9. OpenJudge计算概论-求分数序列和

    /*======================================================================== 求分数序列和 总时间限制: 1000ms 内存限制 ...

随机推荐

  1. Mybatis实现部门表增删改查以及排序

    废话不说,直接开门见山! 需要在WebContent下的lib下导入两个包 mybatis-3.2.5.jar ojdbc6.jar package com.xdl.entity; import ja ...

  2. 《JavaScript高级程序设计》笔记:DOM扩展(十一)

    选择符API querySelector()方法 // 取得body元素 var tbody = document.querySelector('body'); // 取得ID为"myDIV ...

  3. 【AO笔记】关于创建IFeatureClass中的参考系设置——不能为null也不能为IUnknownCoodinateSystem

    创建一个要素类是很简单的,只需要获取一枚IFeatureWorkspace或者一个IFeatureDataset,然后调用其CreateFeatureClass()即可. 这个CreateFeatur ...

  4. 自动化测试 Appium之Python运行环境搭建 Part2

    Appium之Python运行环境搭建 Part2 by:授客 QQ:1033553122 实践环境 参见 Appium之Python运行环境搭建 Part1 环境部署 1.安装Android SDK ...

  5. Docker-Docker-compose应用

    Docker-compose是用来定义和运行多容器应用的工具,它是独立于docker存在的,需要单独安装.实际应用场景中,我们的应用可能被打包运行在不同的容器里面,例如一个常规的web应用可能会涉及到 ...

  6. 【SpringBoot笔记】SpringBoot整合Druid数据连接池

    废话少说,按SpringBoot的老套路来. [step1]:添加依赖 <!-- 数据库连接池 --> <dependency> <groupId>com.alib ...

  7. THINKphp中复杂的查询

    字符串拼接查询 案例一:拼接字符串(多条件查询) $where = ''; //定义字符串,用于拼接满足条件的数据字段 $value = []; // 定义空数组,用于接收值 if(!empty($n ...

  8. 在后台业务管理系统中使用Autofac实现微信接口的处理

    在后台业务管理系统中使用Autofac实现微信接口的处理,我们只需要把相关使用到的DLL放到BIN目录里面即可,通过IOC控制反转方式实现对接口的调用.在实现在业务系统里面,我们本身程序可能已经依赖了 ...

  9. 【故障公告】推荐系统中转站撑爆服务器 TCP 连接引发的故障

    上周五下午,我们在博客中部署了推荐系统,在博文下方显示“最新IT新闻”的地方显示自动推荐的关联博文.我们用的推荐系统是第四范式的推荐服务,我们自己只是搭建了一个推荐系统中转站(基于 ASP.NET C ...

  10. 本地跑 spark ui 报错

    java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.isAsyncStarted()Z at org.spark_pr ...