2015-12-21 69 views
1

我正在研究代碼的問世,作爲練習TDD和學習PHPSpec的一種方式。我被困在第17天,這本質上是硬幣改變的難題。PHP:硬幣更換難題

精靈們再次買了太多的蛋酒 - 這次是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; 
     }); 
    } 
} 
+2

TDD中的一個原則是具有容易測試的一小段代碼。也許你應該把它分解成小塊來縮小問題所在。 – dan08

+0

這個工作適合你嗎? – Mike

回答

1

使用可用容器的數組索引作爲組合值。