Linuxでもc#を使っていろんな数列を書き出してみる

はじめに

こんにちは、野村です。

今回は、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とは何なのか?何ができるのか?などについて気になっている人におすすめです。
とにかく語り口が面白い。
にもかかわらずしっかりと説明してくれているという、絶妙なバランスの上に成り立っている良書です。

というわけで、今回はこれにて。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

野村 野村のプロフィール
枕は高いほうがいい。高いほうが本を読みやすいのですよ。なので広めのタオルケットを何重にも折りたたんでその上に枕を載せてその上に頭を載せてたりする。twitterやってます