LeetCodeの Mendix: ダンジョンに入る | Mendix

メインコンテンツへスキップ

LeetCodeの Mendix: ダンジョンに入る

Leetcodeの Mendix - ダンジョンに入る - 神話のダンジョンに入る男性を示すブログのサムネイル

このシリーズを初めてご覧になる方のために、これまでの経緯をまとめておきます。開発者が面接の準備に使うLeetCodeの問題を取り上げ、ローコードで解くのは楽しいチャレンジになると思いました。最初のチャレンジでは、 部分の合計 – 簡単な問題を出発点として、 Mendix それを解くために、私たちはさらに難易度を上げて中程度の難易度のチャレンジに挑戦しました。その詳細は、こちらの記事で読むことができます。 二つの塔.

完璧な探求の探求

今度は難しいチャレンジに挑戦する時です。ここから少し難しくなってきます。

私が挑戦すべき適切な課題を探すのに長い時間を費やしました。なぜなら、私が遭遇したほとんどの問題は、以前の配列ベースの問題の焼き直しにすぎず、コード行数を減らして効率を上げるために若干の変更が加えられていたからです。 Mendix そしてそれは確かにこれらの記事の要点ではありません。

次に遭遇した問題は多次元配列に関するものでした。基本的なプログラミング言語では比較的単純な概念で、データのグリッドを素早く保存する方法です。 Mendix、それほどエレガントではありません。しかし、実用的な方法で実行でき、興味深い概念でもある問題が 1 つありました。課題 174: 「ダンジョンゲーム」.

ダンジョンに入る

私たちの探求の主な要素:

  • 勇敢で大胆な騎士。🛡
  • 救出されるのを待つ囚人。⛓
  • ダンジョン 🚨

このチャレンジでは、勇敢な騎士が最後の部屋にいる囚人を救出するために進むダンジョンを作成します。ダンジョンは、便利なことに、正方形のグリッドに部屋が並んでおり、各部屋には以下のいずれかがあります。

  1. 何もなし – ゼロで何もしません。
  2. 悪魔 👿 – 負の数であり、騎士の体力スコアを低下させます。
  3. 魔法のオーブ 🔮 – 正の数であり、騎士の体力スコアを増加させます。

私たちの勇敢な騎士は、左と上に行くのが異常に怖いので、右または下への移動のみでダンジョンを左上から右下へ移動しなければなりません。最後の部分は私が作ったかもしれませんが、ループに陥らないようにするための恣意的なルールです。

ダンジョン マスターとしての私たちの仕事は、騎士が最後の部屋に到達して生き残るために最低限必要な体力を計算し、体力ポイントを 1 にして終了することです。

ダンジョンを作る

まず最初に、ダンジョンを表すデータを保存する方法が必要です。いくつかの選択肢があります:

1 つは、部屋をそのままリスト化する簡単な方法です。移動するには、右に移動する場合は 1 行移動し、下に移動する場合は n 部屋移動します (n は正方形のセルの数)。ただし、このチャレンジには多次元配列の取り込みが含まれるため、少しズルをしているように感じます。

次はもっと Mendix 各部屋をリストに保持し、参照用の行と列のインデックスを保持し、各部屋からその右と下の部屋へのリンクを保存するという方法です。これにより、関連付けを介して 1 つの部屋から次の部屋に移動するのが簡単になります。ただし、これは多次元配列の公平な表現ではありません。

最後に、この演習を始めるには、まず「Row」エンティティを作成し、セルの行を表すとともに、それらを整列させるためのインデックス属性を作成します。次に、その行の各部屋を表す「Cell」という子エンティティを作成します。これも、それらを整列させるためのインデックスを使用します。これは実際には多次元配列のように動作します。実際の配列ほど効率的にナビゲートすることはできません。 Mendix アプローチは異なりますが、できるだけ概要に近づけるように努めています。

データをどのように保存するか

データ ストアができたので、数値を入力しましょう。この部分の効率については心配していないので、ネストされたループをいくつか実行すれば十分です。また、Dungeon エンティティにグリッド サイズと最大セル値の属性を追加して、さまざまな範囲を構成できるようにしました。現時点では、どちらもデフォルトで 10 に設定されています。データ ロードの本体は次のようになります。シンプルです。

本体グラフ

これを画面に出力し、ギャラリー ウィジェットに SASS スタイルを少し追加すると、例のダンジョンによく似たものになります。

類似例

ルートを計画する

ここで、騎士は右と下にしか移動できないことを念頭に置きながら、ダンジョンを横断する必要があります。左上隅のグリッド参照 0-0 から開始し、そこから次の最適なステップを確認します。上記の例では、右へのステップになります。それぞれの値が最大になるステップ (この場合は 0) を実行します。また、騎士の体力とそれがどれだけ低下するかを追跡する必要があることも覚えておく必要があります。そのため、現在の体力と最低体力の別の属性をダンジョンに追加することはおそらく価値があります。

