(12/07/01~)

12/07/05

With a little bit of monkey magic, Every thing will be all right.
 さて、ちょっと前の話になりますが、第21回デベロッパーキャンプ の【T4】セッションで私が喋った事を覚えてますか?後半はスッ飛ばし気味だったので、印象が薄いかもしれませんが、

 覚えてない方は、セッション資料補足記事を読み返してみて下さい。

 ...察しのいい方はお分かりかと思いますが、「MonkeyMixer が DL 可能なようだ」 というお話です。

MonkeyMixer (Delphi XE2)
 MonkeyMixer とは、簡単に言えば "VCL フォームと FMX フォームを一つのプロジェクトに混在させる事を可能にする IDE 機能拡張" です。名前のまんまですね。概略は Monkey Mixer の Youtube ビデオを観て頂くとして、DL 先は以下になります。

WHERE CAN I DOWNLOAD MONKEYMIXER?

The arrangement I made with Embarcadero was that MonkeyMixer would be released on CodeCentral. As yet this has not happened, and I don’t know why.

I am trying to figure out what’s holding it up, and I will update this post as I find out more!

 ( ゚Д゚)ハァ? エンバカさん何やってんすか? ...てな訳で、古いバージョンなら DL 可能です。

  

 インストーラの情報を見る限りでは、XE2 Update2 用のようです。XE2 Update 4 HotFix 1 環境にインストールしてみましたが、とりあえずは動作するようです。VCL フォームと FMX フォームを切り替えた時にコンポーネントパレットが更新されない事がありますが、そのような場合には〔F12〕キーを何度か押せばいいようです。

  

 同一プロジェクトに VCL と FMX のフォームを作成しています。試しに Form1 (VCL) のボタンを押すと Form2 (FireMonkey HD) が表示されるというコードを書いてみましたが、普通に動作しました。

 ...ただ、VCL と FMX をミックスするとアプリケーション終了時にメモリリークが発生するそうなので (コメ欄参照)、最新版が CodeCentral で DL 可能になる事を望みます...てか、Simon 氏も Simon 氏で、何故に CodeCentral 以外にアップしないのだろう? XE2 Update 2 用のはアップしたのに?しかも Dropbox でしょう???


12/07/06

X680x0 ATX 電源化用ハーネス作成
 過日 twitter でツイートしたのですが、X68K の電源がことごとくイカれて駄目になっていました。

 先人が残してくれた知恵により、X68K (XVI) の電源を ATX 化して復活させる事にしてみます。

  

 配線は上記のようになります。EXPERT / EXPERT2 / SUPER / XVI / 030 用ですので、初代 / ACE / PRO / PRO2 / Compact 系の場合はメインボード用コネクタの配線を読み替えて下さい。

 必要な材料は以下の通りです。

 ATX 電源に 20pin <-> 24pin 変換ケーブルが付いてたりしますが、ATX 電源延長ケーブルの代わりにこの変換ケーブルでも作れます。ただ、失敗するとケーブルがどんどん短くなっていって作業しにくくなってしまうので、ATX 電源延長ケーブル を使う事をオススメします。

 材料の中で入手が困難...というか面倒なのが 74LS04 と抵抗でしょう。これらは共立エレショップで購入 (通販) 可能です。74LS04 が \31、4.7KΩ抵抗が \40 です (10個単位の注文なので)。私は 74LS04 を 10 個と 4.7KΩ抵抗 10 本を購入しましたが、送料込みで 470円でした。地方在住者には有難いですね。

 ハーネスの作り方ですが、ニッパでブッタ切ってハンダ付けするだけなので特に難しい事はないでしょう。74LS04 の不要なピンを折り取り、必要なピンの足を真っ直ぐに伸ばして空中配線しています。本当は空中配線せずに、ユニバーサル基板を使って作った方が確実だと思います。

  

 ATX 電源コネクタ (メス) 側にある赤いカバーは IDE スマートケーブル (MSI のMB に付属していたもの) のカバーを流用して作りました。

 組み付けて電源を入れてみたら、普通に電源が入りました...ただ、この XVI 君は残念ながら HDD がお亡くなりになっているようですね。多忙のため適当な記事になってしまいましたが、そのうちちゃんとした記事にまとめたいと思っています。


12/07/19

Delphi による FizzBuzz 解法
 エンジニアの採用試験に "FizzBuzz 問題を解かせる" というものがあります。有名なのでご存知の方も多いと思いますが、知らないヒトのためにちょっとだけおさらいを。

 という簡単な仕様です。以前 delfusa 氏totonica 氏がブログの記事にしていたのですが、細川さんの FizzBuzz 問題関連ツイートが気になってしまったという訳です。



 普通に書くと皆さんが最初に提示されたようなコードになります。Delphi (Pascal) だとあまり変態的なコードは書けません。多様性がないと言われればそれまでですが、逆に言えば "誰が書いても大抵読める" というメリットもあります。

 ...話が逸れましたが、僕も即興で "Delphi で面白く書く" というコンセプトで FizzBuzz を書き、ツイートしました。


program FizzBuzz;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

var
  i: WORD;
  s: AnsiString;
  p: PAnsiChar;
