# 八枚銀幣

## 解法

``````from '/lib/math' import sum

def compare(coins, i, j, k) {
if coins.get(i) > coins.get(k) {
println('The fake coin {0} is heavier.'.format(i + 1))
}
else {
println('The fake coin {0} is lighter.'.format(j + 1))
}
}

def coins(coins) {
c1 = sum(coins.slice(0, 3)) - sum(coins.slice(3, 6))
c2 = sum(coins.get(0), coins.get(3)) - sum(coins.get(1), coins.get(4))

if c1 == 0 {
compare67(coins)
}
else {
compare1To5(coins, c1, c2)
}
}

def compare67(coins) {
if coins.get(6) > coins.get(7) {
compare(coins, 6, 7, 0)
}
else {
compare(coins, 7, 6, 0)
}
}

def compare1To5(coins, c1, c2) {
if c1 > 0 {
c1GreaterThan0(coins, c2)
}
else {
c1NotGreaterThan0(coins, c2)
}
}

def c1GreaterThan0(coins, c2) {
if c2 == 0 {
compare(coins, 2, 5, 0)
}
else {
if c2 > 0 {
compare(coins, 0, 4, 1)
}
else {
compare(coins, 1, 3, 0)
}
}
}

def c1NotGreaterThan0(coins, c2) {
if c2 == 0 {
compare(coins, 5, 2, 0)
}
else {
if c2 > 0 {
compare(coins, 3, 1, 0)
}
else {
compare(coins, 4, 0, 1)
}
}
}

coins([5, 5, 5, 4, 5, 5, 5, 5])``````

``#include <stdio.h> #include <stdlib.h> #include <time.h> void compare(int[], int, int, int); void fake(int[]);  int main(void) {     srand(time(NULL));     int coins[8] = {0};     int i;    for(i = 0; i < 8; i++) {        coins[i] = 10;     }    printf("\n輸入假幣重量 ( 比10大或小 )：");         int input;    scanf("%d", &input);     coins[rand() % 8] = input;    fake(coins);     printf("\n\n列出所有錢幣重量：");     for(i = 0; i < 8; i++) {        printf("%d ", coins[i]);     }        return 0; } void compare(int coins[], int i, int j, int k) {     if(coins[i] > coins[k]) printf("\n假幣 %d 較重", i + 1);     else                    printf("\n假幣 %d 較輕", j + 1); } void fake(int coins[]) {     int c1 = coins[0] + coins[1] + coins[2] - coins[3] - coins[4] - coins[5];    int c2 = coins[0] + coins[3] - coins[1] - coins[4];        if(!c1) {        if(coins[6] > coins[7]) compare(coins, 6, 7, 0);        else                    compare(coins, 7, 6, 0);     }    else if(c1 > 0) {         if(!c2)                 compare(coins, 2, 5, 0);         else if(c2 > 0)         compare(coins, 0, 4, 1);         else                    compare(coins, 1, 3, 0);     }     else {         if(!c2)                 compare(coins, 5, 2, 0);         else if(c2 > 0)         compare(coins, 3, 1, 0);         else                    compare(coins, 4, 0, 1);     } }``

