逆FizzBuzz问题求最短序列
问题描述
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问题求最短序列的更多相关文章
- hdu 1394 zoj 1484 求旋转序列的逆序数(并归排序)
题意:给出一序列,你可以循环移动它(就是把后面的一段移动到前面),问可以移动的并产生的最小逆序数. 求逆序可以用并归排序,复杂度为O(nlogn),但是如果每移动一次就求一次的话肯定会超时,网上题解都 ...
- hdu 1394 Minimum Inversion Number (裸树状数组 求逆序数 && 归并排序求逆序数)
题目链接 题意: 给一个n个数的序列a1, a2, ..., an ,这些数的范围是0-n-1, 可以把前面m个数移动到后面去,形成新序列:a1, a2, ..., an-1, an (where m ...
- 动态规划求一个序列的最长回文子序列(Longest Palindromic Substring )
1.问题描述 给定一个字符串(序列),求该序列的最长的回文子序列. 2.分析 需要理解的几个概念: ---回文 ---子序列 ---子串 http://www.cnblogs.com/LCCRNblo ...
- [zz]求一维序列的信息熵(香浓熵)的matlab程序实例
对于一个二维信号,比如灰度图像,灰度值的范围是0-255,因此只要根据像素灰度值(0-255)出现的概率,就可以计算出信息熵. 但是,对于一个一维信号,比如说心电信号,数据值的范围并不是确定的, ...
- poj 2001:Shortest Prefixes(字典树,经典题,求最短唯一前缀)
Shortest Prefixes Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12731 Accepted: 544 ...
- 39. 求分数序列前N项和
求分数序列前N项和 #include <stdio.h> int main() { int i, n; double numerator, denominator, item, sum, ...
- 20. 求阶乘序列前N项和
求阶乘序列前N项和 #include <stdio.h> double fact(int n); int main() { int i, n; double item, sum; whil ...
- 19. 求平方根序列前N项和
求平方根序列前N项和 #include <stdio.h> #include <math.h> int main() { int i, n; double item, sum; ...
- OpenJudge计算概论-求分数序列和
/*======================================================================== 求分数序列和 总时间限制: 1000ms 内存限制 ...
随机推荐
- Deepin MongoDB安装&使用总结
参考:手把手教你 MongoDB 的安装与详细使用(一) deepin 安装 mongodb 数据库(全面) 1. 导入公钥 sudo apt-key adv --keyserver hkp://ke ...
- 程序员50题(JS版本)(九)
程序41:八进制转换为十进制 var num1=425; var num2=0; num1=num1.toString(); for(var i=num1.length-1,root=1;i>= ...
- CSS3 弹性盒子
理解: CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式. 设置弹性盒子: 弹性盒子由弹性容器(Fl ...
- Hacking HackDay: Albania
概述: Name: HackDay: Albania Date release: 18 Nov 2016 Author: R-73eN Series: HackDay 下载: https://down ...
- NET4.6下的UTC时间转换
int UTCSecond = (int)((DateTimeOffset)DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local)).ToUnix ...
- 什么是Docker,它可干什么?
定义我们知道,软件依赖的环境大致包括: 1• 配置文件2• 代码3• tomcat4• JDK5• 操作系统 Docker作为一个软件集装箱化平台,可以让开发者构建应用程序时,将它与其依赖环境一起打包 ...
- 城市经纬度 json
[ { "name": "北京市", "log": "116.46", "lat": "3 ...
- SQL Server(1)数据库基础
一.数据库能够做什么 1.存储大量的数据. 2.保持数据信息的一致.完整. 3.共享和安全. 4.通过组合分析,产生新的有用信息. 二.数据库的基本概念 1.数据库就是“数据”的“仓库”. 2.数据库 ...
- 'Attempt to create two animations for cell' iOS
我是在对一个UITableView 一起进行 reloadRows和reloadSections 的操作的时候 出现的
- File operations 1
1:只读(‘r' 和 ’rb'以字节读) f = open('d:\模特主妇护士班主任.txt',mode='r',encoding='UTF-8') content = f.read() print ...