1

我正在将 Advent of Code 作为练习 TDD 和学习 PHPSpec 的一种方式。我被困在第 17 天,这本质上是硬币找零难题。

精灵们又买了太多的蛋酒——这次是 150 升。要将其全部装入冰箱,您需要将其移入较小的容器中。您清点可用容器的容量。

例如,假设您有大小为 20、15、10、5 和 5 升的容器。如果您需要储存 25 升,有四种方法可以做到:

  • 15 和 10
  • 20和5(前5)
  • 20和5(第二个5)
  • 15、5 和 5

完全装满所有容器,有多少种不同的容器组合可以完全装满 150 升蛋酒?

这是我的代码。我使用上面的示例编写了一个测试。该combinations方法应按4示例返回,但它返回 3。它似乎无法处理有多个 5 升容器的事实。

请问有什么建议吗?

<?php

namespace Day17;

class Calculator
{
    private $containers = [];

    public function combinations($total, array $containers)
    {
        $combinations = $this->iterate($total, $containers);
        return count($combinations);
    }

    /**
     * http://stackoverflow.com/questions/12837431/find-combinations-sum-of-elements-in-array-whose-sum-equal-to-a-given-number
     *
     * @param $array
     * @param array $combinations
     * @param array $temp
     * @return array
     */
    private function iterate($sum, $array, $combinations = [], $temp = [])
    {
        if (count($temp) && !in_array($temp, $combinations)) {
            $combinations[] = $temp;
        }

        $count = count($array);
        for ($i = 0; $i < $count; $i++) {

            $copy = $array;
            $elem = array_splice($copy, $i, 1);

            if (count($copy) > 0) {

                $add = array_merge($temp, array($elem[0]));
                sort($add);
                $combinations = $this->iterate($sum, $copy, $combinations, $add);

            } else {

                $add = array_merge($temp, array($elem[0]));
                sort($add);
                if (array_sum($combinations) == $sum) {
                    $combinations[] = $add;
                }
            }
        }

        return array_filter($combinations, function ($combination) use ($sum) {
            return array_sum($combination) == $sum;
        });
    }
}
4

1 回答 1

1

使用可用容器的数组索引作为组合值。

于 2015-12-21T23:36:26.193 回答