begin
  s := 'Fizz Buzz';
  for i:=1 to 100 do
    begin
      p := @s[1];
      if      (i mod 15) = 0 then
        s[5] := #$20
      else if (i mod  3) = 0 then
        s[5] := #$00
      else if (i mod  5) = 0 then
        Inc(p, 5)
      else
        begin
          Writeln(i);
          Continue;
        end;
      Writeln(StrPas(p));
    end;
end.

 ツイートしたのはマジックナンバーがあり、あまりいいコードとは言えないですね。わかりやすいようにちょっと手直ししてみたのが下のコードです。

program FizzBuzz;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

const
  FIZZ      = 3;
  BUZZ      = 5;
  FIZZ_BUZZ = FIZZ * BUZZ;
  SPLITTER  = 5;
var
  i: WORD;
  s: AnsiString;
  p: PAnsiChar;
begin
  s := 'Fizz Buzz';
  for i:=1 to 100 do
    begin
      p := @s[1];
      if      (i mod FIZZ_BUZZ) = 0 then
        s[SPLITTER] := #$20
      else if (i mod  FIZZ    ) = 0 then
        s[SPLITTER] := #$00
      else if (i mod  BUZZ    ) = 0 then
        Inc(p, SPLITTER)
      else
        begin
          Writeln(i);
          Continue;
        end;
      Writeln(StrPas(p));
    end;
end.

 Delphi を含む "ポインタが使える言語" をお使いのヒトは一発で理解できるコードだと思います...が、Delphi 固有の仕様もあるので他の言語をお使いの方は変なコードだと思われるかもしれませんね。

FizzBuzz 解法の解説
 Wikipedia で FizzBuzz を参照した時、Fizz と Buzz の間にホワイトスペースがある事に気付き、以下のようなアルゴリズムになりました。

  1. "Fizz Buzz" という文字列を用意しておく
  2. ループカウンタの値が Fizz(3) と Buzz(5) の最小公倍数で割り切れる場合には文字列の先頭にポインタを置き、"Fizz" と "Buzz" を区切っている文字 (SPLITTER = S[5]) をホワイトスペースにする。
  3. ループカウンタの値が Fizz(3) でのみ割り切れる場合には文字列の先頭にポインタを置き、"Fizz" と "Buzz" を区切っている文字をヌル文字にする。
  4. ループカウンタの値が Fizz(5) でのみ割り切れる場合には "Buzz" の先頭にポインタを置く。
  5. それ以外の場合にはループカウンタの数値を表示し、次のループへ進む (Continue)。
  6. ヌル終端の文字列として文字列を表示する。
 先述のコードを理解するにはポインタと Delphi の長い文字列、それにヌル終端の文字列に関する知識が必要です。

 Delphi 2009 以降の AnsiString へ 'Fizz Buzz' を代入すると以下のようになります。

コードページ
(WORD)
要素サイズ
(WORD)
参照カウンタ
(LongInt)
要素数
(LongInt)
文字列
(文字構成要素: AnsiChar)
Null
(8bit)
932 1 -1 9 F i z z B u z z

 Delphi の文字列は "1 オリジン" で、s[1] は 'F' が格納されています (s[0] を参照すると格納されている文字数を取得できます)。

 この Delphi の文字列はヌル終端の文字列に簡単に変換できます。Delphi の文字列は暗黙のヌル終端がありますので、s[1] へポインタを置いてやればヌル終端文字列として扱えます。但し、Delphi の長い文字列にはヌル文字を含む事ができます

 Fizz(3) と Buzz(5) の最小公倍数で割り切れる場合には、ポインタが s[1] にあり s[5] がホワイトスペースですから、ヌル終端文字列は 'Fizz Buzz' です。

コードページ
(WORD)
要素サイズ
(WORD)
参照カウンタ
(LongInt)
要素数
(LongInt)
文字列
(文字構成要素: AnsiChar)
Null
(8bit)
932 1 -1 9 F i z z B u z z

 Fizz(3) でのみ割り切れる場合には、ポインタが s[1] にあり s[5] がヌル文字ですから、ヌル終端文字列は 'Fizz' です。

コードページ
(WORD)
要素サイズ
(WORD)
参照カウンタ
(LongInt)
要素数
(LongInt)
文字列
(文字構成要素: AnsiChar)
Null
(8bit)
932 1 -1 9 F i z z 0x00 B u z z

 Buzz(5) でのみ割り切れる場合には、ポインタが s[6] にある (Inc でポインタを 5 つ進めています) ので、ヌル終端文字列は 'Buzz' です。

コードページ
(WORD)
要素サイズ
(WORD)
参照カウンタ
(LongInt)
要素数
(LongInt)
文字列
(文字構成要素: AnsiChar)
Null
(8bit)
932 1 -1 9 F i z z B u z z

 後は、@ が "変数のアドレスを指す演算子" で、StrPas() はヌル終端文字列を Delphi の文字列へ変換する関数というのが理解できれば先述のコードの全容が掴めると思います。

 Delphi が扱える文字列については、"各種文字列の実際 (Delphi VCL Tips)" に詳細があるのでそちらを参照してみて下さい。実際に FizzBuzz を解く事になったらですか?...こんなヘンテコなコードは書きませんよ、絶対にね (w


 BACK   古いのを読む   新しいのを読む