<?php
function operateNums($firstNum, $operate, $secondNum)
{
switch ($operate) {
case '+':
$result = [
'num' => $firstNum['num'] + $secondNum['num'],
'numStr' => '(' . $firstNum['numStr'] . '+' . $secondNum['numStr'] . ')',
];
break;
case '-':
$result = [
'num' => $firstNum['num'] - $secondNum['num'],
'numStr' => '(' . $firstNum['numStr'] . '-' . $secondNum['numStr'] . ')',
];
break;
case '*':
$result = [
'num' => $firstNum['num'] * $secondNum['num'],
'numStr' => '(' . $firstNum['numStr'] . '*' . $secondNum['numStr'] . ')',
];
break;
case '/':
if ($secondNum['num'] == 0) {
$result = [];
} else {
$result = [
'num' => $firstNum['num'] / $secondNum['num'],
'numStr' => '(' . $firstNum['numStr'] . '/' . $secondNum['numStr'] . ')',
];
}
break;
default:
$result = [];
}
return $result;
}
function calc24($nums)
{
$count = count($nums);
//当只有一个数时,说明计算完成,可以判断结果了
if ($count == 1) {
if ($nums[0]['num'] == 24) {
global $allResults;
if(!isset($allResults[$nums[0]['numStr']])){
$allResults[$nums[0]['numStr']] = $nums[0]['numStr'];
}
}
return;
}
$ops = ['+', '-', '*', '/'];
//两重循环,从numbers中找两个数的组合
for ($i = 0; $i < $count; $i++) {
for ($j = 0; $j < $count; $j++) {
//排除相同的情况
if ($i == $j) {
continue;
}
//对四种运算进行枚举
foreach ($ops as $op) {
$newNum = operateNums($nums[$i], $op, $nums[$j]);
//运算可能失败,比如除数是0的情况,不再继续处理这个运算符,相当于剪枝效果
if ($newNum) {
//定义子问题
$subNums = [];
$subNums[] = $newNum;
//除了被选出来的两个数,将剩下的数加入子问题
for ($k = 0; $k < $count; $k++) {
if (($k != $i) && ($k != $j)) {
$subNums[] = $nums[$k];
}
}
//解决子问题
calc24($subNums);
}
}
}
}
}
$numbers = [
['num' => 11],
['num' => 12],
['num' => 13],
['num' => 14]
];
foreach($numbers as &$v){
$v['numStr'] = $v['num'];
}
$allResults = [];
calc24($numbers);
if($allResults){
foreach($allResults as $result){
echo $result.' = 24'.PHP_EOL;
}
}else{
$allNums = [];
foreach($numbers as $number){
$allNums[] = $number['num'];
}
echo implode(',', $allNums).'这四个数加减乘除无法合成24'.PHP_EOL;
}