2011-11-10 16 views
1

5只猴子分享桃,他們不能平等分配。所以第一隻猴子傾倒一隻桃子,桃子總數可以被五分之一,第一隻猴子佔據他的一部分。調整我的代碼來解決一個難題

然後是第二隻猴子,-1桃,可以被5除以他的部分。直到第五隻猴子完成所有步驟。可能還有一些桃子還剩下。

給出符合此條件的桃子的最小數量。

Perl代碼1:

#!/usr/bin/perl -w 
for $n (0..10000){  #this is basic idea but code is too messy ! 
    if(($n-1) % 5 == 0){ 
    $remain = 4/5 * ($n -1); 
     if(($remain - 1) % 5 == 0){ 
      $remain = 4/5 * ($remain -1); 
      if(($remain - 1) % 5 == 0){ 
       $remain = 4/5 * ($remain -1); 
       if(($remain - 1) % 5 == 0){ 
        $remain = 4/5 * ($remain -1); 
        if(($remain - 1) % 5 == 0){ 
         $remain = 4/5 * ($remain -1); 
         print "remain: $remain original: $n\n"; 
        } 
       } 
      } 
      } 
    } 
} 

Perl代碼2:

sub doit($){ 
    ($n) = @_; 
    if(($n - 1) % 5 ==0){ #if can be distributed by 5 monkey 
     $n = ($n - 1) * 4/5; #commit distribute 
     return $n; 
    }else{ 
     return -1; #fail 
    } 
} 

for $n (0..10000){ #restriction 
    $r = $n; #"recursively" find solution 
    $o = $n; #backup n 
    $count = 0; 
    for ($i = 0; $i < 5; $i++){ #assume there is 5 monkey, it can be changed 
     $r = doit($r); 
    if($r == -1){ #skip once fail 
     last; 
    } 
    $count++; 
    } 
    if($count == 5){ # if pass 5 test, then you found the number ! 
     print "now ".$r."\n"; 
     print "origin ".$o."\n"; 
    } 
} 

我想削減一些代碼。但感覺很難。誰能幫忙?

+1

首先你沒有使用嚴格和警告! –

+3

這個問題不值得downvotes。與所有展示我的代碼帖子相比,CodeFarmer已經給了它兩次很好的嘗試。它可以在頂部使用更好的描述。 –

+0

是的,我投了票,因爲一些非常可怕的全球使用,但後來改變了我的想法,因爲它實際上是一個很好的問題。問題是它不會讓我失望! –

回答

1

首先開始,你真的應該在你的腳本的頂部使用strictwarnings編譯指示。您的$n用法尤其令人擔憂。將來,如果您使用my聲明變量,但使用相同的名稱,則表示它們將代表相同數量的事實,而不會擔心它們可能發生碰撞。

反正這裏是一個稍微進行研磨,更重要的是strictwarnings安全版本:

#!/usr/bin/env perl 

use strict; 
use warnings; 

sub doit { 
    my ($n) = @_; 
    if(($n - 1) % 5 ==0){ #if can be distributed by 5 monkey 
     $n = ($n - 1) * 4/5; #commit distribute 
     return $n; 
    } else { 
     return undef; #fail 
    } 
} 

OUTER: for my $n (0..10000){ #restriction 
    my $r = $n; #"recursively" find solution 
    for (1..5){ #assume there is 5 monkey, it can be changed 
     $r = doit($r); 
     next OUTER unless defined $r; 
    } 
    # if code gets here, then it passed 5 test, then you found the number ! 
    print "now: $r\torigin: $n\n"; 
} 

而現在,如果你真的想成爲它的樂趣(不生產,可讀性使用第一!):

#!/usr/bin/env perl 

use strict; 
use warnings; 

OUTER: for my $n (0..10000){ 
    my $r = $n; 
    $r = ($r - 1) % 5 ? next OUTER : 4/5 * ($r - 1) for (1..5); 
    print "now: $r\torigin: $n\n"; 
} 

甚至golfed:

for(0..10000){$r=$n=$_;map$r*=--$r%5?next:4/5,1..5;print"now: $r\torigin: $n\n"} 
+0

哇,這是一個偉大的建議 – CodeFarmer

0

我不是100%確定我理解你的問題,而是從最後一隻猴子開始尋找答案。他可以拿到的最小桃子數是1,儘管可能有一些剩下的,但爲了得到最小值,假設剩下0個。現在,計算倒數第二隻猴子看到的桃子數量,等等。

沒有必要循環,如果從過去的猴子

# set numPeaches to what the last monkey had 
$numPeaches = 1; 

# then, figure out how many the second to last monkey had, and add to numPeaches 

# and, so on ... 

# until you get to the first monkey 
+0

是的,我知道,我只是想嘗試編碼來解決問題。桃子的最新剩餘數量可以是任何大於0的數字,在這種情況下,最小數字是3121,在第五次拿走他的部分後,它仍然是數千 – CodeFarmer

1

考慮這個解決方案:

sub share { 
    ($_[0] - 1) % 5 == 0 ? ($_[0]-1)/5*4 : die "unable to share"; 
} 

for my $i (1..10000) { 
    eval { 
    share(share(share(share(share($i))))); 
    }; 
    unless ([email protected]) { 
    print "solution: $i\n"; 
    last; 
    } 
} 

我確定有一個monad潛伏在裏面。

+0

是的,它變得更加清晰 – CodeFarmer