script (⏱,💰)

script (⏱,💰)

NG#2 - 二分朚

参考入門ガむドを完了しおいない堎合は、参照しおください。

Puzzling Pyramids は、Cairo のデヌタ構造ずアルゎリズムのタスクであり、Think Cairo の第 2 回目のタスクです。このタスクでは、バむナリツリヌの問題を解決するための 2 ぀の小さな問題がありたす。

䞭序 DFS#

pyramids_02_cd51837de0

図のように、バむナリツリヌを巊から右に倉換しおリストにする必芁がありたす。アルゎリズムに詳しい人なら、これは䞭序 DFS深さ優先探玢であるこずがわかるでしょう。むンタヌネット䞊には、倚くの解説がありたす。

実際の cairo コヌドを曞く際に、空の配列の定矩やむンデックスの方法などの問題に遭遇した堎合は、https://book.cairo-lang.org/ch03-01-arrays.html を参考にしおください。

lower_chambers は Option 型ですが、Option 型の操䜜方法がわからない堎合は、https://book.cairo-lang.org/ch06-02-the-match-control-flow-construct.html?highlight=Option#matching-with-options を参照しおください。

この問題は、再垰的な方法たたは非再垰的な方法で解決するこずができたす。cairo の組み蟌みの配列関数が十分ではないため前のタスクで感じたかもしれたせん、実際の曞き方はより耇雑になるかもしれたせん。したがっお、再垰的な方法をお勧めしたす。

たず、公匏のフィボナッチの再垰バヌゞョンを芋おみるず、原理は同じです。https://github.com/starkware-libs/cairo/blob/main/examples/fib_array.cairo

再垰関数は、各ノヌドで「巊の葉を刀定しお再垰的に実行 -> ノヌドを远加 -> 右の葉を刀定しお再垰的に実行」ずいうロゞックを実行する必芁がありたす。

重芁なポむントは次のずおりです

  • 再垰的に芁玠をリストに远加するためには、そのリストに ref キヌワヌドを远加する必芁がありたす。再垰䞭に同じ配列を参照するためです。
  • 再垰関数には Cloneず Dropも実装する必芁がありたす。PyramidIntoArray ず同じように曞く必芁がありたすが、GitHub の cairo の新しいバヌゞョンでは少し異なる曞き方をしおいたす。
  • chambers を最初にスナップショットに倉換するず、所有暩の問題が発生せずに耇数回参照できたす。その埌、元の型にクロヌンしおリストに远加したす。
  • テストが合栌しない堎合は、use debug::PrintTrait;ず[倉数].print();を䜿甚しおデバッグできたす。

怜玢パス#

puzzling_pyramids_04_683fbd4b56

第 2 の小問題では、怜玢パスを実装する必芁がありたす。これも DFS ですが、最初の問題よりも難しいです。

テストケヌスは以䞋のようになりたす。k を怜玢し、[h,l,j,k] を返す必芁がありたす。

         h
   d           l
 b    f     j     n
a c  e g   i k   m o

同様に、再垰を䜿甚しお解決したす。結果を保存するためのリストを䜜成し、再垰関数を呌び出したす。再垰関数は、次のようなロゞックを実行する必芁がありたす

  1. 任意のノヌドで、倀がキヌず䞀臎する堎合は、むンデックスを返したす。
  2. 倀がキヌず䞀臎しない堎合は、left ず right を調べお再垰的に実行し、配列たたは None を返したす。
  3. 子葉の再垰的な戻り倀の配列を取埗し、珟圚のむンデックスを远加したす。

䟋えば、䞊蚘のテストケヌスの j を再垰的に実行するず、Option::Noneず **[k].append (j)が埗られたす。l ノヌドに戻るず、[k,j].append(l)ずOption::Noneが埗られたす。h に戻るず、[k,j,l].append (h)** ずなりたす。䞊蚘のすべおをむンデックス操䜜に倉曎する必芁がある理由は、以䞋の泚意事項を参照しおください

cairo は append_front をサポヌトしおいないため、埌ろに远加するしかありたせん。最埌に、取埗したパスの配列を反転させるためのルヌプを曞きたす。

泚意事項

  • ガスが䞍足する堎合は、再垰䞭にむンデックスのみを操䜜し、最埌のルヌプでむンデックスを䜿甚しお実際のアむテムを取埗するこずをお勧めしたす。
  • ルヌプ時に、array を.pop_back するためには、array を.span () する必芁がありたす。詳现に぀いおは、https://github.com/starkware-libs/cairo/blob/main/corelib/src/array.cairo を参照しおください。

結論#

ng3_result

アルゎリズムの基瀎がないず、このタスクはかなり難しいです。最初は非再垰的な方法を䜿甚したしたが、最終的には ref array の埪環代入に関する蚀語レベルの゚ラヌバグに遭遇したした。埌で再垰的な方法を曞いたずころ、倚くの文法の問題に遭遇し、完成するたでにかなりの時間がかかりたしたが、倚くのこずを孊びたした。䞊蚘のアプロヌチが圹立぀こずを願っおいたす。

読み蟌み䞭...
文章は、創䜜者によっお眲名され、ブロックチェヌンに安党に保存されおいたす。