2014年12月17日

C#でn個の数値を10個ずつ折り返して表示

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その57

この問題のオリジナルタイトルは、、「ビンゴの結果を整形表示」です。

■問題 (出題者:raynstard さん)
「重複無し乱数」の続編です。 「重複無し乱数」で作ったbingo関数の結果を下のように「何番目の乱数か」と セットにして10個ずつ折り返して表示するコードを書いてください。

>>> bingo(30)
 1  2  3  4  5  6  7  8  9 10
29 14 16 13 30 15 22 11 25  9

11 12 13 14 15 16 17 18 19 20
23  4 18  5 28 17  8 12 21 20

21 22 23 24 25 26 27 28 29 30
26  6  2 19  1  7 10 27  3 24

>>> bingo(35)
 1  2  3  4  5  6  7  8  9 10
 7 15  3 32  1 16 17 28  6 29

11 12 13 14 15 16 17 18 19 20
19 23 30 26 20  5 12  2 25 31

21 22 23 24 25 26 27 28 29 30
35 13 24 18 11  8 10 34 22 21

31 32 33 34 35
 9  4 27 33 14



前回作成した Bingoクラスに、Printメソッドを追加しました。
表示する個数が100を超えても、数字がくっつかないように工夫しています。 それ以外は、いたって普通のコードです。特に説明するまでもないかと。

using System;
using System.Collections.Generic;
using System.Linq;

namespace Doukaku.Org {
    class Program {
        static void Main(string[] args) {
            var result = Bingo.Create(9);
            Bingo.Print(result);
            Console.ReadLine();
        }
    }

    static class Bingo {
        // シャッフル拡張メソッド : Fisher-Yates shuffle アルゴリズムを採用
        public static IEnumerable<int> Create(int n) {
            return Enumerable.Range(1, n).Shuffle();
        }

        // これが新たに追加したメソッド
        public static void Print(IEnumerable<int> list) {
            string head = "";
            string data = "";
            // listの個数によって、幅を調整している。
            string format = string.Format("{{0,{0}}}", (int)(Math.Log10(list.Count()) + 2));
            int i = 1;
            foreach (var val in list) {
                head += string.Format(format, i);
                data += string.Format(format, val);
                if (i++ % 10 == 0) {
                    Print10(head, data);
                    head = "";
                    data = "";
                }
            }
            if (head.Length > 0)
                Print10(head, data);
        }

        private static void Print10(string head, string data) {
            Console.WriteLine(head);
            Console.WriteLine(data);
            Console.WriteLine();
        }


    }

    static class IEnumerableExtentions {
        static Random rnd = new Random();
        // シャッフル拡張メソッド : Fisher-Yates shuffle アルゴリズムを採用
        public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> list) {
            T[] result = list.ToArray();
            for (int i = result.Length - 1; i > 1; i--) {
                int j = rnd.Next(0, i);
                T a = result[i];
                result[i] = result[j];
                result[j] = a;
            }
            return result;
        }       
    }
}
  

Posted by gushwell at 22:30Comments(0)TrackBack(0)

2014年08月03日

C#で九九の表示(桁合わせ)

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その30

■問題
掛け算の九九を下のように表示してください。
1 * 1 =  1
1 * 2 =  2
1 * 3 =  3
(略)
7 * 8 = 56
7 * 9 = 63
8 * 1 =  8
8 * 2 = 16
8 * 3 = 24
8 * 4 = 32
(略)
9 * 8 = 72
9 * 9 = 81
なお、この問題は掛け算をどうやるかではなく、どうやって右端がそろうようにレ イアウトするかに重点を置いているので、下のようなへこんだ出力は禁止です。
7 * 9 = 63
8 * 1 = 8
8 * 2 = 16

※ ごめんなさい出題者の方が分かりません。

右端そろえは、string.Format 使えば簡単に出来ますね。
using System;
using System.Linq;

namespace Doukaku.Org {
    class Program {
        static void Main(string[] args) {
            PrintTimesTable();
            Console.ReadLine();
        }

        private static void PrintTimesTable() {
            for (int i = 1; i <= 9; i++)
                for (int j = 1; j <= 9; j++) {
                    string s = string.Format("{0} * {1} = {2,2}", i, j, i * j);
                    Console.WriteLine(s);
                }
        }
    }
}

でも、これだけだと面白くないので、LINQ to Object 使って書いてみました。
まずは、クエリ構文使ったコード。

  private static void PrintTimesTable() {
      var q = from i in Enumerable.Range(1, 9)
              from j in Enumerable.Range(1, 9)
              select string.Format("{0} * {1} = {2,2}", i, j, i * j);
      q.ToList().ForEach(Console.WriteLine);
  }

次は、メソッド構文を使ったコード。 やってるいることは同じです。

  private static void PrintTimesTable() {
      Enumerable.Range(1, 9)
          .SelectMany(i => Enumerable
.Range(1, 9) .Select(j => string.Format("{0} * {1} = {2,2}", i, j, i * j))) .ToList() .ForEach(Console.WriteLine); }
  
Posted by gushwell at 21:12Comments(0)TrackBack(0)