私たちの勇敢な騎士は最初のセルから旅を始めます。すでに体力を 1 ポイント失っているので、あまり良いスタートとは言えません。そこで、彼を最初のセルに配置して、初期体力を計算することからフローを開始します。

心臓の健康を計算する

これを実行すると、最初のセルが更新され、彼の現在位置が表示され、彼の健康スコアも更新されます。

正常性スコア

次に、ダンジョン内で次の最善のステップを踏むパスを見つけましょう。これを行う 1 つの方法は、右と下のオプションを比較し、体力に最も影響を与えるオプションを選択する再帰的な Microflow 呼び出しを使用することです。

再帰マイクロフロー呼び出し

この関数を使用すると、そのパスをマップできます。必ずしも最善のパスではありませんが、少なくとも実行可能なパスです。また、体力の最低低下がどこにあるかも確認できるため、それより 10 ポイント大きい値から開始すると、適切な体力値が得られます。以下の例では、ナイトの体力を XNUMX から開始する必要があります。

パスマップ

これで、ダンジョンを通る 1 つの経路と、騎士を囚人のところまで導く体力スコアがわかりました。では、それが最善の経路、つまり体力ポイントが最も少ない経路であると、どうやってわかるのでしょうか。答えは、わかりません。それを理解するには、各ポイントで最適なステップを計算し、騎士が旅の途中で受ける体力の損失量を追跡するボトムアップ アプローチを試す必要があります。

より良いルートを見つける

これを実行するには、囚人から始めて、グリッドの端から外側へ、そして上へ進んでいきます。各ステップで、現在いるマスから次のマスへ移動する相対的なコストを計算する必要があります。グリッドの例を見てみましょう。

グリッド例1
グリッド例2
グリッド例3
グリッド例4

  1. 右下の 0 から 5 または -4 に移動する相対的なコストを計算します。
  2. -4 に移動すると、体力が 4 減少します。
  3. 5 に移動しても体力は消費されません。実際、体力は増加するので、相対的なコストは 0 です。
  4. 最後に、-2 から 2 までの -0 マス目からの最適なステップのコストを計算します。そのため、そのマス目の最終コストは -2 になります。

から Mendix つまり、グリッドを行ごとに、セルごとに逆方向にループする Microflow が必要になります。ステップ 1 では、各セルに属性を追加して、セルの相対コストを保存し、画面に表示します。

セルの相対コストを画面に表示する

次に、必要な行リストを取得し、各行を逆順に反復処理するループを設定します。つまり、行を追跡するためのインデックスと、最初の行 (見方によっては最後の行) に到達するまでそれを継続するための while ループが必要になります。

逆順ループ反復

ご覧のとおり、空のリストもいくつか作成できます。1 つは、相対コストを更新する際にセルに加えられた変更を収集して、最後に一括更新できるようにするもので、もう 1 つは、前回の反復処理からのセルを保存して、2 回の取得を行わなくて済むようにするためのものです。

この新しいループ内で、本当の魔法が起こります。現在の行の反復のセル リストを取得し、その中のすべてのセルをループします。各セルについて、グリッド内の位置を確認します。セルが下部または右側にある場合は、2 つの出口ポイントを持つセルとは異なる方法で処理する必要があるためです。

新しいループの内部を覗いてみよう

各セルについて、最適な出口ポイントに基づいて相対コストを更新する必要があります。一番下の行と最後の列の場合、現在のセルの値に右または下のセルの値が追加されるだけです。他のすべてのセルでは、現在のセルの値に最大の出口ポイントの値が加算されます。最終値がゼロより大きい場合は、相対コストがゼロであるため、値をゼロにリセットするだけであることに留意してください。最も複雑な例では、次のような計算になります。

セルコスト計算

これらのループは、グリッド全体にわたって相対コストを上と左に移動させ、最初のセルに到達して両方のループを終了するまで続きます。この時点で、必要な最小開始ヘルス (最初のセルの相対コストに 1 を加えた値) を計算し、ダンジョンに対して保存します。

この時点で、ダンジョンのサイズを設定して再生成する機能も追加したので、より小さなダンジョンでテストできるようになりました。現在は次のようになっています。正しい答えが出ているように見えます。

グリッド移動例1

グリッド移動例2

成功を祝う

というわけで、これで終わりです。技術的には、この難しいタスクを完了しました。お祝いしましょう。パフォーマンスは追跡していませんし、標準的なコード ソリューションほどパフォーマンスが高いとは思えませんが、私が知る限り、かなり応答性が高く、エレガントなソリューションのように見えます。続行する場合は、おそらく最適なパスを追跡し、この卑劣なダンジョンを通って危険な囚人を救出するために高貴な騎士が移動すべきパスをマークすることに戻りたいと思うでしょう。それを見たい人がいたら、私に知らせてください。

ローコードのさまざまな課題をテストする間、お読みいただきありがとうございます。次に取り組んでほしい問題はありますか? お気軽にご連絡いただき、ご提案をお寄せください。

 

言語を選択してください