``interface Fake {    void doAction(int index, boolean isBigger);}public class Coins {    public static void compare(int[] coins, int i, int j, int k, Fake fake) {        if(coins[i] > coins[k]) fake.doAction(i + 1, true);        else                    fake.doAction(j + 1, false);    }        public static void compare(int[] coins, Fake fake) {        Integer h1 = coins[0] + coins[1] + coins[2];        Integer h2 = coins[3] + coins[4] + coins[5];        Integer h3 = coins[0] + coins[3];        Integer h4 = coins[1] + coins[4];                switch(h1.compareTo(h2)) {            case  0: if(coins[6] > coins[7])                                   compare(coins, 6, 7, 0, fake);                     else                                           compare(coins, 7, 6, 0, fake);                     break;            case  1: switch(h3.compareTo(h4)) {                         case  0: compare(coins, 2, 5, 0, fake); break;                         case  1: compare(coins, 0, 4, 1, fake); break;                         case -1: compare(coins, 1, 3, 0, fake);                      } break;            case -1: switch(h3.compareTo(h4)) {                         case  0: compare(coins, 5, 2, 0, fake); break;                         case  1: compare(coins, 3, 1, 0, fake); break;                         case -1: compare(coins, 4, 0, 1, fake);                      }        }    }    public static void main(String[] args) {        compare(new int[] {10, 10, 11, 10, 10, 10, 10, 10},          // JDK8 Lambda          (index, isBigger) -> {             System.out.printf("硬幣 %d 較%s", index, isBigger ? "大" : "小");          }        );    }}``

``def compare(coins, i, j, k):    return (i + 1, True) if coins[i] > coins[k] else (j + 1, False)    def coins(coins):    c1 = sum(coins[0:3]) - sum(coins[3:6])    c2 = sum([coins[0], coins[3]]) - sum([coins[1], coins[4]])    return (                           (compare(coins, 6, 7, 0)             if coins[6] > coins[7] else compare(coins, 7, 6, 0))         if c1 == 0 else (((             compare(coins, 2, 5, 0)             if c2 == 0 else             compare(coins, 0, 4, 1))             if c2 > 0 else              compare(coins, 1, 3, 0))         if c1 > 0 else (                compare(coins, 5, 2, 0)            if c2 == 0 else (           compare(coins, 3, 1, 0)            if c2 > 0 else              compare(coins, 4, 0, 1)))))    i, isBigger = coins([10, 10, 10, 10, 2, 10, 10, 10])print('硬幣', i, '重' if isBigger else '輕', end='')``

``def coins(coins: List[Int]) = {    def compare(coins: List[Int], i: Int, j: Int, k: Int) = {        if(coins(i) > coins(k)) (i + 1, true) else (j + 1, false)    }    val h1 = coins.slice(3, 6).sum    val h2 = coins.slice(3, 6).sum    val h3 = coins(0) + coins(3);    val h4 = coins(1) + coins(4);        h1.compareTo(h2) match {        case  0 => if(coins(6) > coins(7)) compare(coins, 6, 7, 0)                   else                    compare(coins, 7, 6, 0)        case  1 => h3.compareTo(h4) match {                       case  0 =>          compare(coins, 2, 5, 0)                       case  1 =>          compare(coins, 0, 4, 1)                       case -1 =>          compare(coins, 1, 3, 0)                   }        case -1 => h3.compareTo(h4) match {                       case  0 =>          compare(coins, 5, 2, 0)                       case  1 =>          compare(coins, 3, 1, 0)                       case -1 =>          compare(coins, 4, 0, 1)                   }    }}val (i, isBigger) = coins(List(10, 10, 11, 10, 10, 10, 10, 10))printf("硬幣 %d 較%s", i, if(isBigger) "重" else "輕")``

• Ruby
``# encoding: Big5def compare(coins, i, j, k)   if coins[i] > coins[k]       {index: i + 1, isBigger: true}    else        {index: j + 1, isBigger: false}    endenddef coins(coins)    h1 = coins.take(3).reduce(:+)    h2 = coins[3...6].reduce(:+)    h3 = coins[0] + coins[3]    h4 = coins[1] + coins[4]        case h1 <=> h2    when  0; if coins[6] > coins[7]                      compare(coins, 6, 7, 0)             else                      compare(coins, 7, 6, 0)              end    when  1; case h3 <=> h4             when  0; compare(coins, 2, 5, 0)             when  1; compare(coins, 0, 4, 1)             when -1; compare(coins, 1, 3, 0)             end    when -1; case h3 <=> h4             when  0; compare(coins, 5, 2, 0)             when  1; compare(coins, 3, 1, 0)             when -1; compare(coins, 4, 0, 1)             end    endendfake = coins [10, 10, 10, 10, 2, 10, 10, 10]printf("假幣 %d 較%s", fake[:index], if fake[:isBigger]; "重" else "輕" end)``

``var coins = function() {    function compare(coins, i, j, k) {        return coins[i] > coins[k] ? {index: i + 1, isBigger: true} :                                      {index: j + 1, isBigger: false};    }    return function(coins) {        var c1 = coins[0] + coins[1] + coins[2] -                  coins[3] - coins[4] - coins[5];        var c2 = coins[0] + coins[3] - coins[1] - coins[4];        return (c1 === 0 ? (coins[6] > coins[7] ? compare(coins, 6, 7, 0)  :                                                   compare(coins, 7, 6, 0)) :                (c1 > 0 ?                    (c2 === 0 ?                    compare(coins, 2, 5, 0)  :                    (c2 > 0 ?                      compare(coins, 0, 4, 1)  :                                                   compare(coins, 1, 3, 0))):                    (c2 === 0 ?                    compare(coins, 5, 2, 0)  :                    (c2 > 0 ?                      compare(coins, 3, 1, 0)  :                                                   compare(coins, 4, 0, 1))))               );    };}();var fake = coins([10, 10, 10, 2, 10, 10, 10, 10]);print('假幣 ' + fake.index + ' 較' + (fake.isBigger ? '重' : '輕'));``

``import Text.Printfcoins cs = case h1 `compare` h2 of               EQ -> if cs !! 6 > cs !! 7 then comp cs 6 7 0                                          else comp cs 7 6 0               GT -> case h3 `compare` h4 of                         EQ -> comp cs 2 5 0                         GT -> comp cs 0 4 1                         LT -> comp cs 1 3 0               LT -> case h3 `compare` h4 of                         EQ -> comp cs 5 2 0                         GT -> comp cs 3 1 0                         LT -> comp cs 4 0 1    where h1 = sum \\$ take 3 cs          h2 = sum \\$ take (5 - 3) \\$ drop 3 cs          h3 = cs !! 0 + cs !! 3          h4 = cs !! 1 + cs !! 4          comp cs i j k= if cs !! i > cs !! k then (i + 1, True)                                               else (j + 1, False)          main = printf "Coin %d is %s" index (if isHeavy then "heavy" else "light")    where (index, isHeavy) = coins [10, 10, 10, 10, 2, 10, 10, 10]``

``````round3(Coins, I, _, K, [I, heavier]) :-
nth1(I, Coins, CI), nth1(K, Coins, CK), CI > CK, !.
round3(_, _, J, _, [J, lighter]).

ordercases((>), (=), Coins, Fake) :- round3(Coins, 3, 6, 1, Fake), !.
ordercases((>), (>), Coins, Fake) :- round3(Coins, 1, 5, 2, Fake), !.
ordercases((>), (<), Coins, Fake) :- round3(Coins, 2, 4, 1, Fake), !.
ordercases((<), (=), Coins, Fake) :- round3(Coins, 6, 3, 1, Fake), !.
ordercases((<), (>), Coins, Fake) :- round3(Coins, 4, 2, 1, Fake), !.
ordercases((<), (<), Coins, Fake) :- round3(Coins, 5, 1, 2, Fake).

round2(Coins, (=), Fake) :-
nth1(7, Coins, C7), nth1(8, Coins, C8),
compare(Order, C7, C8), (
Order == (>) -> round3(Coins, 7, 8, 1, Fake);
round3(Coins, 7, 8, 1, Fake)
).

round2(Coins, H12Order, Fake) :-
[C1, C2, _, C4, C5, _, _, _] = Coins,
H3 is C1 + C4,
H4 is C2 + C5,
compare(H34Order, H3, H4),
ordercases(H12Order, H34Order, Coins, Fake).

which(Coins, Fake) :-
[C1, C2, C3, C4, C5, C6, _, _] = Coins,
H1 is C1 + C2 + C3,
H2 is C4 + C5 + C6,
compare(Order, H1, H2),
round2(Coins, Order, Fake).

main(_) :-
which([1, 1, 1, 2, 1, 1, 1, 1], Fake),
write(Fake), nl.``````