はじめに
こんにちは、野村です。
今回は、c#を使っていくつかの数列を書き出してみます。
c#というプログラム言語は、Visual Studioという統合開発環境で使って書くのが一般的。
でも、Visual StudioはWindowsでしか使えません。
Windows以外でC#を書くときは、MonoDevelopという統合開発環境を使います。
最近は、Visual Studio Codeというエディタで書くのかな?僕はまだ使ったことがない。
今回は、Vimで書きました。
入力補完がないと結構面倒。もうVimでc#を書くことはないと思う。
あと、この機会にLINQを勉強しながら書いてみました。
少しわかってくると結構面白い。
インストールと実行
Windows以外でC#をビルドするときは、Monoを使います。
Monoというのは、.NET Framework互換の環境を実現するためのオープンソースのソフトウェア群です。
Monoのインストール
管理ユーザになって、mono-develをインストールします(debianの場合)。
# apt install mono-devel
実行
ソースファイルをVimで開いてコマンドモードから以下のコマンドを実行します。
:!mcs % -out:a.exe; ./a.exe
オプション「-out:」で書き出すファイル名を指定できる。
素数
・1より大きい自然数で、正の約数が1と自分自身のみである数。
using System; using System.Collections.Generic; using System.Linq; class Program{ private static IEnumerable<int> Sosu(IEnumerable<int> a){ int m = a.Min(); if (m > Math.Sqrt(a.Max())) return a; return a.Take(1).Concat(Sosu(a.Where(x=>x%m!=0))); } static void Main(){ var a = Enumerable.Range(2,100-2); // 100未満の素数を表示 Console.WriteLine(string.Join(",", Sosu(a))); } }
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
双子素数
・双子素数:差が2である2つの素数の組
・いとこ素数:差が4である2つの素数の組
・セクシー素数:差が6である2つの素数の組
using System; using System.Collections.Generic; using System.Linq; class Program{ private static List<int> Loop(List<int> a, int i, int f){ if (a.Where(v=>v<=Math.Sqrt(i)).All(v=>i%v!=0)){ a.Add(i); if (a.Any(v=>v==i-f)) return a; } return Loop(a,i+1,f); } private static void Twin(int f, int c){ var b = Enumerable.Range(0,c); List<List<int>> m = new List<List<int>> (); m.Add(new List<int>(new int[] {2})); m.Add(new List<int>(new int[] {})); var r = b.Aggregate(m, (x,y)=>{ List<int> z = Loop(x[0],x[0].Last()+1,f); x[0] = z; x[1].Add(z.Last()); return x; }); Disp(r[1],f); } private static void Disp(List<int> a, int f){ var m = a.Select(v=>$"({v-f},{v})"); Console.WriteLine(string.Join(",",m)); } static void Main(){ Twin(2,10); // 双子素数を10組表示 Twin(4,10); // いとこ素数を10組表示 Twin(6,10); // セクシー素数を10組表示 } }
(3,5),(5,7),(11,13),(17,19),(29,31),(41,43),(59,61),(71,73),(101,103),(107,109) (3,7),(7,11),(13,17),(19,23),(37,41),(43,47),(67,71),(79,83),(97,101),(103,107) (5,11),(7,13),(11,17),(13,19),(17,23),(23,29),(31,37),(37,43),(41,47),(47,53)
幸運数
・ポーランドの数学者スタニスワフ・ウラムによって提案された数列。
・素数の性質を研究するために、素数に似たルールで導き出せる数列を考案したとのこと。
using System; using System.Collections.Generic; using System.Linq; class Program{ private static List<int> z = new List<int>(){0}; private static List<int> Luc(List<int> a, int i){ var b = z.Concat(a).ToList(); int s = b[i]; int l = b.Count; if (s<=l) { var m = Enumerable.Range(0,l); var c = m.Where(v=>v%s!=0).Select(v=>b[v]).ToList(); return Luc(c,i+1); } return a; } static void Main(){ // 100未満の幸運数を表示 var a = Enumerable.Range(0,100).Where(v=>v%2!=0).ToList(); Console.WriteLine(string.Join(",", Luc(a,2))); } }
1,3,7,9,13,15,21,25,31,33,37,43,49,51,63,67,69,73,75,79,87,93,99
階乗
・1 から n までのすべての整数の積。
using System; using System.Linq; class Program{ private static int Fact(int a){ if (a==0) return 1; var b = Enumerable.Range(1,a); return b.Aggregate((x,y)=>x*y); } static void Main(){ var a = Enumerable.Range(0,10); // 階乗を10個表示 Console.WriteLine(string.Join(",", a.Select(v=>Fact(v)))); } }
1,1,2,6,24,120,720,5040,40320,362880
フィボナッチ数
・フィボナッチ数:イタリアの数学者レオナルド・フィボナッチにちなんで名付けられた数
・リュカ数:フランスの数学者エドゥアール・リュカにちなんで名付けられた数
using System; using System.Linq; class Program{ private static int Fibo(int a, int b, int c){ if (c==0) return a; if (c==1) return b; return Fibo(a,b,c-2)+Fibo(a,b,c-1); } static void Main(){ var a = Enumerable.Range(0,10); // フィボナッチ数を10個表示 Console.WriteLine(string.Join(",", a.Select(v=>Fibo(0,1,v)))); // リュカ数を10個表示 Console.WriteLine(string.Join(",", a.Select(v=>Fibo(2,1,v)))); } }
0,1,1,2,3,5,8,13,21,34 2,1,3,4,7,11,18,29,47,76
パスカルの三角形
・二項展開における係数を三角形状に並べたもの。
using System; using System.Collections.Generic; using System.Linq; class Program{ private static IEnumerable<int> Pas(int a){ if (a==0) return Enumerable.Range(1,1); var z = Enumerable.Range(0,1); var b = Pas(a-1); return z.Concat(b).Zip(b.Concat(z), (x,y)=>x+y); } static void Main(){ var a = Enumerable.Range(0,10); // パスカルの三角形を10段表示 foreach(int i in a){ Console.WriteLine(string.Join(",", Pas(i))); } } }
1 1,1 1,2,1 1,3,3,1 1,4,6,4,1 1,5,10,10,5,1 1,6,15,20,15,6,1 1,7,21,35,35,21,7,1 1,8,28,56,70,56,28,8,1 1,9,36,84,126,126,84,36,9,1
終わりに
以上、C#を使っていくつかの数列を書き出してみました。
LINQについては、以下の書籍を参考にしました。
LINQとは何なのか?何ができるのか?などについて気になっている人におすすめです。
とにかく語り口が面白い。
にもかかわらずしっかりと説明してくれているという、絶妙なバランスの上に成り立っている良書です。
というわけで、今回はこれにて。