###前提・実現したいこと
注)困っていることではありません。好奇心からの質問です。
下記のような課題があったとします。
1円、5円、10円、50円、100円、500円の各硬貨を3枚組み合わせて得られる金額をすべて列挙しなさい。
ただし、回答に使用できる組み合わせで5円、50円、500円の各硬貨は最大1枚までしか使用できません。
(JR新宿駅で「3CoinsShop」なる看板を見てふと思いついた問題です。)
期待される回答は下記のようになるはずですが。。。
金額 - 組合せ 3円 - 1円×3枚 7円 - 1円×2枚+ 5円×1枚 12円 - 1円×2枚+ 10円×1枚 16円 - 1円×1枚+ 5円×1枚+ 10円×1枚 21円 - 1円×1枚+ 10円×2枚 25円 - 5円×1枚+ 10円×2枚 30円 - 10円×3枚 52円 - 1円×2枚+ 50円×1枚 56円 - 1円×1枚+ 5円×1枚+ 50円×1枚 61円 - 1円×1枚+ 10円×1枚+ 50円×1枚 65円 - 5円×1枚+ 10円×1枚+ 50円×1枚 70円 - 10円×2枚+ 50円×1枚 102円 - 1円×2枚+100円×1枚 106円 - 1円×1枚+ 5円×1枚+100円×1枚 111円 - 1円×1枚+ 10円×1枚+100円×1枚 115円 - 5円×1枚+ 10円×1枚+100円×1枚 120円 - 10円×2枚+100円×1枚 151円 - 1円×1枚+ 50円×1枚+100円×1枚 155円 - 5円×1枚+ 50円×1枚+100円×1枚 160円 - 10円×1枚+ 50円×1枚+100円×1枚 201円 - 1円×1枚+100円×2枚 205円 - 5円×1枚+100円×2枚 210円 - 10円×1枚+100円×2枚 250円 - 50円×1枚+100円×2枚 300円 -100円×3枚 502円 - 1円×2枚+500円×1枚 506円 - 1円×1枚+ 5円×1枚+500円×1枚 511円 - 1円×1枚+ 10円×1枚+500円×1枚 515円 - 5円×1枚+ 10円×1枚+500円×1枚 520円 - 10円×2枚+500円×1枚 551円 - 1円×1枚+ 50円×1枚+500円×1枚 555円 - 5円×1枚+ 50円×1枚+500円×1枚 560円 - 10円×1枚+ 50円×1枚+500円×1枚 601円 - 1円×1枚+100円×1枚+500円×1枚 605円 - 5円×1枚+100円×1枚+500円×1枚 610円 - 10円×1枚+100円×1枚+500円×1枚 650円 - 50円×1枚+100円×1枚+500円×1枚 700円 -100円×2枚+500円×1枚
皆さんが得意としている言語で解くならどんなふうになりますか?
###回答例
javascriptで書いてみました。
javascript
1{ 2 let arr=[1,1,1,5,10,10,10,50,100,100,100,500]; 3 let keys=[]; 4 for(let i = 0; i < arr.length; i++) 5 for(let j = i+1; j < arr.length; j++) 6 for(let k = j+1; k < arr.length; k++){ 7 let val = arr[i]+arr[j]+arr[k]; 8 keys[val]=val; 9 }; 10 for(key in keys){ console.log(key); } 11}
回答お待ちしていますm(_ _)m
16/05/06.11:05追記:できれば回答例の表記からは乖離したものがいただけると嬉しいです。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答6件
0
ruby で書いてみました。
ruby
1require 'awesome_print' 2 3ans = [1,1,1,5,10,10,10,50,100,100,100,500].combination(3).group_by {|coins| coins.inject(:+)} 4 5ap ans.keys.sort 6ans.sort.each { |k, v| p "#{k}: #{v}" }
実行結果
[ [ 0] 3, [ 1] 7, [ 2] 12, [ 3] 16, [ 4] 21, [ 5] 25, [ 6] 30, [ 7] 52, [ 8] 56, [ 9] 61, [10] 65, [11] 70, [12] 102, [13] 106, [14] 111, [15] 115, [16] 120, [17] 151, [18] 155, [19] 160, [20] 201, [21] 205, [22] 210, [23] 250, [24] 300, [25] 502, [26] 506, [27] 511, [28] 515, [29] 520, [30] 551, [31] 555, [32] 560, [33] 601, [34] 605, [35] 610, [36] 650, [37] 700 ] "3: [[1, 1, 1]]" "7: [[1, 1, 5], [1, 1, 5], [1, 1, 5]]" "12: [[1, 1, 10], [1, 1, 10], [1, 1, 10], [1, 1, 10], [1, 1, 10], [1, 1, 10], [1, 1, 10], [1, 1, 10], [1, 1, 10]]" "16: [[1, 5, 10], [1, 5, 10], [1, 5, 10], [1, 5, 10], [1, 5, 10], [1, 5, 10], [1, 5, 10], [1, 5, 10], [1, 5, 10]]" "21: [[1, 10, 10], [1, 10, 10], [1, 10, 10], [1, 10, 10], [1, 10, 10], [1, 10, 10], [1, 10, 10], [1, 10, 10], [1, 10, 10]]" "25: [[5, 10, 10], [5, 10, 10], [5, 10, 10]]" "30: [[10, 10, 10]]" "52: [[1, 1, 50], [1, 1, 50], [1, 1, 50]]" "56: [[1, 5, 50], [1, 5, 50], [1, 5, 50]]" "61: [[1, 10, 50], [1, 10, 50], [1, 10, 50], [1, 10, 50], [1, 10, 50], [1, 10, 50], [1, 10, 50], [1, 10, 50], [1, 10, 50]]" "65: [[5, 10, 50], [5, 10, 50], [5, 10, 50]]" "70: [[10, 10, 50], [10, 10, 50], [10, 10, 50]]" "102: [[1, 1, 100], [1, 1, 100], [1, 1, 100], [1, 1, 100], [1, 1, 100], [1, 1, 100], [1, 1, 100], [1, 1, 100], [1, 1, 100]]" "106: [[1, 5, 100], [1, 5, 100], [1, 5, 100], [1, 5, 100], [1, 5, 100], [1, 5, 100], [1, 5, 100], [1, 5, 100], [1, 5, 100]]" "111: [[1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100], [1, 10, 100]]" "115: [[5, 10, 100], [5, 10, 100], [5, 10, 100], [5, 10, 100], [5, 10, 100], [5, 10, 100], [5, 10, 100], [5, 10, 100], [5, 10, 100]]" "120: [[10, 10, 100], [10, 10, 100], [10, 10, 100], [10, 10, 100], [10, 10, 100], [10, 10, 100], [10, 10, 100], [10, 10, 100], [10, 10, 100]]" "151: [[1, 50, 100], [1, 50, 100], [1, 50, 100], [1, 50, 100], [1, 50, 100], [1, 50, 100], [1, 50, 100], [1, 50, 100], [1, 50, 100]]" "155: [[5, 50, 100], [5, 50, 100], [5, 50, 100]]" "160: [[10, 50, 100], [10, 50, 100], [10, 50, 100], [10, 50, 100], [10, 50, 100], [10, 50, 100], [10, 50, 100], [10, 50, 100], [10, 50, 100]]" "201: [[1, 100, 100], [1, 100, 100], [1, 100, 100], [1, 100, 100], [1, 100, 100], [1, 100, 100], [1, 100, 100], [1, 100, 100], [1, 100, 100]]" "205: [[5, 100, 100], [5, 100, 100], [5, 100, 100]]" "210: [[10, 100, 100], [10, 100, 100], [10, 100, 100], [10, 100, 100], [10, 100, 100], [10, 100, 100], [10, 100, 100], [10, 100, 100], [10, 100, 100]]" "250: [[50, 100, 100], [50, 100, 100], [50, 100, 100]]" "300: [[100, 100, 100]]" "502: [[1, 1, 500], [1, 1, 500], [1, 1, 500]]" "506: [[1, 5, 500], [1, 5, 500], [1, 5, 500]]" "511: [[1, 10, 500], [1, 10, 500], [1, 10, 500], [1, 10, 500], [1, 10, 500], [1, 10, 500], [1, 10, 500], [1, 10, 500], [1, 10, 500]]" "515: [[5, 10, 500], [5, 10, 500], [5, 10, 500]]" "520: [[10, 10, 500], [10, 10, 500], [10, 10, 500]]" "551: [[1, 50, 500], [1, 50, 500], [1, 50, 500]]" "555: [[5, 50, 500]]" "560: [[10, 50, 500], [10, 50, 500], [10, 50, 500]]" "601: [[1, 100, 500], [1, 100, 500], [1, 100, 500], [1, 100, 500], [1, 100, 500], [1, 100, 500], [1, 100, 500], [1, 100, 500], [1, 100, 500]]" "605: [[5, 100, 500], [5, 100, 500], [5, 100, 500]]" "610: [[10, 100, 500], [10, 100, 500], [10, 100, 500], [10, 100, 500], [10, 100, 500], [10, 100, 500], [10, 100, 500], [10, 100, 500], [10, 100, 500]]" "650: [[50, 100, 500], [50, 100, 500], [50, 100, 500]]" "700: [[100, 100, 500], [100, 100, 500], [100, 100, 500]]"
投稿2016/05/06 14:55
総合スコア22324
0
バッチファイルで作ってみました。
dos
1@echo off 2setlocal ENABLEDELAYEDEXPANSION 3 4set arr=1 1 1 5 10 10 10 50 100 100 100 500 5call :prepare %arr% 6for /L %%I in (1,1,%length%) do ( 7 set /A j = %%I + 1 8 for /L %%J in (!j!,1,%length%) do ( 9 set /A k = %%J + 1 10 for /L %%K in (!k!,1,%length%) do ( 11 set /A val = arr[%%I] + arr[%%J] + arr[%%K] 12 set sval=00!val! 13 set sval=!sval:~-3! 14 set keys[!sval!]=!val! 15 ) 16 ) 17) 18for /F "tokens=2 delims==" %%A in ('set keys[') do echo %%A 19goto :eof 20 21:prepare 22set /A length=0 23:getlength_1 24if "%1" == "" goto :eof 25set /A length += 1 26set arr[%length%]=%1 27shift 28goto :getlength_1
投稿2016/05/06 14:17
編集2016/05/06 14:22総合スコア5938
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
ちょっとした工夫を思いついてしまったので、そのコードを書いてしまいます(Java8)。
java
1import java.util.ArrayList; 2import java.util.Arrays; 3import java.util.List; 4 5public class Q34167_2 { 6 public static void main(String[] args) { 7 int[] coins = {1, 5, 10, 50, 100, 500}; 8 9 // 一枚しか使えない硬貨 10 List<Integer> once = Arrays.asList(new Integer[]{5, 50, 500}); 11 List<Integer> total = new ArrayList<>(); 12 for (int i = 0; i < coins.length; i++) { 13 14 // 一枚しか使えない硬貨を前のステップで使っていた場合には次の硬貨から、そうでなければ同じ硬貨から選択 15 for(int j = once.contains(coins[i]) ? i + 1 : i; j < coins.length ; j++) { 16 for (int k = once.contains(coins[j]) ? j + 1 : j; k < coins.length; k++){ 17 total.add(coins[i] + coins[j] + coins[k]); 18 } 19 } 20 } 21 total.stream().sorted().forEach(System.out::println); 22 } 23 24} 25
更にこれをなんとかStreamで書けないか試してみた…が、余り綺麗に書けなかったです。
java
1import java.util.ArrayList; 2import java.util.Arrays; 3import java.util.List; 4import java.util.function.Function; 5import java.util.stream.IntStream; 6import java.util.stream.Stream; 7 8public class Q34167_2 { 9 public static void main(String[] args) { 10 int[] coins = {1, 5, 10, 50, 100, 500}; 11 12 // 一枚しか使えない硬貨 13 List<Integer> once = Arrays.asList(new Integer[]{5, 50, 500}); 14 15 // Stream内のListの最後の番号に応じ、次の番号を詰めたすべてのパターンのListのStreamを返す 16 Function<List<Integer>, Stream<List<Integer>>> f = 17 e -> { 18 int last = e.get(e.size() - 1); 19 if (once.contains(coins[last])){ 20 last++; 21 } 22 return IntStream.range(last, coins.length).mapToObj(i -> { 23 List<Integer> l = new ArrayList<>(e); 24 l.add(i); 25 return l; 26 }); 27 }; 28 29 IntStream.range(0, coins.length).mapToObj(i -> { 30 List<Integer> list = new ArrayList<>(); 31 list.add(i); 32 return list; 33 }).flatMap(f).flatMap(f) 34 .mapToInt(e -> e.stream().mapToInt(i -> coins[i]).sum()) 35 .sorted().forEach(System.out::println); 36 } 37 38} 39
旧回答
この手の問題では、制約の厳しいものから考えることが鉄則です。今回の場合、「5円、50円、500円は最大1枚しか使えない」という制約があるので、これから考えます。
ある硬貨の組み合わせで、5円、50円、500円はそれぞれ「使う」か「使わない」かの2つの選択肢があります。全部使っても3枚に収まるので、各硬貨の選択は他の硬貨を使うか使わないかに影響を受けません。そうすると、2^3=8通りの組み合わせが出てきます。その「枚数」と「金額」をセットにしておきます。
残りの1円、10円、100円については3枚まで使えるわけですが、こう考えます。
- それぞれ「使う」か「使わない」かで2つずつ選択肢
- 使う硬貨が0種なら0円。
1種類ならそれを1~3枚のうち何枚使うか。
2種類ならどっちを2枚使うか、あるいはどちらも1枚ずつか。
3種類なら1枚ずつで確定
そして、最初の5円、50円、500円硬貨の枚数-金額ペアと照らし合わせ、合計3枚になるように足し合わせればできます。
投稿2016/05/06 03:41
編集2016/05/07 17:32総合スコア20651
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/06 08:16 編集
2016/05/06 08:58
2016/05/06 09:59
2016/05/10 02:38
0
Scalaなら 1行で 書けます。
scala
1object Main extends App { 2 List(1,1,1,5,10,10,10,50,100,100,100,500).combinations(3).foreach(println) 3}
実行結果はこちら: http://scastie.org/16988
これはScalaが 順列、組み合わせ、冪集合 を生成する関数を標準で持っているからですね。
Scala Codebook 順列、組み合わせ、冪集合を生成する
投稿2016/05/06 02:20
総合スコア158
0
ライブラリありそうだなーと探してみました。
python
1from itertools import permutations 2 3arr = [1,1,1,5,10,10,10,50,100,100,100,500] 4keys = set() 5for x in permutations(arr, 3): 6 keys.add(sum(x)) 7for x in sorted(keys): 8 print x
python
1from itertools import permutations 2print sorted(set([sum(x) for x in permutations([1,1,1 ,5,10,10,10,50,100,100,100,500], 3)]))
実行結果はこちら: http://ideone.com/Vy52JY
検索中に、こんな記事を見つけました。わけがわからない。
全ての組み合わせを作る
投稿2016/05/06 02:11
編集2016/05/06 02:32総合スコア2493
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/06 02:28
2016/05/06 03:27
2016/05/06 03:36
0
こんにちは。
ちょっと頭休めにトライしてみました。
短いコードと言う意味では既に最適化できている印象ですし、アルゴリズムの解き方と言うよりは言語によってどのように書けるのかに興味をお持ちのように見えました。
C++は、そこそこ元ソースに忠実に書けます。C++11を使ってできるだけ元ソースに近づけてみました。
C++
1#include <type_traits> 2#include <set> 3#include <iostream> 4using namespace std; 5 6int main() 7{ 8 unsigned arr[]={1,1,1,5,10,10,10,50,100,100,100,500}; 9 set<unsigned> keys; 10 for (size_t i = 0; i < extent<decltype(arr)>::value; i++) 11 for (size_t j = i+1; j < extent<decltype(arr)>::value; j++) 12 for (size_t k = j+1; k < extent<decltype(arr)>::value; k++) { 13 unsigned val = arr[i]+arr[j]+arr[k]; 14 keys.emplace(val); 15 } 16 for (auto key : keys) cout << key << "\n"; 17 18 return 0; 19}
投稿2016/05/06 01:48
編集2016/05/06 01:51総合スコア23272
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/09 04:13