2011年12月25日

Androidで動画ストリーミング@家庭内無線LAN

クリスマス、近所のスーパーで子供が今朝貰ったプレゼントについて話しているのを聞いた
「サンタさん来てね、○○(オモチャ名は忘れた)おいてくれたよ」
「ぼくも○○(やっぱり商品名はよく分からなかった)もらったよ」
・・・そうかー。今のオモチャの商品名は妙に長ったらしいんだなぁ~(え?そこ?)

頑張ってる子にはサンタさん来るんだねぇ、
毎日深夜まで残業してる独り身の人たちにサンタさん、
プレゼントは子供たちにあげればいいから労いの言葉だけでもください・・・ホント(ノ_・、)
最後に笑うのは辛くてもひたむきに毎日努力する人だと信じてます

・・・さて!今回は昨日ぼそっとつぶやいた年末年始に向けた
Androidでパソコン内の動画をストリーミング再生しちゃおう@無線LAN
を行なってみたいと思います。

以前のSugarSyncでのストリーミング
便利っちゃあ便利なんですが、auも300万パケットの規制が始まりましたし
動画の変換時間がうっとおしい!
って思われている方もいるような気がします。
(更に言ってしまえばIS01でSugarSyncアプリが動かなくなりましたΣ(゚д゚lll))

というわけで、
自宅内にいるのであればわざわざSugarSyncとかMicroSDHCカードとか使わず
宅内ネットワークを使用して無線LAN経由でパソコンの中の動画を再生しちゃえばいい
というわけです。

では、お料理開始です!

まずは以下の材料を用意します

1:パソコン
2:無線LAN
3:スマートフォン
4:PS3 Media Server
5:UPnPlay
6:見たい動画(今回は外部に公開しないのでどんなのでもOKъ( ゜ー^))

1と2と3については説明するまでも無いはずですが、
パソコンはデュアルコアCPU以上の性能があったほうがいいと思います。
Windows7が入ってるPCであれば、まあ、問題無いです。

無線LANはできるだけ電波状況が良くなるように設置場所を工夫してください、
YouTubeの動画がコマ落ちせずに無線LANで再生できるくらいは必要です

さて、それでは4のPS3 Media Serverについて説明します。

こちら、名前の通り本来はPS3でパソコン内の動画を再生できるようにする
DLNAサーバツールです。
他にもDLNAサーバ機能を持っているツールというのは沢山あるのですが
「日本語」で「無料」で「安定している」ということでこちらを選びました。
(英語もバッチリって方は色々探してみてください)

まずはこちらにアクセスしてください


すると画像のようなページが出ますので、
中央のWindowsロゴをクリック(MacやLinuxの方は両隣をどうぞ)

GoogleProjectのページが表示されますので

赤枠で囲った部分をクリックしてファイルをダウンロードします。

ダウンロードが終わったら、インストールの開始です


pms-setup-windows-(バージョン).exeをダブルクリックして起動します


「NEXT」で先に


インストール場所はデフォルトのままで問題ないはずなので
そのまま「NEXT」
(JAVAがインストールされていないとエラーになるかもしれないので、その時はインストールを)


するとインストールが始まります


インストールが終わったら「Finish」を!
デスクトップにショートカットが欲しい場合は、下のチェックボックスにチェックを

はい、あっさりとインストール完了です(^_^)v

それでは早速起動してみます


