🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

706閲覧

整数解を列挙するアルゴリズムが知りたい

program_test

総合スコア3

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2021/01/09 10:15

編集2021/01/09 10:16

前提・実現したいこと

はじめまして。
現在、下記の条件を満たす整数a[i]の組を列挙するコードを書きたいと思っています。
∑(i = 1からNまで) a[i] = K (N, Kは、N >= 1, K >= 0 を満たす整数)

具体的には、例えば
X + Y + Z = 6
を満たすような整数X,Y,Zの組を求めるような感じです。
組の数を求めるのではなく、各組を列挙したいです。

Nがわかっていれば、N-1回for文を入れ子にして列挙できそうですが、
Nが分からない場合、どのように一般化して書いたらいいか教えてもらいたいです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2021/01/09 10:33

N が 1 の時 6 N が 2 の時 0 6, 1 5, 2 4, 3 3, 4 2, 5 1, 6 0 N が 3 の時 0 0 6, 0 1 5, 0 2 4, 0 3 3, 0 4 2, 0 5 1, 0 6 0, 1 0 5, 1 1 4, 1 2 3, 1 3 2, 1 4 1, 1 5 0, 2 0 4, 2 1 3, 2 2 2, 2 3 1, 2 4 0, 3 0 3, 3 1 2, 3 2 1, 3 3 0, 4 0 2, 4 1 1, 4 2 0, 5 0 1, 5 1 0, 6 0 0 再帰でできそうですね。
program_test

2021/01/09 13:18

コメントありがとうございます。 再帰でできるかと思って考えてはいたのですが、どうも漸化式が作れず。。 もう少し詳しく教えていただけますでしょうか。
Zuishin

2021/01/09 14:07

i が 0 の時、K の取りうる範囲は 0 から 6 までです。 i が 1 の時、K の取りうる範囲は 0 から 6 - a[0] までです。 i が 2 の時、K の取りうる範囲は 0 から 6 - a[0] - a[1] までです。 取りうる範囲をすべて列挙するのを N 回繰り返してください。 動作確認済みのサンプルコードを回答に書きますが、C# 9.0 なので提出はできません。
guest

回答1

0

ベストアンサー

C#

1#nullable enable 2 3using System; 4using System.Collections.Generic; 5using System.Linq; 6 7namespace ConsoleApp1 8{ 9 class Program 10 { 11 static Func<TArg, TResult> Memoize<TArg, TResult>(Func<Func<TArg, TResult>, TArg, TResult> func) 12 where TArg : notnull 13 { 14 var dic = new Dictionary<TArg, TResult>(); 15 16 TResult memoized(TArg arg) 17 { 18 if (!dic.TryGetValue(arg, out TResult result)) 19 { 20 result = func(memoized, arg); 21 dic[arg] = result; 22 } 23 return result; 24 } 25 26 return memoized; 27 } 28 29 static void Main() 30 { 31 var func = Memoize<(int, int), string[]>((memoized, args) => 32 { 33 (int n, int sum) = args; 34 35 return n switch 36 { 37 < 1 => throw new ArgumentOutOfRangeException(nameof(args)), 38 1 => new[] { sum.ToString() }, 39 _ => Enumerable 40 .Range(0, sum + 1) 41 .SelectMany(a => memoized((n - 1, sum - a)).Select(b => $"{a} {b}")) 42 .ToArray() 43 }; 44 }); 45 46 while (true) 47 { 48 Console.Write("N = "); 49 if (!int.TryParse(Console.ReadLine(), out int n)) break; 50 51 Console.Write("Sum = "); 52 if (!int.TryParse(Console.ReadLine(), out int sum)) break; 53 54 foreach (var item in func((n, sum))) 55 { 56 Console.WriteLine(item); 57 } 58 } 59 } 60 } 61}

csproj

1<Project Sdk="Microsoft.NET.Sdk"> 2 3 <PropertyGroup> 4 <OutputType>Exe</OutputType> 5 <TargetFramework>net5.0</TargetFramework> 6 </PropertyGroup> 7 8</Project>

投稿2021/01/09 14:08

Zuishin

総合スコア28669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

program_test

2021/01/09 15:51

コードまで書いていただきありがとうございます。 まだまだ自分の知らない記法があり、勉強しながら理解しようと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問