作为提高我作为PHP开发人员的技能的一种方法,我经常挑战自己来自网站Programming Praxis的问题。 99%的时间我自己可以解决谜语,但是我对这个问题很困惑,需要一些关于如何开始的指导。这个谜语被称为“多重住宅”。这是问题所在:
Baker,Cooper,Fletcher,Miller和Smith住在一栋只有五层楼的公寓楼的不同楼层。贝克不住在顶楼。库珀不住在底层。弗莱彻不住在顶层或底层。米勒生活在比库珀更高的楼层。史密斯不住在弗莱彻附近的地板上。弗莱彻并不住在库珀附近的地板上。每个人住在哪里?
我的基本麻烦是:我不明白如何测试和评估不同的逻辑情况。例如,如果我们想测试Baker是否属于一楼,那么如何最好地“填写”其余四个人中每个人的测试位置?我(很多)的尝试都以大量的If / else if / else树的底部沮丧而告终。
这不是作业,金钱或名气 - 只是一个谜,我可以使用一点帮助开始!
已更新 - 这是我的解决方案!感谢大家的所有输入,不一定优化但至少现在我明白了:
<?php
function testThisOne ($testList) {
$MillerFloor = "";
$CooperFloor = "";
$SmithFloor = "";
$FletcherFloor = "";
foreach ($testList as $key => $person) if ($person == "Miller") $MillerFloor = $key;
foreach ($testList as $key => $person) if ($person == "Cooper") $CooperFloor = $key;
foreach ($testList as $key =>$person) if ($person == "Smith") $SmithFloor = $key;
foreach ($testList as $key => $person) if ($person == "Fletcher") $FletcherFloor = $key;
if ($testList[4] == "Baker") return false;
if ($testList[0] == "Cooper") return false;
if ($testList[0] == "Fletcher" || $testList[4] == "Fletcher") return false;
if ($MillerFloor < $CooperFloor) return false;
if (abs($SmithFloor - $FletcherFloor) == 1 || abs($CooperFloor - $FletcherFloor) == 1) return false;
return true;
}
function puzzleSolve1() {
$people = array("Baker","Cooper","Fletcher","Miller","Smith");
do {
shuffle($people);
} while (!testThisOne($people));
return $people;
}
?>
答案 0 :(得分:4)
有趣的问题。由于这是一项编程挑战,我认为最好的方法是生成所有可能的人员安排,并测试他们是否正确。
由于你只是想要一个起点,我不会写任何实际的代码,我只是概述我解决它的方法:
{1, 2, 3, 4, 5}
这样的集合,每个元素代表一个人的楼层数,比如按Baker,Cooper,Fletcher,Miller,Smith的顺序排列。你需要找到所有其他可能的安排。 The algorithm on wikipedia非常简单,易于实施。对于您生成的每个排列,您需要测试所有条件是否都为真。如果任何条件为假,请停止测试并继续下一个排列。如果满足所有条件,那么你就完成了。所有条件都相当容易测试,例如:
“贝克不住在顶楼。” &GT;&GT; $baker != 5
“米勒生活在比库珀更高的地板上。” &GT;&GT; $miller > $cooper
等等。
答案 1 :(得分:1)
我猜你可以把它格式化为一组线性(in)方程式。
B < 5
C > 1
F < 5
F > 1
M > C
|S - F| > 1
|F - C| > 1
这些加号:B!= C!= F!= S!= M
现在将其提供给simplex algorithm,您就完成了:)
编辑:但是如果你想以编程方式解决这个问题,我想测试这些条件的所有排列都会简单得多 - 只有5个!他们。
答案 2 :(得分:1)
所以我们打电话给B C F M S。
基本上每个人都可以住在任何地方,所以我们有这个起点:
[BCFMS] [BCFMS] [BCFMS] [BCFMS] [BCFMS]
现在你说
Baker不住在顶层。
所以我们有
[BCFMS] [BCFMS] [BCFMS] [BCFMS] [CFMS]
库珀不住在底层。
所以我们最终得到:
[BFMS] [BCFMS] [BCFMS] [BCFMS] [CFMS]
弗莱彻不住在顶层或底层。
Ookay:
[BMS] [BCFMS] [BCFMS] [BCFMS] [CMS]
米勒住在比库珀更高的楼层上。
好的,所以M不能低于C:
[BS] [BCFS] [BCFMS] [BCFMS] [CMS]
而且,C不能在最后一层,因为M必须在他之上:
[BS] [BCFS] [BCFMS] [BCFMS] [MS]
(A):史密斯不住在弗莱彻附近的楼层。
(B):弗莱彻不住在库珀附近的楼层。
所以在相邻的“盒子”(地板)上没有S-F,F-S,F-C或C-F。
我们也知道
(C):住在公寓的不同楼层
符合(C),我们有两种可能的情况,第一层是B或S's
让我们来看第二种情况(因为我们知道(A)关于他)
[S] [BCFS] [BCFMS] [BCFMS] [MS]
根据(A):
[S] [BC] [BCF] [BCF] [M]
所以我们也知道M生活在C之上(前一步已经是真的,因为我们知道M肯定是在最后一层):
[S] [BC] [BCF] [BCF] [M]
根据(B),F和C都不能在3楼,并且在(C)的影响下,由于进一步减少(每层只有一个人),我们最终得到唯一可能的排列:< / p>
[S] [C] [B] [F] [M]
所以这是解决方案:
Smith,Cooper,Baker,Fletcher,Miller