问题描述

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

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

编程实现

 <?php

 /**
* @author cenze
*
* 反FizzBuzz问题求最短序列
*
* $inverseFizzBuzz = new InverseFizzBuzz([
* 'fizz',
* 'fizz',
* 'buzz',
* ]);
* $inverseFizzBuzz->sequence():
* Array ( [0] => 6 [1] => 7 [2] => 8 [3] => 9 [4] => 10 )
*/
class InverseFizzBuzz
{
// FizzBuzz问题赋值
const FizzBuzz = [
'fizz' => 3,
'buzz' => 5,
'fizzbuzz' => 15
]; // 预定义问题区间
private $range = [
1,
100
]; // 待求序列
private $list = []; // 待求序列包含项数统计
private $listItemsCount = 0; public function __construct($list = [], $range = [])
{
$this->init($list, $range);
} /**
* 待求序列、区间初始化
*
* @param array $list
* 待求序列
* @param array $range
* 问题区间
* @param bool $check
* 是否检查属性已完成初始化
*
* @return void
*/
private function init($list = [], $range = [], $check = false)
{
if ($list) {
$this->list = $this->inverseList($list);
$this->listItemsCount = count($this->list);
if (! $this->listItemsCount) {
exit('Invalid list.');
}
} if ($range) {
$this->range = $range;
} if ($check) {
if (! $this->list) {
exit('Property list uninitialized.');
}
}
} /**
* 将待求解序列反转
*
* @param array $list
* 待求解序列
*
* @return mixed
*/
private function inverseList($list)
{
$inverseList = [];
foreach ($list as $item) {
if (! array_key_exists($item, self::FizzBuzz)) {
return null;
}
$inverseList[] = self::FizzBuzz[
$item
];
} return $inverseList;
} /**
* 搜索最短序列是否存在
*
* @param array $list
* 待求序列
* @param array $range
* 问题区间
*
*
* @return mixed
*/
public function sequence($list = [], $range = [])
{
$this->init($list, $range, true); $sequences = $this->findSequences();
if (! $sequences) {
return 'Found no sequences.';
} $sequence = $this->findShortestSequence($sequences);
// 将最短序列序列化后返回
return range($sequence[0], $sequence[$this->listItemsCount - 1]);
} /**
* 搜索最短序列(未序列化)
*
* @param array $sequences
* 序列集合,包含最短序列
*
* @return array
*/
private function findShortestSequence($sequences)
{
// 默认第一条为最短
$shortestSequence = $sequences[0];
// 把每一个序列看做一条路径,都有对应的长度。记录最短的序列长度
$shortestSequenceLength = $sequences[0][$this->listItemsCount - 1] - $sequences[0][0];
// 为array_reduce()定义一个callback,用来搜索最短序列
$findShortestSequence = function ($shortestSequence, $currentSequence) use(&$shortestSequenceLength) {
$currentSequenceLength = $currentSequence[$this->listItemsCount - 1] - $currentSequence[0];
if ($currentSequenceLength < $shortestSequenceLength) {
$shortestSequenceLength = $currentSequenceLength;
return $currentSequence;
} else {
return $shortestSequence;
}
}; return array_reduce($sequences, $findShortestSequence, $shortestSequence);
} /**
* 从指定位置开始搜索指定项目的序列
*
* @param int $item
* 指定项目
* @param int $start
* 起始搜索位置
*
* @return int
*/
private function findItemSequenceFromPosition($item, $start)
{
if ($start % $item == 0) {
return $start;
} return $start + ($item - $start % $item);
} /**
* 从指定位置开始搜索首个序列
*
* @param int $start
* 起始搜索位置
*
* @return mixed
*/
private function findSequenceFromPosition($start)
{
$listSequence = [];
for ($i = 0; $i < $this->listItemsCount; $i ++) {
$itemSequence = $this->findItemSequenceFromPosition($this->list[$i], $start);
if ($itemSequence > $this->range[1]) {
return null;
} else {
$listSequence[] = $itemSequence;
$start = $itemSequence + 1;
}
} return $listSequence;
} /**
* 找到多个序列,其中包括最短序列
*
* @return void
*/
private function findSequences()
{
$sequences = [];
// 以第一个项为初始搜索位置在预定区间中搜索,且以第一个项为递增步长向后逐步搜索
for ($start = $this->list[0]; $start <= $this->range[1]; $start += $this->list[0]) {
// 只需找到指定位置开始的第一个序列即可
if ($sequence = $this->findSequenceFromPosition($start)) {
$sequences[] = $sequence;
}
} return $sequences;
}
}

逆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. Java基础小知识笔记

    1. Integer转进制的一个类2. toBinaryString,toOctalString,toHexString.(转为二进制,八进制,十六进制的方法)3. 如果·数据的大小没有超过byte/ ...

  2. 升级WIN10 (9879)后IE无响应的解决办法

    身为程序猿,当然有了新系统就要尝尝鲜,有WIN8时,哥是朋友圈第一个用的,有WIN8.1时哥也是第一个升级的. 现在WIN10来了,当然也得赶紧尝尝鲜.直接下载了 9879版的预览版本安装. 要说WI ...

  3. Swiper4.x使用方法

    1.首先加载插件,需要用到的文件有swiper.min.js和swiper.min.css文件.可下载Swiper文件或使用CDN. <!DOCTYPE html> <html> ...

  4. 测者的测试技术手册:分清Java的Override和Overload

    Java的Override和OverloadOverride重写:子类对父类的允许访问的方法实现过程重新编写,但是 不可改变返回值和入参.重弄写的规则: 参数列表必须完全与被重写方法的相同: 返回类型 ...

  5. 猴子吃桃儿问题(C#)

    猴子第一天摘了许多个桃子,先吃了所有桃子的一半,后又吃了一个:第二天又吃了剩下桃子的一半,后又吃了一个……第十天,剩1个桃子.问:猴子第一天摘了多少个桃子? 本程序对其做了修改,天数和吃一半后又吃了一 ...

  6. 定义工作,解读自我——IT帮2019年2月线下活动回顾

    本次活动是在北京和深圳两个分站同步进行的,IT团建委员会负责策划和组织,北京站由帮主周老师.王兵老师主导,深圳站由副帮主兼深圳站长陈焕老师主导. 几位老师都是有着丰富的工作经历和人生体验的导师,他们不 ...

  7. 我的第一个python web开发框架(38)——管理员管理功能

    后台管理员的管理功能,它主要用来管理后台的登录账号,绑定权限,当然如果想将后台管理扩展成企业相关管理系统,比如用于公司人事管理,在这个基础上进行适当扩展就可以了. 我们先看看界面效果(也可以看着数据字 ...

  8. javaEmail发邮件是问号乱码,已解决

    寒假学习了ssm,就把之前看过的一个商城项目用ssm重构了. 然后在本地一切都正常,放到个人服务器上就凉了. 因为这个项目注册需要邮箱激活,然后就在发邮件的时候出了问题. 一.发送端口 因为源程序是用 ...

  9. Core官方DI解析(5)-ServiceProviderEngine

    最后来看看前面一直说的Engine(工作引擎),工作引擎接口是IServiceProviderEngine在ServiceProvider的构造函数中看到了根据指定的Mode创建了不同的实现类,下面先 ...

  10. 关于SSH的那些事

    SSH: Secure Shell Protocol  (安全外壳协议) Secure Shell,又可记为安全外壳协议(SSH) Secure Shell,又可记为安全外壳协议(SSH),最初是UN ...