Help us understand the problem. What is going on with this article?

C#で数学パズル - 小町数で3つの式の値を等しくする

More than 1 year has passed since last update.

小町数を使った数学パズルの第3弾です。

問題

「○○ − ○ = ○○ / ○ = ○ + ○ × ○ 」の○の部分に、1から9までの数がひとつずつ入るようにせよ。
真ん中の式は、割り切れる数にすること。

どうやて解くか

いわゆる小町数パズルのひとつです。

意外と難しいです。紙と鉛筆で解こうと試行錯誤してみましたが、僕は答えがわかりませんでした。

この問題を解くには、基本的には、総当たりで調べてゆくプログラムを書けば良いですね。
それには、1から9までの数のすべての順列を求めて、その順列に対し、式が成り立つかを調べれば答えを求めることができます。
例えば、求めた順列が、3,5,6,9,8,2,1,4,7 ならば、35 - 6 = 98 / 2 = 1 + 4 * 7 という式が成り立つかを調べればいいですね。

つまり、順列を求めるプログラムが書ければ、それを少し変形することで、この問題を解くプログラムを書くことができます。

ということで、「C#:全ての要素を使った順列を求める」に掲載した順列を求めるクラスPermutationを利用して、問題を解こうと思います。

求めた順列の一つ一つに対して、「○○ー○ = ○○ / ○ = ○ + ○ × ○ 」に当てはめて、式が成り立つかを調べます。

C#:全ての要素を使った順列を求める」で掲載しているコードをブラックボックスとして捉えれば、それほど難しいことをやっているわけではありません。
IskomachiExpなんて、力技のコードなので、もうすこしスッキリ書きたいなとは思ったのですが...

C#のコード

順列を求めるPermutationクラスのコードも、最後に載せておきます。

public class Solver {
    public IEnumerable<int[]> Solve() {
        var nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        return _Solve<int>(nums);
    }

    private IEnumerable<int[]> _Solve<T>(IEnumerable<int> nums) {
        var perm = new Permutation();
        foreach (var n in perm.Enumerate(nums)) {
            var array = n.ToArray();
            if (IskomachiExp(array))                    
                yield return array;
        }
    }

    // 「○○ー○ = ○○ / ○ = ○ + ○ × ○ 」が成り立つかを調べる
    // nums.Length は9であることが保証されている
    private bool IskomachiExp(int[] nums) {
        var a = nums[0] * 10 + nums[1];
        var b = nums[2];
        var x = a - b;
        var c = nums[3] * 10 + nums[4];
        var d = nums[5];
        var y = c / d;
        if (x != y)
            return false;
        if (y * d != c) // yは切り捨てされるので、ここで、再度チェック
            return false;
        var e = nums[6];
        var f = nums[7];
        var g = nums[8];
        if (x != e + f * g)
            return false;
        return true;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var sol = new Solver();
        foreach (var nums in sol.Solve()) {
            string s = $"答えは、{nums[0]}{nums[1]}-{nums[2]} = " +
                $"{nums[3]}{nums[4]}/{nums[5]} = {nums[6]}+{nums[7]}*{nums[8]} です。";
            Console.WriteLine(s);
        }
    }
}

以下に示すのは、C#:全ての要素を使った順列を求めるに掲載した順列を求めるPermutationクラス

public class Permutation {
    public IEnumerable<T[]> Enumerate<T>(IEnumerable<T> items) {
        return _GetPermutations<T>(new List<T>(), items.ToList());
    }

    private IEnumerable<T[]> _GetPermutations<T>(IEnumerable<T> perm, IEnumerable<T> items) {
        if (items.Count() == 0) {
            yield return perm.ToArray();
        } else {
            foreach (var item in items) {
                var result = _GetPermutations<T>(perm.Concat(new T[] { item }),
                                                    items.Where(x => x.Equals(item) == false)
                                );
                foreach (var xs in result)
                    yield return xs.ToArray();
            }
        }
    }

    internal int[] ToArray() {
        throw new NotImplementedException();
    }
}

結果

答えは、37-8 = 29/1 = 5+4*6 です。
答えは、37-8 = 29/1 = 5+6*4 です。

2つの答えが出ましたが、最後の2つの数が入れ替わっただけなので、実質的に答えはひとつということになりますね。


この記事は、Gushwell's C# Programming Pageで公開したものをに加筆・修正したものです。

gushwell
株式会社ジード / Microsoft MVP for Developer Technologies 2005-2019 / 著書『実戦で役立つ C#プログラミングのイディオム/定石&パターン』『新・標準プログラマーズライブラリ なるほどなっとく C#入門』『C#プログラミング入門―オブジェクト指向のプログラミング手法を基礎から解説』
https://github.com/gushwell
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした