友人がオンラインのScalaコースをやっていて、これを共有しています。
# Write a recursive function that counts how many different ways you can make
# change for an amount, given a list of coin denominations. For example, there
# are 3 ways to give change for 4 if you have coins with denomiation 1 and 2:
# 1+1+1+1, 1+1+2, 2+2.
あなたが出席していてまだ解決策に取り組んでいるなら、これを読まないでください!
(免責事項:私のPythonソリューションが間違っている場合でも、コースに参加している場合は、何らかの方法であなたの思考に影響を与えたくありません!学習をもたらすのは思考だけではないでしょう。 「解決」...)
それはさておき...
Scalaチョップがないので、Pythonで試してみようと思いました(私自身はコースに参加していません。PythonとJavaの学習に興味があり、練習するための「ドリル」を歓迎します)。
これが私の解決策です。可能な限りコンパクトな表記法を使用してJavaに移植したいと思います。
def show_change(money, coins, total, combo):
if total == money:
print combo, '=', money
return 1
if total > money or len(coins) == 0:
return 0
c = coins[0]
return (show_change(money, coins, total + c, combo + [c]) +
show_change(money, coins[1:], total, combo))
def make_change(money, coins):
if money == 0 or len(coins) == 0:
return 0
return show_change(money, list(set(coins)), 0, [])
def main():
print make_change(4, [2, 1])
if __name__ == '__main__':
main()
質問
- 上記をJavaでどれだけコンパクトにして、JDKの外部のライブラリを使用できるようにすることができますか?
自分で移植してみましたが、非常に冗長になり、いつもの「もっと良い方法があるはず」と思いました!
ここに私の試み:
import java.util.ArrayList;
import java.util.List;
import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
public class MakeChange {
static int makeChange(int money, int[] coins) {
if (money == 0 || coins.length == 0) {
return 0;
}
return showChange(money, Ints.asList(coins), 0, new ArrayList<Integer>());
}
static int showChange(int money, List<Integer> coins, int total,
List<Integer> combo) {
if (total == money) {
System.out.printf("%s = %d%n", combo, total);
return 1;
}
if (total > money || coins.isEmpty()) {
return 0;
}
int c = coins.get(0);
List<Integer> comboWithC = Lists.newArrayList(combo);
comboWithC.add(c);
return (showChange(money, coins, total + c, comboWithC) + showChange(money,
coins.subList(1, coins.size()), total, combo));
}
public static void main(String[] args) {
System.out.println(makeChange(4, new int[] { 1, 2 }));
}
}
具体的には、私が非常に嫌いなのは、要素が追加されたリストのコピーを渡すためだけに、以下のことを実行する必要があることです。
List<Integer> comboWithC = Lists.newArrayList(combo);
comboWithC.add(c);
Javaがいかにコンパクトで読みやすいかを教えてください。私はまだ両方の言語の初心者です...