起動すると自動的にLAN内にあるDLNA機器をスキャンして表示してくれます
Android端末はドロイド君が表示されていればOKです
(テレビも出てますが、DLNAプレーヤー非対応機種なので使えなかったです(´・ω・`))

実際に動画を見る前に設定を行なっていきます


言語は「Japanese」にします。
自動的に起動する設定はお好みで選択して下さい。
毎日必ず動画を見るんだ!って方はつけておいてもいいかもしれないですが
貧PGは「見たいときに起動すればいい」ということでつけてません(どうでもいいすな)


次はどのフォルダにある動画たちを再生させるかの設定です。
画面一番下の部分がその設定項目になっていますので、
PC内の全てを対象としたい場合は全ドライブ
動画が一箇所に固まっているのであればそのフォルダを選択したりしてください


そして動画変換の基本設定
PS3でも再生してAndroidでも再生するっていう場合、どちらかに合わせることになるので
より再生頻度の多い方に合わせておけばいいかと(都度直せばいいという話でもある)

Androidのスピーカーの場合、音声は通常のステレオで充分ですし
ビデオの品質も無駄に高くするとスマートフォンのCPUが追いつきません
なので、使用している端末と環境に合わせた設定を試してみてください。


そしてもうひとつの設定項目で、ビデオファイルエンジンの設定というのがあります、
ここにある「ビデオと音声の同期」は忘れずにチェックしておきましょう!
長時間の動画で徐々に音声がずれていってしまう現象を軽減できます

さて、設定が終わったら「保存」をクリックして、「サーバーを再起動」します。
これで、PC側の設定はひとまず完了です!


お次はスマートフォン側のストリーミング再生準備となります。

ではこちらからAndroidアプリのUPnPlayをインストールしてください
(もしくはAndroidマーケットから「UPnPlay」を検索してインストール)


無線LANに接続され、パソコン上でPS3 Media Serverが起動していると
画面のように接続可能なサーバ一覧が表示されると思います。
※DIGAも表示されていますが、デジタル放送の再生に対応したツールが
  Androidに入っていないので再生はできないっす(;´▽`A``


ちゃんと接続が行えるとフォルダの一覧が表示されますので、
見たい動画のあるフォルダへ移動していきます
(ドライブ沢山あるけどボロHDDの寄せ集めなので、全部あわせても1TBないっす(T▽T))


お目当てのフォルダに到着したら、以下の分岐判定をすることになります

1:Androidでそのまま再生できるファイルの場合
2:そのままでは再生できないので自動変換をしてもらうファイルの場合

1の場合はそのまま再生できるので問題ないのですが
2の場合が問題です、そのまま再生を一度してみて、ダメであった場合は
「#--TRANSCODE--#」
というフォルダに移動してみてください。

フォルダ内の動画ファイルが再度フォルダの状態で表示されていると思います。


そして再度見たい動画のフォルダに移動したら、
末尾に「MEncoder」と付いたファイルがあると思いますので、
そのファイルを再生してみましょう!(末尾の文字は動画変換設定で設定したエンジン名です)


ファイルを長押しするとこんなような画面も出ますので、
スマートフォンで再生できる動画をUSBケーブル使わずに転送したい!
って場合はここで「Download」を選ぶと変換されたファイルがDL出来るはずです


あとは、パソコンの性能次第ですが、
少し遅れて動画の再生が始まるので、存分に楽しんでください、( ̄▽ ̄)V

以上!お料理完成です!

インターネット上から家庭内のDLNAサーバ動画再生は、
環境が作れないので貧PGは試せていないです。
VPNとかで繋げばできるような気もしますが、IS03のスペックじゃぁ、厳しいので・・・

今回紹介したのも多くの手段の中のほんの一例ですので、
きっともっといい設定方法とかが存在すると思います。
それを色々と探ってみるのも、楽しいAndroidライフの一部ではないでしょうかヾ(@~▽~@)ノ
(綺麗にまとめたつもり)

では!今回のお料理もこのあたりで!

※おやくそく※
ツールの使用方法はあくまでも貧PGが行った一例です、上手く動かなくても怒らないでください。
動画の再生はマナーを守って楽しく使用しましょう(*´∇`*)

2011年12月24日

クリスマス、その日は世界に笑顔があふれる・・・はずなんだが

クリスマスイブも仕事だぜ~、だから独り身でも寂しくないぜ~ъ( ゜ー^)
と言える思っていたらこういう時に限って休日出勤なしという
運命の歯車は歯がすり減った上に逆に回っているような気がする今日この頃

そうそう、年賀状を書かないといけないなーと
年とか月の感覚が年を重ねるにつれて希薄化しているような気もするのですが
まあ、特にすることも無いのでなんかデザインを考えてみましょう

メールの年賀状は相手によって適当に文面変えて送ればいいので
今回は紙の年賀状です。(σ・∀・)σ

では、作成時間30分!2012年の貧乏プログラマからの年賀状。デザインはこちら!

さて、年が明ける前から年賀状を公開したついでに
このAA風挨拶ロゴの詳細をご説明

知っている人にはすぐ分かることかもしれませんが、
この「謹賀新年」の部分はプログラムのコードになっています。
QuineでRubyのコードをまんま出力しております。
(C#でのやり方がよく分からなかったので今回はRubyです(;´▽`A``)

簡単にご説明すれば、自分自身と同じ文字列を出力する
効率主義が叫ばれる中ではなんの意味があるんだい?と言われるような
「プログラマにとってのただの遊びです」
(偉い人にはそれがわからんのですよ)

受け取った人が年賀状を見ながら同じコードを書き
それを実行すれば「謹賀新年」と表示されると。

では、この文字列を出力するソースコードを載せてみます
  1. b="BAhsKwK6AQAA/v+Bf/wDAPwHwP//BwAAACAA0A84wA8/wP8FAEAAAAAAAgAFAACAEAAAUAAABAAAAOD/XwAAAAgBAAAFfEAAAACA////////8AAfUMAHBAAAAAgAoP///wcH/AEFAEAAAACAAAAKAABAGGABUAAABAAAAPj/vwAAAISB8f/9/38AAAAA/v8JPPBAEPz/////AQAAACAAkMADDwQTAAAAABAAAAAAAgAJAABA4AEAAAAAAQAAAOD/nwAAAAQW8P//DxAAAAAA/v/5P/B/AAH+//8AAQAAACAA0P8B/g8QAAAAABAAAAAAAgAFAACAAAH///8AAQAAAOD/XwAAAAgQ4P//DxAAAAAA/v/9P/D/AAH+//8AAQAAACAAkP8B/gcQ8P//DxAAAAAAAgAJAABAAAEAAAAAAQAAACB4kP8B/gcQAAAAABAAAAAAggf9P/D/AP8A/wP+AQAAACAAUAAAAAj/ADAwAP4BAAAAAgAFAACAYADAAwcACAAAACAAUAAAAAgM/wOA/8EAAAAA/v/9////gB8AAADwBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwHwAA/gcA/w8AAAAAAAAA/wH//B9AAAzAAAAAAAAAABAAAEgAAAxwAPz//38AAAAAAQCABACAgAEAAAAABAAAABAAAEgA8A8GAAAAAEAAAAAAD3zgBPwAGAAAAAAABAAAAIBABkJAAIAB/v8A/38AAAAADzzgBfj/MDAACBAAAAAAABAAAFAAAAgG//8A/j8AAAAAAQAABQCAwAcAAAAAAgAAABAAAFAAAAhYAAAAACAAAAAA/wH/BTzgAAQAAAAAAgAAAPAf8F9AAgJAgP8A/z8AAAAAAQAABSQgAAQICBAAAAAAABAAAFBAAgJ/gP8A//8AAAAAAQAAAyQgEAAAAAAACAAAAPADwD9AAgIBAAAAAIAAAAAADAA4AiYgEAAAAAAACAAAADAAACwgAgIBAAAAAIAAAAAAAQBAAyIg8P//D/D/DwAAACAccBQgAgIAAIAAAQAAAAAAZgE9ASIgAAAACBAAAAAAAMAREBMwAgIAAIAAAQAAAAAACP8B/yEgAAAA+B8AAAAAAAAAAAAQ/gMA"  
  2.   
  3. n=Marshal.load(b.unpack("m")[0])  
  4.   
  5. e="eval$s=%w"<<39<<($s*3)  
  6.   
  7. o=""  
  8. j=-1  
  9. 0.upto(54*132-1){|i|  
  10.   o<<((n[i]==1)?e[j+=1]:32)  
  11.   o<<((i%132==131)?10:"")  
  12. }  
  13.   
  14. o[-77,6]=""<<39<<".join"  
  15. puts(o)  

詳しい解説・・・
を書こうと思いましたが、これを必要としているような人が思いつかないので
省略。
興味のある方はhttp://code.google.com/codejam/japan/tshirt.html
などを調べてみてください。もっと綺麗な作り方が見つかると思います。

では、クリスマスはまだ終わっていないようなので
年末年始に布団の中からAndroidで動画鑑賞するための準備をしたいと思います。

では、また!
え?クリスマス当日?当然引きこもるよ!(^_^)v

2011年11月23日

そうだ、SkyDrive、やろう

ご無沙汰です。
最近HDDが高いっすなー、2~3倍近くまで跳ね上がってるものもあるようで
年末こそは新しいPC作ろうと思っていたのですが
HDDの値上り以前に年末の賞与もとい寸志
ほぼ0というレベルのため中止となりましたΣ(T□T)

さらに最近コードを書く仕事が入ってこないので、
非常にコーディング欲が湧いています。
何が悲しくて他社製品のER図とかDFD書かなきゃなんないんだよと(;-_-) =3 フゥ

で、いくつか作ってみたいツールのネタが出たので
欲求不満解消+HDD買えない憂さ晴らしに作ってみた。

その名も

SkyDriveのアカウントを管理して、ついでにワンクリックでログインしちゃうツール


えーっと、機能としてはこれらを満たすように作ったつもりです

1:SkyDriveのアカウントとパスワードを一覧で管理できる
2:ワンクリックでログイン処理が実行できる
3:ログインしたらざっと中の様子を見れる+ちょっとしたファイル操作ができる
4:最後にいつログインしたかが分かるようにする
5:無料

自動でログイン→自動ログアウト機能をつけるべきか迷ったのですが
そういった機能を自分は欲していないので今回はなしとしました<(_ _)>
まあ、あまり自動化しすぎるとSkyDrive側の仕様変更に対応できなくなるし

画面としてはこんな感じです。


SkyDriveは1アカウントで25GB使えるので、
1アカウント20GBの利用量でも5アカウントで100GBいく計算ですな
無限に作れるメールアカウント用意すれば理論上は無制限なファイルスペースが・・・
※あくまでも理論上です。SkyDriveは使用上の注意をよく読み、用法用量を守って正しくお使いください

で、ここから重要です。

どうもこのツール。起動時にインターネット通信を行うためか
ノートンのSONARにマルウェアとして誤検知されますΣ(゚д゚lll)

怪しい処理は何一つしていませんが?ノートン先生?
その証拠としてソースコードも公開しちゃいますよ?

  1. namespace SkyDriveLoginAssistant  
  2. {  
  3.  public partial class Form1 : Form  
  4.  {  
  5.   public Form1()  
  6.   {  
  7.    InitializeComponent();  
  8.   }  
  9.   
  10.   private void button1_Click(object sender, EventArgs e)  
  11.   {  
  12.    //とりあえずテーブルがちゃんと選択されているか確認  
  13.    int SelectRowNumber = 0;  
  14.    SelectRowNumber = dataGridView1.CurrentCell.RowIndex;  
  15.    if (SelectRowNumber < 0)  
  16.    {  
  17.     return;  
  18.    }  
  19.    //データを変数にfade-in  
  20.    string id = dataGridView1[1, SelectRowNumber].Value.ToString();  
  21.    string pass = dataGridView1[2, SelectRowNumber].Value.ToString();  
  22.   
  23.    //入力ボックスにそれぞれ値をセット  
  24.    webBrowser1.Document.All.GetElementsByName("login")[0].Focus();  
  25.    webBrowser1.Document.All.GetElementsByName("login")[0].InnerText = id;  
  26.    webBrowser1.Document.All.GetElementsByName("passwd")[0].InnerText = pass;  
  27.   
  28.    HtmlElementCollection all = webBrowser1.Document.All;  
  29.    HtmlElementCollection forms = all.GetElementsByName("SI");  
  30.    forms[0].InvokeMember("click");  
  31.   
  32.   
  33.    //ログインボタンをクリック!  
  34.    //webBrowser1.Document.Forms[0].InvokeMember("submit");  
  35.   
  36.   
  37.   
  38.   
  39.   
  40.   }  
  41.   
  42.   private void button2_Click(object sender, EventArgs e)  
  43.   {  
  44.    //リストを保存  
  45.    //本当はDataGridViewにDataSourceを設定してXML出力したほうが楽  
  46.    //でも、ファイルを直でメンテしたかったりするので、あえてCSVをループで出力させる  
  47.   
  48.    string line = string.Empty;  
  49.    Encoding enc = Encoding.GetEncoding("Shift_JIS");  
  50.    System.IO.StreamWriter sr = new System.IO.StreamWriter(@"ACLIST.csv"false, enc);  
  51.    int colCount = dataGridView1.Columns.Count;  
  52.             int rowcount = 0;  
  53.      
  54.    foreach (DataGridViewRow row in dataGridView1.Rows)  
  55.    {  
  56.                 rowcount++;  
  57.                 if (rowcount == dataGridView1.Rows.Count)  
  58.                 {  
  59.                     break;  
  60.                 }  
  61.     for (int i = 0; i < colCount; i++)  
  62.     {  
  63.      //フィールドの取得  
  64.      string field;  
  65.      if (row.Cells[i].Value == null)  
  66.      {  
  67.       field = string.Empty;  
  68.      }  
  69.      else  
  70.      {  
  71.       field = row.Cells[i].Value.ToString();  
  72.      }  
  73.      //"で囲む必要があるか調べる  
  74.      if (field.IndexOf('"') > -1)  
  75.      {  
  76.       //"を""とする  
  77.       field = field.Replace("\"""\"\"");  
  78.      }  
  79.                     if (i == 0 && field == "0")  
  80.                     {  
  81.                         break;  
  82.                     }  
  83.      field = "\"" + field + "\"";  
  84.      //フィールドを書き込む  
  85.      sr.Write(field);  
  86.      //カンマを書き込む  
  87.      if (colCount-1 > i)  
  88.      {  
  89.       sr.Write(',');  
  90.      }  
  91.     }  
  92.     //改行する  
  93.     sr.Write("\r\n");  
  94.    }  
  95.    sr.Close();  
  96.   
  97.   }  
  98.   
  99.   private void Form1_Load(object sender, EventArgs e)  
  100.   {  
  101.    //CSVファイルからDataGridViewに値を格納  
  102.    //CSVからDataSourceに使えるテーブルにしたほうがいいかと思う  
  103.    //だが直接セットを貫いてみる。仕事で作るソフトじゃないし(*^-゜)vィェィ♪  
  104.    if (!System.IO.File.Exists("ACLIST.csv"))  
  105.    {  
  106.     //ないものはない  
  107.     return;  
  108.    }  
  109.   
  110.    System.Collections.ArrayList csvRecords = new System.Collections.ArrayList();  
  111.    System.Collections.ArrayList csvFields = new System.Collections.ArrayList();  
  112.    Encoding enc = Encoding.GetEncoding("Shift_JIS");  
  113.             System.IO.StreamReader sr = new System.IO.StreamReader("ACLIST.csv", enc);  
  114.   
  115.   
  116.    string csvText = sr.ReadToEnd();  
  117.    sr.Close();  
  118.    sr.Dispose();  
  119.   
  120.    //前後の改行を削除しておく  
  121.    csvText = csvText.Trim(new char[] { '\r''\n' });  
  122.   
  123.    int csvTextLength = csvText.Length;  
  124.    int startPos = 0, endPos = 0;  
  125.    string field = "";  
  126.   
  127.    while (true)  
  128.    {  
  129.     //空白を飛ばす  
  130.   
  131.     while (startPos < csvTextLength &&  
  132.       (csvText[startPos] == ' ' || csvText[startPos] == '\t'))  
  133.     {  
  134.      startPos++;  
  135.     }  
  136.   
  137.     //データの最後の位置を取得  
  138.   
  139.     if (startPos < csvTextLength && csvText[startPos] == '"')  
  140.     {  
  141.      //"で囲まれているとき  
  142.   
  143.      //最後の"を探す  
  144.   
  145.      endPos = startPos;  
  146.      while (true)  
  147.      {  
  148.       endPos = csvText.IndexOf('"', endPos + 1);  
  149.       if (endPos < 0)  
  150.       {  
  151.        throw new ApplicationException("\"が不正");  
  152.       }  
  153.       //"が2つ続かない時は終了  
  154.   
  155.       if (endPos + 1 == csvTextLength || csvText[endPos + 1] != '"')  
  156.       {  
  157.        break;  
  158.       }  
  159.       //"が2つ続く  
  160.       endPos++;  
  161.      }  
  162.   
  163.      //一つのフィールドを取り出す  
  164.   
  165.      field = csvText.Substring(startPos, endPos - startPos + 1);  
  166.      //""を"にする  
  167.      field = field.Substring(1, field.Length - 2).Replace("\"\"""\"");  
  168.   
  169.      endPos++;  
  170.      //空白を飛ばす  
  171.   
  172.      while (endPos < csvTextLength && csvText[endPos] != ',' && csvText[endPos] != '\n')  
  173.      {  
  174.       endPos++;  
  175.      }  
  176.     }  
  177.     else  
  178.     {  
  179.      //"で囲まれていない  
  180.   
  181.      //カンマか改行の位置  
  182.      endPos = startPos;  
  183.      while (endPos < csvTextLength &&  
  184.        csvText[endPos] != ',' && csvText[endPos] != '\n')  
  185.      {  
  186.       endPos++;  
  187.      }  
  188.   
  189.      //一つのフィールドを取り出す  
  190.   
  191.      field = csvText.Substring(startPos, endPos - startPos);  
  192.      //後の空白を削除  
  193.      field = field.TrimEnd();  
  194.     }  
  195.   
  196.     //フィールドの追加  
  197.     csvFields.Add(field.Replace("\"""").TrimEnd(' '));  
  198.   
  199.     //行の終了か調べる  
  200.   
  201.     if (endPos >= csvTextLength || csvText[endPos] == '\n')  
  202.     {  
  203.      //行の終了  
  204.   
  205.      //レコードの追加  
  206.      csvFields.TrimToSize();  
  207.      csvRecords.Add(csvFields);  
  208.      csvFields = new System.Collections.ArrayList(csvFields.Count);  
  209.   
  210.      if (endPos >= csvTextLength)  
  211.      {  
  212.       //終了  
  213.   
  214.       break;  
  215.      }  
  216.     }  
  217.   
  218.     //次のデータの開始位置  
  219.     startPos = endPos + 1;  
  220.    }  
  221.   
  222.    csvRecords.TrimToSize();  
  223.   
  224.    for (int i = 0; i < csvRecords.Count; i++)  
  225.    {  
  226.     try  
  227.     {  
  228.      int Num = int.Parse(((System.Collections.ArrayList)csvRecords[i])[0].ToString());  
  229.      string id = ((System.Collections.ArrayList)csvRecords[i])[1].ToString();  
  230.      string pass = ((System.Collections.ArrayList)csvRecords[i])[2].ToString();  
  231.      string day = ((System.Collections.ArrayList)csvRecords[i])[3].ToString();  
  232.   
  233.      dataGridView1.Rows.Add(new Object[] { Num, id, pass, day });  
  234.     }  
  235.     catch  
  236.     {  
  237.     }  
  238.    }  
  239.   
  240.   }  
  241.   
  242.   private void button3_Click(object sender, EventArgs e)  
  243.   {  
  244.    int SelectRowNumber = 0;  
  245.    SelectRowNumber = dataGridView1.CurrentCell.RowIndex;  
  246.    if (SelectRowNumber < 0)  
  247.    {  
  248.     return;  
  249.    }  
  250.    dataGridView1[3, SelectRowNumber].Value= DateTime.Now.ToString("yyyy/MM/dd");  
  251.   }  
  252.   
  253.         private void button4_Click(object sender, EventArgs e)  
  254.         {  
  255.             webBrowser1.Navigate("https://skydrive.live.com/");  
  256.         }  
  257.  }  
  258. }  


どうでしょうか?怪しい動きはありましたか?
デジタル署名すればSONARの誤検知を防げるという情報も見ましたが
「無料で公開するツールにそんなお金かけられるかっての!」
※デジタル署名に必要な証明書の入手には大抵お金がかかります

なので無料のVisualStudioで出来る範囲の対応しかできませんことをお詫びします<(_ _)>
もし誤検出されちゃったら復元してもらえるとありがたいです。
ついでにSymantecにクレームしてくれても構いません(;´▽`A``

正直まだまだバグが残っていますが、
必要最低限の機能は確保できているので
あとは運用でカバーしてください。
100点満点のプログラムはコストも時間も掛かり世界じゃ通用しません。
ま、動けばいいんです。バグったらその時直します。

ダウンロードはこちらからどうぞ!

いやー、意味もなく長い仕様書とか標準化とか画面定義書とかない
自由に作れるコーディングはやっぱり楽しいです。ものづくりバンザイ!ヽ(^◇^*)/

2011年9月29日

GoogleCodeJamに挑戦。挫折寸前


お昼休みに激安弁当つつきながらGoogleCodeJamの練習問題というのを解いてみました。

まあ、あれです。昼休みなのに客先サーバの動作が不安定っていう理由で座席に縛り付けられているのです(;-_-) =3
なので気分転換にやってみました。
とりあえずは「数珠繋ぎ」だけですが、
C#で解いたよっ♪
っていう記事が見当たらなかったのでC#で解いてみた結果を載せてみます。

ロジックとしては単純な処理しかしていません。
というか、複雑な処理を組む気はないっす(;´▽`A``

問題としては、

  • 1個以上の電気的スイッチが存在している
  • スイッチの終端には電球がセットされている
  • 終端以外のスイッチの出力には次のスイッチが接続されている
  • スイッチは指を鳴らすという動作によってON/OFFが切り替わる
  • 先頭のスイッチは電力を供給するプラグに接続されている
  • スイッチは電力が供給されている場合のみON/OFFを切り替え、電力が遮断されている場合には変化しない

さて、指をN回鳴らしたとき、K個連結されたスイッチの終端にある電球は光るでしょうか?

脳内で解読した限りこんな感じの要点ではないかと。
興味の出た人はCodeJamのページを読んでみてください。
(練習問題が消えてしまってたらごめんちゃい)

さて、どう解こうかな~、と紙にスイッチの動きを書き出してみたところ
「4個のスイッチ(A-B-C-D)がつながっている場合」
試行回数:スイッチの状態(0:OFF/1:ON)
0:0-0-0-0
1:0-0-0-1
2:0-0-1-0
3:0-0-1-1
4:0-1-0-0
5:0-1-0-1
中略
13:1-1-0-1
14:1-1-1-0@まだ電球は点かない
15:1-1-1-1@ここで電球点灯
16:0-0-0-0@また消える

・・・うん。2進数だ
2進数でスイッチの数の桁数下位ビットがすべて1の時に点灯するな、これ(^_^;)

てことは。
指を鳴らした数を2進数で変数にセット
その数にスイッチの数だけ下位ビットから1を並べた2進数を論理積する
論理積した結果がスイッチの数とイコールであれば電球は点く
ということではないかと。

紙にちょっと書き出して検算中・・・検算中・・・β(□-□ )
うん。たぶんおっけー

で、こんなソースになりましたとさ

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Data;  
  5. using System.Drawing;  
  6. using System.Text;  
  7. using System.Windows.Forms;  
  8. using System.IO;  
  9.   
  10. namespace GCM_A  
  11. {  
  12.     public partial class Form1 : Form  
  13.     {  
  14.         public Form1()  
  15.         {  
  16.             InitializeComponent();  
  17.         }  
  18.   
  19.         string Fileadd = string.Empty;  
  20.         int counter = 0;  
  21.         int[] snapper;  
  22.         int[] finguer;  
  23.         bool[] light;  
  24.   
  25.         private void button1_Click(object sender, EventArgs e)  
  26.         {  
  27.             //ファイルを開くボタンを用意して、ファイルを開くと同時に処理スタート  
  28.   
  29.             OpenFileDialog ofd = new OpenFileDialog();  
  30.   
  31.             if (ofd.ShowDialog() == DialogResult.OK)  
  32.             {  
  33.                 Fileadd = ofd.FileName;  
  34.             }  
  35.             else  
  36.             {  
  37.                 return;  
  38.             }  
  39.   
  40.             //FileLoad  
  41.             //全データをStringの配列に突っ込む  
  42.             string[] lines = System.IO.File.ReadAllLines(Fileadd);  
  43.   
  44.             //先頭に問題数が記載されているのでそれを取り出して各配列の初期値に使う  
  45.             counter = int.Parse(lines[0]);  
  46.             snapper = new int[counter];  
  47.             finguer = new int[counter];  
  48.             light = new bool[counter];  
  49.   
  50.             for (int i = 1; i <= counter; i++)  
  51.             {  
  52.                 //スイッチの数と指を鳴らす回数はブランクで繋がっているので数値に変換して取り出す  
  53.                 snapper[i-1] = int.Parse(lines[i].Split(' ')[0]);  
  54.                 finguer[i-1] = int.Parse(lines[i].Split(' ')[1]);  
  55.   
  56.             }  
  57.   
  58.             //電球点灯状態を一括チェック  
  59.             Calc();  
  60.   
  61.             //結果を出力  
  62.             OUTPUT();  
  63.   
  64.             //めでたしめでたし  
  65.         }  
  66.   
  67.         private void Calc()  
  68.         {  
  69.   
  70.             for (int j = 0; j < counter; j++)  
  71.             {  
  72.                 //指を鳴らした数  
  73.                 uint a = (uint)finguer[j], x;  
  74.                 //スイッチの数から論理積に使用するビット列を作る。-1するのを忘れないように  
  75.                 int n = (int)Math.Pow(2, (snapper[j]));  
  76.                 uint b = (uint)n-1;  
  77.                 //指を鳴らした数と1になっているべき値を論理積  
  78.                 x = a & b;  
  79.                 //電球が点灯しているかを判断  
  80.                 if (x==b)  
  81.                 {  
  82.                     light[j] = true;  
  83.                 }  
  84.                 else  
  85.                 {  
  86.                     light[j] = false;  
  87.                 }  
  88.   
  89.             }  
  90.   
  91.         }  
  92.   
  93.   
  94.         private void OUTPUT()  
  95.         {  
  96.             //ファイルに一気に出力する  
  97.             StreamWriter sw = new StreamWriter(@"z:\output.txt");  
  98.             for (int k = 0; k < counter; k++)  
  99.             {  
  100.                 if (light[k])  
  101.                 {  
  102.                     sw.WriteLine("Case #" + (k + 1).ToString() + ": ON");  
  103.                 }  
  104.                 else  
  105.                 {  
  106.                     sw.WriteLine("Case #" + (k + 1).ToString() + ": OFF");  
  107.                 }  
  108.   
  109.             }  
  110.             sw.Close();  
  111.             sw.Dispose();  
  112.         }  
  113.   
  114.     }  
  115. }  

Largeの問題を1秒程度で解いてくれると思っています。
さらに速度を上げるのであれば、、、そうすなぁ~
スイッチの数であらわすことのできる2進数値よりも指を鳴らす回数のほうが小さいときは即座にOFFと判断できるんじゃないかと。

ここまで書いておいてなんですが、
きっと毎回参加される方々はもっと早くプログラム作って解けるんだろうなぁ~と。
C#でビット演算ってあまりやらないよなぁ~と。

こういうの好きな高校とかの先生は次回のテストで
+αのボーナス問題に穴埋めにしてこの問題使いそうだな
と思ったところでお開き。

土曜の予選に参加できるかどうかはサーバが安定するかにかかっている( ̄▽ ̄;)

2011年9月4日

Hello Android、一年近く前から使ってるけど

実際何もコード入力しなくても自動でHelloと言ってくれるAndroidですが、
ちゃんと自力でコードの編集をしてみようと思います。

今更感オーバーフローしてますが、
自分の備忘録的な内容だったりもするので温かい目で。。。
というかそもそも知ってる人はここ読まないですな、お詫びしておきます<(_ _)>

では、自分の作業メモ開始で


「ファイル」→「新規」→「プロジェクト」を選んでいきます。


今回作成するのはAndroidアプリですので、
Androidプロジェクトを選択。テストプロジェクトとの違いはいまいちよく理解してません(;´▽`A``


とりあえずプロジェクトの名前はHelloAndroidWorldとしました。
普通はHelloWorldなんですが、まあ、弄れもんですからъ( ゜ー^)

ビルドターゲットはIS03君に合わせて2.2を選択。
2.3とか3.2の機種欲しいなぁ。。。うん、貧PGには高値の花高嶺の花ですな(わざとです)

そしてパッケージ名ですが、ドメインとかを付けるのが通例みたいです、
もっとも誰かに公開する予定は今のところないので
「bin_pg.android.helloandroidworld」っていう名前にしましたけど

アクティビティーの作成にチェックを入れて、SDKのバージョンはデフォルトのままで行きます。
なぁ~に、上手く行かなかったらもういっかいやり直せばいいだけですから(⌒▽⌒)


はい、とりあえず準備完了です。

このままメニューバーの中にある「実行」(再生ボタンみたいなやつ)を押せば


何で実行するか聞いてくるので、Androidアプリケーションを選んでOK。
すると・・・


はい、無事動きましたヽ(^◇^*)/
何も入力してないけどアクティビティ名を勝手に出してくれたから
Helloって出てる~

で、満足感ちょっと出ていますが、
ちゃんと自力でコード直しましょう、うん。


Eclipseに戻って「src」の中にある、「.java」のソースファイルを開きます。

デフォルトだと画像のようになっていますが、
これの「setContentView(R.layout.main);」の部分が勝手にアクティビティ名を
出してくれているので、ここを修正してみます。

とりあえずテキストでHelloと言って欲しいので、

import android.widget.TextView;

っていうのを追加
(TextViewのロジック作ったあとで、Ctrl+Space押せば自動で作ってくれるけど)

あとは。


TextView _helloAndroidWord = new TextView(this);
_helloAndroidWord.setText("Hello, Android world");
setContentView(_helloAndroidWord);


TextViewのオブジェクトを新規で作成し、
その値はHello, Android worldと設定し、
表示するのは作成したオブジェクトであるとカタカタ入力。

オブジェクト指向言語触ったことある人ならば大体仕組みはわかるはずです。
というか、言語なんて、1ヶ月本気で取り組めば大抵ある程度のレベルまでは到達できるもんです
(なのに古い言語に拘るSIerとか上層部がいるから下請けや平社員は以下略)

  1. package bin_pg.android.helloandroidworld;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.widget.TextView;  
  6.   
  7. public class HelloAndroidWorldActivity extends Activity {  
  8.     /** Called when the activity is first created. */  
  9.     @Override  
  10.     public void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.           
  13.         TextView _helloAndroidWord = new TextView(this);  
  14.         _helloAndroidWord.setText("Hello, Android world");  
  15.         setContentView(_helloAndroidWord);  
  16.     }  
  17. }  

全体のソースとしてはこんな感じになります。



あとはこれを実行すれば・・・
(再生マークみたいの押すか、Ctrl+F11で)


出来上がり♪
というわけでございます。

さて、GDD2011のAndroidの課題を解くとしましょうかъ( ゜ー^)
では、あとは各自、解散!

Androidアプリの開発環境をスローペースで整える(当然画像つき)+日本語化

なぜに今頃インストール環境を整えるのかといえば、
ようやく自分の開発時間が持てるようになったというか

簡単にいえばGDD2011のクイズにAndroidがあったから
なんですが、まあ、それもきっかけの一つとして
そろそろなんかくっだらね~!って言われるようなツールも作りたくなったと
そういう理由付けとしておいてください。

※GDD2011のクイズでAndroidを選ぼうって場合にチラッと見てもらえればいいですが
※ルールに従って、貧PGの回答は載せておりませんのであしからずご了承を<(_ _)>

さて、AndroidSDKのインストールについてでございますが、
当方のPC、既にインストールされていますので、インストール方法は以前投稿した
シャープ製Androidスマートフォンのスクリーンショット、今頃試す
をご参照願います。IS03ベースですが、他の機種でも大きな違いはありません。
(JAVAのバージョンが新しくなってるくらいでしょうか?)


それでは、開発環境であるEclipseのダウンロードとインストールを行いましょう

ダウンロード先はこちら


上記サイトにある、
Eclipse IDE for Java Developers
というのをダウンロードします。
Eclipse IDE for Java EE Developers
ってのもありますが、プラグインがいっぱいあるかどうかの違いですから、
とりあえずAndroidの開発がしたいだけならEEが付いてないバージョンでも問題ないです
あ、当然そっちを選んでも何ら実害はないので好きなようにしてください( ̄▽ ̄)

通常はその右側にある、Windows 32Bitを選択すればよいでしょう。
64Bit使っている人は64Bit版です。未だXPの貧PGは当然32Bitです(;-_-) =3


クリックすると上記のようなダウンロード先を選ぶ画面が表示されると思います。
赤枠で過去ってある部分がダウンロードするリンクです。
(負荷分散で自動でダウンロード先が変わりますが、中身は一緒ですから心配なさらず)



ダウンロードも終わりましたでしょうか?
懐かしのXP画面で恐縮ですが、こちらのファイルをまずは解凍します。

すると、「eclipse-java-indigo-win32」ってフォルダの下に
「eclipse」っていうフォルダが出来上がるはずですので、
こちらをc:\直下など、自分で管理しやすい場所に移動してあげてください。
日本語の入っていない場所を開発環境にするのはまあ、安全のためってことで、( ̄▽ ̄)V


準備ができたらeclipse.exeを起動しましょう


起動時に作業フォルダの場所を聞かれますので、
自分の管理しやすい場所を選択します(貧PGはc:\直下にeclipse-Workを作って設定しました)
日本語や半角スペースとかのない場所を用意していただくとEclipseが喜びますъ( ゜ー^)

毎回起動時に聞かれるので、特に問題がないようであれば
「Use this・・・」にチェックを付けてしまってもいいと思います


起動したら、Helpの中にある、「Install new Software」を選びます
あ、英語だ・・・って思って諦めてしまいそうですが、
ここでは画像つきで自分の覚書も兼ねて載せていますのでご安心を
ちゃんと最後には日本語化しますから、はい。


すると画面のような状態になると思うので、
Work withに「https://dl-ssl.google.com/android/eclipse/」を入力してエンター。


少し待つとAndroidの開発環境一覧が出ますので、
チェックを付けて「Next」へ進みます。
万一一覧がでない場合はhttpsとなっているところを、httpに変えると出るかもしれません。


一覧が表示されるので、そのまま「Next」で進みます


ライセンスに同意しますか?って聞かれます。
同意しないことには先に進めないので、ざっと目を通して
I accept~にチェックを付けて「Finish」です。


で、インストールが始まるのです。


何故か途中でSecurityWarningなんていう物々しいダイアログが出てきますが(自分だけかな?)
問題ないのでOKで突き進みます


インストールが終わると、Eclipseの再起動を求められますので、
Restart Nowでさっさと再起動します(PCが再起動するわけじゃないのでご安心ください)


再起動したら、Windowメニューにある「Performances」を開きます


AndroidSDKの存在する場所を選びます。
シャープ製Androidスマートフォンのスクリーンショット、今頃試す
でSDKを入れている場合、確かc:\androidの感じの位置にあるはずですので
そのへんは適切に調整をお願い申し上げる。


次はWindowメニュー内にある
「Android SDK and AVD Manager」というのをクリックします。
アイコンにドロイド君がちらっと覗いています。チラリズムです。


EclipseにインストールするSDK関連一覧が表示されますので、
必要なものにチェックを入れていきます。
まあ、全部チェックつけても何ら問題ないですが、
Android1.5のSDKとかもう使わないような気も・・・(1.6はIS01君のために必須ですよ!)

チェックできたらInstall Selectedでインストール開始です


インストールが始まる!と思いきや。
新規追加分のライセンス同意を求められます( ̄▽ ̄;)
面倒なのでAccept Allで全て承認してしまいましょう!


では、インストールできるまでしばしご歓談を。
ぶっちゃけ時間がかかるので、暇なようであればCMをどうぞ


さて、インストール終わりましたでしょうか?


完了のメッセージが出たらOKで閉じちゃいましょう


こいつもCloseで閉じてしまい、一旦Eclipseを再起動したら完了です。
やはり設定変更後の再起動は言われなくても基本です(^_^)v



いやー、随分見た目が変わりました。
お次はAndroidエミュレーターの設定をシておきましょう。
実機動作前にエミュレータで動作確認は基本ですから


再びWindowのなかのチラリズムドロイド君を選びます。


なぜかすでに2.2の仮想デバイスが出来上がっていましたが、
たぶんIS03の設定した際に出来たんじゃないかな?と思っとります。

空っぽであれば、Newを選んで新規に端末を作成します。
まずは自分の持っているAndroid端末に合わせたものを作るといいでしょう


IS03ユーザの貧PGは上の画像のような設定にしてみました。
画面サイズは別サイトの解像度一覧でも参照してください。
あとからいつでも変更できるので、そんなに難しく考える必要はないですが

そして、新規作成や設定確認が終わったら、
いっこ前の画像にある「Start」をクリックします


確認画面が出ますので、Launchをクリックして起動します。
瞬時に立ち上がるわけではないので、少々お待ち下さい。
Javaの起動にワンテンポ必要なものですから


こんな感じの画面が起動すれば仮想デバイスの設定は完了です。
お疲れ様でした。( ̄ー ̄)ノ▽”フリフリ


・・・あ、日本語化を忘れていました(;´▽`A``

日本語化にはまず、こちらにアクセス願います
MergeDocProject Pleiades


これを書いている時点での最新版は1.3.4ですが、
ここは安定板をインストールする方向で説明しておきます。

今更ぶっちゃけますが、上記サイトで配布しているAll in Oneパッケージの場合
既に日本語化されていたりなんかしちゃったり・・・
いや、まあ、うん。

さて、ダウンロードできましたでしょうか?


とりあえず解凍してみましょう


5つ、アイコンが並んでおります。
readmeは読んで字のごとく、説明書が入っていますので、
とりあえず目を通していただけるとありがたいですが、
殆どの人が読まないということはわかりきっていることなのでざっくり手順説明します。
(なお、貧PGは銀行や保険とかの規約もきっちり読んだりするお馬鹿です)

さて、出来上がったファイルを全て選択し、
c:\eclipseにコピーしてしまいます。(別の場所に作ったのならその場所に)

あ、必ずEclipseは終了しておいてください。
じゃないとぶっ壊れる可能性があります


コピーの際、上書きする?と聞かれるので、
問答無用で上書きしてしまいます。


コピーが終わりましたら、まずは「eclipse.ini」というファイルを開きます。
メモ帳とかで開いてもらえればOKです。


開きましたら、一番下の行に
-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
と入力して保存します。
日本語化のプラグインを使用するようにする設定値です


早速日本語で起動したいところですが、
ちょっと待ったそこのあなた!
必ず「eclipse.exe -clean.cmd」というファイルをダブルクリックして実行してください
こうしないと日本語化がうまくいきません


はい、見事日本語化が完了でございます。
次からは普通にeclipse.exeの方を実行してもらえれば無問題ですので。はい(^_^)v

では、今回はこの辺でお開きにいたしましょう。
一休みしたらHallo Android World!のアプリの作り方も
大量の画像セットでお届けしたいと思います。

では!