teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

テキスト修正

2020/06/10 12:45

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -37,4 +37,29 @@
37
37
 
38
38
  6**C**2 + 6**C**3 + 6**C**4 + 6**C**5 + 6**C**6 = 15 + 20 + 15 + 6 + 1 = 57
39
39
 
40
- となっていることが確認できます。
40
+ となっていることが確認できます。
41
+
42
+ ### 追記2
43
+
44
+ ライブラリを使わないコードを追記しておきます。考え方としては、以下です。
45
+
46
+ - `[500, 100, 100, 50, 10, 5]` を集合(`M`とします)と考えます。この場合、インデクス1 と 2の要素は同じ `100` ですが、これらは別物と考えます。以下では便宜上 100___1__, 100___2__ と書きます。
47
+
48
+ - 集合論一般として、集合`M` の部分集合を集めた、[べき集合](https://ja.wikipedia.org/wiki/%E5%86%AA%E9%9B%86%E5%90%88) `Power(M)`を作ることができます。
49
+ - この`Power(M)`は、要素として、`{5}`, `{500, 100_1, 100_2, 10}`, `{500, 100_1, 100_2, 50, 10, 5}`などの、すべての組み合わせを含みます。
50
+
51
+ ご質問の要件を解決するコードは、配列 `money`を集合とみた場合のべき集合に相当する配列を作り、べき集合に含まれる要素の配列の中で、長さが2以上のものだけを抽出して、各々について合計を出せばよいです。
52
+
53
+ そこで、べき集合を作るコードを作成しました。
54
+
55
+ - [要素の数が n の集合のべき集合(に相当する配列)を得る](https://qiita.com/jun68ykt/items/07f8d59340eaf5152a8f)
56
+
57
+ 上記で作成した関数 `powerSet` を使うと、`[500, 100, 100, 50, 10, 5]`から2つ以上を選び、それらの合計値として作り出せる数を小さい順に並べた配列 `totals` は、以下によって得られます。
58
+
59
+
60
+ ```javascript
61
+ const money = [500, 100, 100, 50, 10, 5];
62
+ const choices = powerSet(money.length).filter(ary => ary.length >= 2).map(a => a.map(i => money[i]));
63
+ const totals = [...new Set(choices.map(ary => ary.reduce((s,v) => s + v)))].sort((v1, v2) => v1 - v2);
64
+ ```
65
+ - **動作確認用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

answer CHANGED
@@ -17,4 +17,24 @@
17
17
 
18
18
  - [n=4 のサンプル](https://codepen.io/jun68ykt/pen/yLeYYOm?editors=0012)
19
19
 
20
- 意図通り、直積の要素の個数は、`money.length ** n` となっていることが確認できます。以上参考になれば幸いです。
20
+ 意図通り、直積の要素の個数は、`money.length ** n` となっていることが確認できます。以上参考になれば幸いです。
21
+
22
+ ### 追記
23
+
24
+ コメントを拝読しまして、要件としては、直積ではなく組み合わせを求めることと把握しました。組み合わせを求めるロジックをご自身で書いても、もちろんよいのですが、[lodash.combinations](https://github.com/SeregPie/lodash.combinations#readme) を使うこともできます。
25
+
26
+ これを使うと、たとえば以下
27
+ ```javascript
28
+ _.combinations(money, 3)
29
+ ```
30
+ によって、`money` の要素から3個選んだ組み合わせの配列が得られます。ですので、コメントから頂いた要件を満たすには、組み合わせに含まれる要素の数を `2` から `money.length` まで変えて、それぞれで得られる配列を連結すればよいかと思います。
31
+
32
+ 以下は、上記の考えによるサンプルです。
33
+
34
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/pogjgJb?editors=0012](https://codepen.io/jun68ykt/pen/pogjgJb?editors=0012)
35
+
36
+ 上記のサンプルでは、各組み合わせでの要素の合計も表示しています。また、組み合わせの数としては
37
+
38
+ 6**C**2 + 6**C**3 + 6**C**4 + 6**C**5 + 6**C**6 = 15 + 20 + 15 + 6 + 1 = 57
39
+
40
+ となっていることが確認できます。