C#|どう書く?org あみだくじ2

 ざっくりと最適化しました。ちょっと自信あります。我ながらエレガントに書けたと思います。

//http://ja.doukaku.org/103/ 投稿用
using System;
using System.Collections.Generic;
class Program {
  static void Main(string[] args) {
    Amida(@"A B C D E
-
- -
- -
- -
|-| | | |");     Console.ReadLine();   }   static void Amida(string amidaText) {     List<string> temp = new List<string>(amidaText.Split(new char[] { '\n' }));     List<char> lastLine = new List<char>(temp[0].ToCharArray());     foreach(string line in temp) {       Console.WriteLine(line);       for(int i = 1; i < line.Length; i = i + 2) {         if(line[i] == '-'){           lastLine.Reverse(i - 1, 3);         }       }     }     Console.WriteLine(lastLine.ToArray());   } }

C#|どう書く?org あみだくじ

 どう書く?orgのお題、あみだくじへの投稿用に書きました。もっとエレガントに書ける気がしますが、これで行きます。

//http://ja.doukaku.org/103/ 投稿用
using System;
using System.Collections.Generic;
class Program {
  static void Main(string[] args) {
    Amida(@"A B C D E
-
- -
- -
- -
|-| | | |");     Console.ReadLine();   }   static void Amida(string amidaText) {     string amidaTemp = amidaText.Split(new char{'\n'});     List<char> amidaRows = new List<char>();     amidaRows.Add(amidaTemp[0].ToCharArray());     for(int i = 1; i < amidaTemp.Length; i++) {       amidaRows.Add(amidaTemp[i].ToCharArray());       for(int j = 0; j < amidaTemp[i].Length; j = j + 2) {         if(j > 0 && amidaTemp[i][j - 1] == '-') {           char tmp;           tmp = amidaRows[0][j];           amidaRows[0][j] = amidaRows[0][j - 2];           amidaRows[0][j - 2] = tmp;         }       }     }     amidaRows.Add(amidaRows[0]);     amidaRows.RemoveAt(0);     amidaRows.Insert(0, amidaTemp[0].ToCharArray());     foreach(char[] line in amidaRows) {       Console.WriteLine(line);     }   } }

C#|どう書く?org正整数のゲーデル数化?

 どう書く?orgのお題正整数のゲーデル数化?への投稿用に書きました。

 既に投稿されているSiroKuroさんのコードのc – ‘0’ってところに萌えつつ、こういうときにIEnumeratorを使うと効率がいいのね~と勉強になりつつ、こんな感じで書いてみました。

 分かりやすく書いたつもりがかえって意図が伝わりにくくなってる気がします。

 参考としてリンクされいるWikiを見ても、ゲーデル数というものがが何なのかさっぱり理解出来ませんが、お題に示されているように書いてみました。

//http://ja.doukaku.org/100/ 投稿用
using System;
using System.Collections.Generic;
class Program {
  static void Main(string[] args) {
    Console.WriteLine(goedel(9));
    Console.WriteLine(goedel(81));
    Console.WriteLine(goedel(230));
    Console.ReadLine();
  }
  static double goedel(int n) {
    string tmpStr = n.ToString();
    double r = 1;
    List<double> prime = new List<double>(new double[] { 2 });
    for(int i = 3; ; i += 2) {
      bool isPrime = true;
      for(int j = 3; j < i; j++) {
        if(i % j == 0) {
          isPrime = false;
          break;
        }
      }
      if(isPrime) prime.Add(i);
      if(prime.Count >= tmpStr.Length) break;
    }
    for(int i = 0; i < tmpStr.Length; i++) {
      r *= Math.Pow(prime[i], (double.Parse(tmpStr[i].ToString())));
    }
    return r;
  }
}

C#|TextBoxにもマウスジェスチャー機能を簡単に追加

 C#|WebBrowserにマウスジェスチャー機能を簡単に追加のTextBox版を書きました。コンテキストメニューの表示設定の切り替えのタイミング以外は元のコードと殆ど同じです。このコンテキストメニューの表示設定の切り替えタイミングの試行錯誤に作業時間の殆どを費やしました。

 これをしないと、マウスジェスチャが終わった後にメニューが開いちゃうんです。で、開かないようにしたら、二度と開かなかったりします。この微妙なタイミングが難しかったです。

 なんでTextBox用にも書いたかと言うと、VB.NETで書いた電八用のビューアにマウスジェスチャ機能を付けたかったからです。↓で閉じる、これだけの為にです。

 ここでVisualStudioだとVBのプロジェクトを参照設定してスタートアッププロジェクトに設定すれば楽なのでしょうが、僕が使っているのはC#、VBそれぞれのExpress Editionです。複数の言語を同時には扱えないので、C#でビルド→VBでテストという繰り返しでした。VSが欲しいです。MSはアカデミックパックに加えてNEETパックとかフリーターパックでも販売するべきです。

 C#とVB.NETを交互に書くのは不思議な感じでした。

C#|どう書く?org 文字列の八方向検索2

 他の皆のコードよりかなり長かったので、短くしてみました。半分になりました。処理時間は倍になった気がします。

 他の皆の他言語のコードも読めれば参考に出来るのですが、難しいです。

//http://ja.doukaku.org/
//http://ja.doukaku.org/99/投稿用
using System;
using System.Collections.Generic;
namespace どう書く_org文字列の八方向検索 {
  class Program {
    static string search;
    static List<string> list;
    static void Main(string[] args) {
      string sample = "リオウウリウ\nウオリウオリ\nオリリオリウ\nリリオオウオ";
      search = "ウオリ";
      char sp = new char { '\n' };
      int width = sample.Split(sp)[0].Length;
      int height = sample.Split(sp).Length;
      list = new List<string>(sample.Split(sp));
      for(int y = 0; y < list.Count; y++) { //縦ループ
        for(int x = 0; x < list[y].Length; x++) { //横ループ
          for(int dx = -1; dx <= 1; dx++) { //左右方向ループ
            for(int dy = -1; dy <= 1; dy++) { //上下方向ループ -1は上、左 1は下、右を表す
              try {
                string strb = "";
                for(int i = 0; i < search.Length; i++) { //iは移動量
                  strb += list[y + i * dy][x + i * dx]; //移動方向をdy,dxで乗算することで反転
                }
                if(search == strb) {
                  string directionStr = "";
                  if(dx < 0) {
                    directionStr += "左";
                  } else if(dx > 0) {
                    directionStr += "右";
                  }
                  if(dy < 0) {
                    directionStr += "上";
                  } else if(dy > 0) {
                    directionStr += "下";
                  }
                  Console.WriteLine("(" + x + "," + y + ")" + "," + directionStr);
                }
              } catch(ArgumentOutOfRangeException) { } catch(IndexOutOfRangeException) { }
            }
          }
        }
      }
      Console.ReadLine();
    }
  }
}

C#|どう書く?org 文字列の八方向検索

 どう書く?orgのお題、文字列の八方向検索投稿用に書きました。

using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic;
namespace どう書く_org文字列の八方向検索 {
  class Program {
    static string search;
    static List<string> list;
    static void Main(string[] args) {
      string sample =
@"リオウウリウ
ウオリウオリ
オリリオリウ
リリオオウオ";
      search = "ウオリ";
      char sp = new char { '\n' };
      int width = sample.Split(sp)[0].Length;
      int height = sample.Split(sp).Length;
      list = new List<string>(sample.Split(sp));
      for(int y = 0; y < list.Count; y++) {
        for(int x = 0; x < list[y].Length; x++) {
          if(list[y][x] == search[0]) {
            if(E(x, y) == search) {
              Console.WriteLine("(" + x + "," + y + ")" + "," + "右");
            }
            if(W(x, y) == search) {
              Console.WriteLine("(" + x + "," + y + ")" + "," + "左");
            }
            if(S(x, y) == search) {
              Console.WriteLine("(" + x + "," + y + ")" + "," + "下");
            }
            if(N(x, y) == search) {
              Console.WriteLine("(" + x + "," + y + ")" + "," + "上");
            }
            if(NE(x, y) == search) {
              Console.WriteLine("(" + x + "," + y + ")" + "," + "右上");
            }
            if(SE(x, y) == search) {
              Console.WriteLine("(" + x + "," + y + ")" + "," + "右下");
            }
            if(NW(x, y) == search) {
              Console.WriteLine("(" + x + "," + y + ")" + "," + "左上");
            }
            if(SW(x, y) == search) {
              Console.WriteLine("(" + x + "," + y + ")" + "," + "左下");
            }
          }
        }
      }
      Console.ReadLine();
    }
    static string E(int x, int y) {
      try {
        return list[y].Substring(x, search.Length);
      } catch(ArgumentOutOfRangeException) { return ""; }
       catch(IndexOutOfRangeException) { return ""; }
    }
    static string W(int x, int y) {
      try {
        return Strings.StrReverse(E(x - search.Length + 1, y));
      } catch(ArgumentOutOfRangeException) { return ""; }
       catch(IndexOutOfRangeException) { return ""; }
    }
    static string S(int x, int y) {
      try {
        StringBuilder strb = new StringBuilder();
        for(int i = 0; i < search.Length; i++) {
          strb.Append(list[y + i][x]);
        }
        return strb.ToString();
      } catch(ArgumentOutOfRangeException) { return ""; }
       catch(IndexOutOfRangeException) { return ""; }
    }
    static string N(int x, int y) {
      try {
        return Strings.StrReverse(S(x, y - search.Length + 1));
      } catch(ArgumentOutOfRangeException) { return ""; }
       catch(IndexOutOfRangeException) { return ""; }
    }
    static string SE(int x, int y) {
      try {
        StringBuilder strb = new StringBuilder();
        for(int i = 0; i < search.Length; i++) {
          strb.Append(list[y + i][x + i]);
        }
        return strb.ToString();
      } catch(ArgumentOutOfRangeException) { return ""; }
       catch(IndexOutOfRangeException) { return ""; }
    }
    static string NW(int x, int y) {
      try {
        return Strings.StrReverse(SE(x - search.Length + 1, y - search.Length + 1));
      } catch(ArgumentOutOfRangeException) { return ""; }
       catch(IndexOutOfRangeException) { return ""; }
    }
    static string NE(int x, int y) {
      try {
        StringBuilder strb = new StringBuilder();
        for(int i = 0; i < search.Length; i++) {
          strb.Append(list[y - i][x + i]);
        }
        return strb.ToString();
      } catch(ArgumentOutOfRangeException) { return ""; }
       catch(IndexOutOfRangeException) { return ""; }
    }
    static string SW(int x, int y) {
      try {
        return Strings.StrReverse(NE(x - search.Length + 1, y + search.Length - 1));
      } catch(ArgumentOutOfRangeException) { return ""; }
       catch(IndexOutOfRangeException) { return ""; }
    }
  }
}

機動戦士ガンダムOO 8

 丁度今、GyaO『機動戦士ガンダムOO』の第八話を観終わったところです。

 内容は、

ソレスタルビーイングの情報漏えいだお!

 今後も、各回お決まりのパターンで紛争に介入しながら、少しずつソレスタルビーイング云々な謎に迫るって感じの進行になるでしょう。

 気になった点

・今回は生ルイスはお預け

・沙慈君パイロットになるフラグ成立!?

 沙慈が羨ましいです。あぁ、僕もルイスに振り回されたいです。

VB.NET|フォルダパス一覧のツリー構造への変換

 多言語度を上げる為にVB.NETに書き換えました。ついでに一番乗りです。

'http://ja.doukaku.org/
'http://ja.doukaku.org/102/投稿用
Imports System
Imports System.Windows.Forms
NameSpace どう書く_orgフォルダパス一覧のツリー構造への変換
Class Program
<STAThread> _
Shared Sub Main(byval args() As String)
Application.Run(new Form1())
End Sub
End Class
class Form1:Inherits Form
'treeView1
Dim treeView1 As TreeView = New TreeView()
'起動時引数でパス一覧のファイルを指定
Dim pathListFilePath As String = System.Environment.GetCommandLineArgs()(1)
Public Sub New()
'treeView1
treeView1.Parent = Me
treeView1.Dock = DockStyle.Fill
End Sub
Private Sub Form1_Load(byval sender As object, byval e As EventArgs)handles Me.Load
'ROOTNode
Dim rootNode As TreeNode = New TreeNode("ROOT")
treeView1.Nodes.Add(rootNode)
For Each fullPath As String In System.IO.File.ReadAllLines(pathListFilePath)
Dim addNode As TreeNode = rootNode
For Each path As String In fullPath.Split(New char(){"\"c})
Dim flag As Boolean = True
For Each node As TreeNode in addNode.Nodes
If node.Text = path Then
addNode = node
flag = False
End If
Next
if flag Then
Dim newnode As TreeNode = New TreeNode(path)
addNode.Nodes.Add(newnode)
addNode = newnode
End If
Next
Next
rootNode.ExpandAll()
End Sub
End Class
End NameSpace

C#|フォルダパス一覧のツリー構造への変換

 どう書く?orgのトピックフォルダパス一覧のツリー構造への変換への投稿用に書きました。

//http://ja.doukaku.org/
//http://ja.doukaku.org/102/投稿用
using System;
using System.Windows.Forms;
namespace どう書く_orgフォルダパス一覧のツリー構造への変換 {
  class Program {
    [STAThread]
    static void Main(string[] args) {
      Application.Run(new Form1());
    }
  }
  class Form1:Form {
    //treeView1
    TreeView treeView1 = new TreeView();
    //起動時引数でパス一覧のファイルを指定
    string pathListFilePath = System.Environment.GetCommandLineArgs()[1];
    public Form1() {
      //Form1
      this.Load += new EventHandler(Form1_Load);
      //treeView1
      treeView1.Parent = this;
      treeView1.Dock = DockStyle.Fill;
    }
    void Form1_Load(object sender, EventArgs e) {
      //ROOTNode
      TreeNode rootNode = new TreeNode("ROOT");
      treeView1.Nodes.Add(rootNode);
      foreach(string fullPath in System.IO.File.ReadAllLines(pathListFilePath)) {
        TreeNode addNode = rootNode;
        foreach(string path in fullPath.Split(new char[] { '\\' })) {
          bool flag = true;
          foreach(TreeNode node in addNode.Nodes) {
            if(node.Text == path) {
              addNode = node;
              flag = false;
            }
            
          }
          if(flag) {
            TreeNode newnode = new TreeNode(path);
            addNode.Nodes.Add(newnode);
            addNode = newnode;
          }
        }
      }
      rootNode.ExpandAll();
    }
  }
}

VC#2005EEでエクスプローラー風のツリービューを実装

 NetBeensとVisualC++2005EEをアンインストールして空いたスペースにVisualC#2005EEをインストールしました。VC#をインストールして最初に書いたのは、フォルダの階層を表示出来るツリービューのDLLです。

 aniscapeのお気に入りツリーをVB.NETで作ったときにちょっと大変だったので、C#で書いてDLLとして残しておこうと思いました。

 再帰処理でフォルダ階層を奥まで読んでゴリゴリとノードを追加していけば簡単なのですが、そうすると全てのノードを追加し終わるまで暫く時間が掛かります。とても実用になりません。

 それなら、ノードを開くときにその下だけ読めばもっと簡単だし、最初の待ち時間もありません。でも、それにも問題があります。ノードの頭についている+-のマークが表示されないので、フォルダの下にファイルやフォルダがあるかどうかが分かりません。

 それではどうするのかと言うと、ノードを開く度に、2階層下まで読み込みます。

 ファイルを表示するのですから、アイコンも表示させた方がいいと思います。

Icon icon = Icon.ExtractAssociatedIcon(“FileName”);

でそのファイルのアイコンを取得出来ます。これを

TreeView.ImageList.Images.Add(“FileName”, icon);

でイメージリストに追加して

TreeNode.ImageKey = “FileName”;

TreeNode.SelectedImageKey = “FileName”;

でノードにアイコンを設定します。

 ここで問題発生です。この一連の処理がとても重いのです。ノードをクリックしてから開くまでに数秒から十数秒掛かります。使い物になりません。

 そこでもう少し改造します。+-マークを表示させる為には2階層下まで読む必要がありますが、2階層下のノードについてはアイコンが無くても問題ありません。そこで、ノードは2階層下まで追加するが、アイコンは1階層下のみ追加する仕様にしました。

 これで、軽快とはいきませんが、使えるレベルまでレスポンスが良くなりました。後はもっとレスポンスが必要な場合の為に、ファイルごとにアイコンを取得しないようにするプロパティでも実装しておけば幅広く使える様になるでしょう。

以上、メモでした。

ソースコード(C#, .NET2.0)

AnisTreeView.cs

バイナリ

AnisTreeView.zip

 大量にノードを開いた時のレスポンスを改善しました。

バイナリ

AnisTreeView1_1_0_0.zip

ソースコード(C#, .NET2.0)

AnisTreeView1_1_0_0.cs