Help us understand the problem. What is going on with this article?

FileMakerでWhile関数を使ってヌジョレーボーボー

はじめに

元記事(元ネタ)

ヌジョレーボーボー
https://qiita.com/mattn/items/ae764601862b0073071e

対象読者

  • 元ネタ好きな人
  • FileMaker Pro / ProAdvanced ( 以下 FMPA と略す ) ユーザー
  • FMPA 18 で新たに追加された While 関数の実例を見てみたい人

要旨

  • ボ/ジョ/レ/ヌ/ボ の 5 つを用いて、長音の位置を変えず、ランダムに先の 5 つを並べ変えて出力する
    • 出力例 : ヌジョレーボーボー, ジョヌボーボーレー, レボジョーボーヌー, ...
  • shuffle なんて便利な関数の存在しない FMPA でがんばる

参考 : While 関数について

  • While 関数の基本構造は以下の通りになります。
While (
  [
    /* 変数設定 */
  ];

   /* ループし続ける条件 */ ;

  [
    /* ループしている間の処理ロジック */
  ];

  /* 返値 */
)

本題

出力結果

まずは出力結果をお見せします。
ランダム 10 行出力するスクリプトを用意して、それを 3 回ほどまわしてみました。

image.png
image.png
image.png

きちんと全て別々に出力されています。

スクリプトの全体像はこんな感じです。

image.png

ここの $result 変数の計算式の中身が、本題ですね。

計算式の中身

以下のようになりました。
(分かりやすくするため 10 行表示するための $result 再代入の部分は除いています)

Let (
  [
    $c[1] = "ボ";
    $c[2] = "ジョ";
    $c[3] = "レ";
    $c[4] = "ヌ";
    $c[5] = "ボ";
    s = "ー";
    eval = "Int ( 5 * Random ) + 1";

    a = Evaluate ( eval );
    b = While (
          [
            a = a;
            b = a
          ];
          ( b = a );
          [ b = Evaluate ( eval ) ];
          b
        );
    c = While (
          [
            a = a;
            b = b;
            c = a
          ];
          ( c = a ) or ( c = b );
          [ c = Evaluate ( eval ) ];
          c
        );
    d = While (
          [
            a = a;
            b = b;
            c = c;
            d = a
          ];
          ( d = a ) or ( d = b ) or ( d = c );
          [ d = Evaluate ( eval ) ];
          d
        );
    e = While (
          [
            a = a;
            b = b;
            c = c;
            d = d;
            e = a
          ];
          ( e = a ) or ( e = b ) or ( e = c ) or ( e = d );
          [ e = Evaluate ( eval ) ];
          e
        );

    result = $c[a] & $c[b] & $c[c] & s & $c[d] & s & $c[e] & s
  ];

  result
)

解説

えー……見たままな感じなので、あまり解説のしどころもないような……ですが……

基本設計

Let 関数の変数定義でゴリゴリ計算させて、出力結果は最後の result だけで済ませています。
$c[n] の n にあたる数字は計算による代入が可能だったので、これをもって並べ替えをおこなうことにしました。

変数まわり

While 関数の変数スコープですが、上位から継承していて閉じられていないので、要注意です。引数の受取みたいなことができないので、仕方ない仕様なのでしょうけれども。

なるべく短くしよう、という必死の抵抗が見られるのが、ランダムに数字出力させる部分を Evaluate 関数で変数評価していたり、といったところでしょうか。

なお、変数 $c[n] における c は character の c ですが、連番の変数 c とかぶってるので、名付けとして適正なものではありません……

また、変数 s は separetor の s ですが、実際にちゃんとしたコーディングをするときは一文字変数を用いることは、イテレータとしてしばしば用いられる i 以外はオススメしません。こんな記事を見て参考にする人はいないと思いますが、念のため……

実行速度

実行速度は一瞬です(計測まではしていませんが体感で 300 ミリ秒以内程度)

ループ継続条件

While のループ継続条件における ( c = a ) or ( c = b ) といったところも、本当はもっと綺麗に処理したかったのですが……
たとえば PatternCount 関数で PatternCount ( c ; a & b ) みたいな感じで判定できないかな? と試してみたところ、何をしても( RomanZenkaku とか GetAsText とか噛ませてみても)数値として評価されてしまうようで無理でした。

終わりに

全体的に、力業すぎん? と思われること必至ですが、よりスマートな別解があればぜひコメント欄にお寄せ頂きたく!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした