巨人の肩の上に登る

先人の積み重ねた発見に基づいて、なにかを発見しようとすることを指す。

monoとXamarin StudioでC#

C# を使ってみたかったので,Xamarinで試してみる.

Xamarin とは

Xamarinは,.NETと互換性のある iOS, Android, Mac, WindowsアプリをC#で書くことが可能な,クロスプラットフォーム開発環境です..NETとの互換は有償ではあるもの、小さいサイズのアプリケーションの開発環境は無償で提供されています。(料金表

付属する,Xamarin Studioは名前から類推できますが, IDEです.Windows, Mac版が存在しています.

monoとは

monoは,Mac環境におけるC#コンパイラーです.OSSC#コンパイラで良さげなものはあるのだろうか...

余談1

Xamarinの経緯.Xamarin - wikipediaより.

2000年6月、マイクロソフト.NET Frameworkをはじめて公表した。Ximianのミゲル・デ・イカザはこのLinux版が実現可能か調査を開始した。その後、2001年6月19日、Monoというオープンソースプロジェクトが立ち上げられた。MonoをサポートしていたXimianは2003年8月4日、ノベルにより買収された。
2011年4月のAttachmate(英語版)によるノベルの買収ののち、Attachmateは数百名にも上るノベル従業員のレイオフを発表した。この中にはMonoの開発者が含まれていた。
同年5月16日、ミゲルは彼のブログにて、Monoを新しい企業Xamarinで開発ならびにサポートすると発表した。

余談2

C# より C Sharp の方が,個人的には字面が良い.
また,googleしてるとC Sharpの表記が多い気もします.

C Sharpを書いてみる

今回は C Sharp を書いてみるのが目的です(ので,Xamarinである必要もないのですが...).

Xmarin Studioを起動してみるとこんな感じです.

f:id:mayo_yamasaki:20131216033658p:plain

New... より新しいプロジェクトを作ります.

f:id:mayo_yamasaki:20131216033934p:plain

C# > コンソールプロジェクト より新しいプロジェクトを作成します. IDEは割とすっきりした印象 .

f:id:mayo_yamasaki:20131216034246p:plain

今回は,シンプルにフィボナッチ数を求めるアルゴリズムを実装してみる.

再帰

とりあえず再帰な実装.O(2n).

public static int fibonacciRecur (int n)
{
    return (n < 2) ? n : fibonacciRecur (n - 1) + fibonacciRecur (n - 2);
}

動的計画法

わかりにくいが動的計画法.O(n).

public static int fibonacciDp (int n)
 {
    int a = 0, b = 1;
    int tmp = 1;

    for (int i = 1; i < n; i++)
    {
        tmp = a + b;
        a = b;
        b = tmp;
    }

    return (n==0) ? 0 : tmp;
}

一般式

いわゆるビネの公式で求められる.O(1).

public static int fibonacciGe (int n)
{
    return  (int)Math.Round((
                Math.Pow ((1.0 + Math.Sqrt (5.0)) / 2.0, (double)n)
                - Math.Pow ((1.0 - Math.Sqrt (5.0)) / 2.0, (double)n)
            ) / Math.Sqrt (5.0));
}

完全なコード

using System;

namespace Fibonacci
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            
            if (args.Length != 1)
            {
                Console.WriteLine ("Error : Required one integer arg.");
                return;
            }

            int n;

            try
            {
                n = Convert.ToInt32 (args[0]);
                if (n < 0) { throw new Exception( "Error : Required positive integer." ); };
            }
            catch (InvalidCastException e)
            {
                throw e;
            }

            Console.WriteLine (fibonacciRecur (n)); // Recursive approach
            Console.WriteLine (fibonacciDp (n));    // Dynamic programming approach
            Console.WriteLine (fibonacciGe (n));    // General expression approach

        }

        public static int fibonacciRecur (int n)
        {
            return (n < 2) ? n : fibonacciRecur (n - 1) + fibonacciRecur (n - 2);
        }

        public static int fibonacciDp (int n)
        {
            int a = 0, b = 1;
            int tmp = 1;

            for (int i = 1; i < n; i++)
            {
                tmp = a + b;
                a = b;
                b = tmp;
            }

            return (n==0) ? 0 : tmp;
        }

        public static int fibonacciGe (int n)
        {
            return  (int)Math.Round((
                        Math.Pow ((1.0 + Math.Sqrt (5.0)) / 2.0, (double)n)
                        - Math.Pow ((1.0 - Math.Sqrt (5.0)) / 2.0, (double)n)
                    ) / Math.Sqrt (5.0));
        }
    }

}

実行

実行方法は,コンソールプロジェクトなので,exeファイルを直接実行する.

# build target によるので,下記のいづれかにexeがあります
PROJECT_ROOT/PROJECT_NAME/bin/Debug
PROJECT_ROOT/PROJECT_NAME/bin/Release
$ mono Fibonacci.exe 12
144  // Recursive approach
144  // Dynamic programming approach
144  // General expression approach

余談3

新しい言語を学ぶ際に効率的な,Learn X in Y minutes をやろうとしたのですが,接続できず.
仕方ないので,最速マスターシリーズを読んでみた.

おわりに

少しだけ C Sharp を書いてみましたが,この程度ではC Sharpっぽさは分からず.


関連記事