回答編集履歴

2

テキスト修正

2020/06/10 12:45

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -77,3 +77,53 @@
77
77
 
78
78
 
79
79
  となっていることが確認できます。
80
+
81
+
82
+
83
+ ### 追記2
84
+
85
+
86
+
87
+ ライブラリを使わないコードを追記しておきます。考え方としては、以下です。
88
+
89
+
90
+
91
+ - `[500, 100, 100, 50, 10, 5]` を集合(`M`とします)と考えます。この場合、インデクス1 と 2の要素は同じ `100` ですが、これらは別物と考えます。以下では便宜上 100___1__, 100___2__ と書きます。
92
+
93
+
94
+
95
+ - 集合論一般として、集合`M` の部分集合を集めた、[べき集合](https://ja.wikipedia.org/wiki/%E5%86%AA%E9%9B%86%E5%90%88) `Power(M)`を作ることができます。
96
+
97
+ - この`Power(M)`は、要素として、`{5}`, `{500, 100_1, 100_2, 10}`, `{500, 100_1, 100_2, 50, 10, 5}`などの、すべての組み合わせを含みます。
98
+
99
+
100
+
101
+ ご質問の要件を解決するコードは、配列 `money`を集合とみた場合のべき集合に相当する配列を作り、べき集合に含まれる要素の配列の中で、長さが2以上のものだけを抽出して、各々について合計を出せばよいです。
102
+
103
+
104
+
105
+ そこで、べき集合を作るコードを作成しました。
106
+
107
+
108
+
109
+ - [要素の数が n の集合のべき集合(に相当する配列)を得る](https://qiita.com/jun68ykt/items/07f8d59340eaf5152a8f)
110
+
111
+
112
+
113
+ 上記で作成した関数 `powerSet` を使うと、`[500, 100, 100, 50, 10, 5]`から2つ以上を選び、それらの合計値として作り出せる数を小さい順に並べた配列 `totals` は、以下によって得られます。
114
+
115
+
116
+
117
+
118
+
119
+ ```javascript
120
+
121
+ const money = [500, 100, 100, 50, 10, 5];
122
+
123
+ const choices = powerSet(money.length).filter(ary => ary.length >= 2).map(a => a.map(i => money[i]));
124
+
125
+ const totals = [...new Set(choices.map(ary => ary.reduce((s,v) => s + v)))].sort((v1, v2) => v1 - v2);
126
+
127
+ ```
128
+
129
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/jOWWaqe?editors=0012](https://codepen.io/jun68ykt/pen/jOWWaqe?editors=0012)

1

テキスト修正

2020/06/10 12:45

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -37,3 +37,43 @@
37
37
 
38
38
 
39
39
  意図通り、直積の要素の個数は、`money.length ** n` となっていることが確認できます。以上参考になれば幸いです。
40
+
41
+
42
+
43
+ ### 追記
44
+
45
+
46
+
47
+ コメントを拝読しまして、要件としては、直積ではなく組み合わせを求めることと把握しました。組み合わせを求めるロジックをご自身で書いても、もちろんよいのですが、[lodash.combinations](https://github.com/SeregPie/lodash.combinations#readme) を使うこともできます。
48
+
49
+
50
+
51
+ これを使うと、たとえば以下
52
+
53
+ ```javascript
54
+
55
+ _.combinations(money, 3)
56
+
57
+ ```
58
+
59
+ によって、`money` の要素から3個選んだ組み合わせの配列が得られます。ですので、コメントから頂いた要件を満たすには、組み合わせに含まれる要素の数を `2` から `money.length` まで変えて、それぞれで得られる配列を連結すればよいかと思います。
60
+
61
+
62
+
63
+ 以下は、上記の考えによるサンプルです。
64
+
65
+
66
+
67
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/pogjgJb?editors=0012](https://codepen.io/jun68ykt/pen/pogjgJb?editors=0012)
68
+
69
+
70
+
71
+ 上記のサンプルでは、各組み合わせでの要素の合計も表示しています。また、組み合わせの数としては
72
+
73
+
74
+
75
+ 6**C**2 + 6**C**3 + 6**C**4 + 6**C**5 + 6**C**6 = 15 + 20 + 15 + 6 + 1 = 57
76
+
77
+
78
+
79
+ となっていることが確認できます。