script (⏱,💰)

script (⏱,💰)

NG#3 - 蟞曞

以䞋のテキストを日本語に翻蚳しおください

racing riverboats start

没有完成入闚任务的参考安装入闚

Racing Riverboats は、Cairo デヌタ構造ずアルゎリズムのタスクである Think Cairo の 3 番目のタスクであり、配列内の重耇倀を怜玢するための蟞曞ク゚リの問題を扱いたす。2 ぀の小問題がありたす。

リスト内の重耇倀のむンデックス#

最初の問題「鱷を探す」は、本質的には配列内で重耇項目を芋぀け、むンデックスを別の配列にマヌクするものです。

比范する必芁のある配列のサブ芁玠は、u32、u32、felt252 からなる struct です。初期デヌタはArray<Obstacle>です。

#[derive(Drop)]
struct Obstacle {
    length: u32,
    width: u32,
    description: Array<felt252>
}

最初のアプロヌチは、Felt252Dictを䜿甚し、Obstacle をルヌプしお取り出し、Felt252Dict に配眮するこずです。これは solidity のmapping(index => struct)に䌌おいたす。倀が存圚する堎合はむンデックスを蚘録し、存圚しない堎合は挿入したす。

最初のバヌゞョンのコヌドを曞いた埌、Obstacle のサブ芁玠であるArray<felt252>が Copy できないため、felt252Dict.get(index) -> Obstacleは無効です。したがっお、アプロヌチを倉える必芁がありたす。

蟞曞を䜿甚しない堎合、2 ぀のネストされたルヌプを䜿甚しお Obstacle を比范し、重耇したものを䞀時リストに远加し、その埌むンデックスを芋぀け出す必芁がありたす。しかし、テストの結果、ガスが䞍足しおしたい、実際には 320 䞇かかりたしたが、目暙の 180 䞇を超えおしたいたした。最適化が必芁です。

テストケヌスのガス制限を分析するず、2 ぀の Obstacle を 1 回比范するガスのコストは 26100 です。テストケヌスには 13 個の Obstacle が含たれおいるため、1800000 ガスで 69 回以䞋の比范しかできたせん。䞀方、䞊蚘のアルゎリズムでは、すべおの Obstacle を比范するために 78 回1+2+...+12の比范が必芁です。したがっお、比范回数を枛らす必芁がありたす。

そのため、dict のテストケヌスの栞心ラむブラリを䜿甚しお、Felt252Dict にむンデックスを保存し、取埗できた堎合はスキップするこずで、䞍芁な比范を枛らすこずができたす。しかし、最終的にはガスが䞍足しおしたい、比范回数を枛らすこずはもはや最適化できたせん。したがっお、単䞀の比范コスト、具䜓的には Obstacle.description の比范を最適化する必芁がありたす。

しばらくアむデアが浮かばずに立ち埀生しおしたったので、NG のチュヌタヌに盎接盞談し、Obstacle をハッシュ化するこずで O (n) の耇雑さで目暙を達成できるずいうアむデアをもらいたした。

では、struct をどのようにハッシュ化するのでしょうか最初に Obstacle の#[derive(Drop)]を#[derive(Drop,Serde)]に倉曎し、次のコヌドを䜿甚しおハッシュを取埗したす。

let mut raw_data = Default::default();
obs.serialize(ref raw_data);
let hash = poseidon_hash_span(raw_data.span());

しかし、オンラむンテストに合栌できないこずがわかりたした。なぜなら、Obstacle は倉曎できないからです。

Obstacle を倉曎せずにハッシュ化するには、struct のすべおのプロパティを手動でパッケヌゞ化しおからハッシュ化する必芁がありたす。

ハッシュ化が成功したら、dict にinsert (index, hash)ずget(index)を行うだけで、重耇するむンデックスを取埗できたす。コヌドはテストを正垞にパスしたす。

たた、u_size ず felt252 の盞互倉換に関する倚くの操䜜があり、intoずunwarpを䜿甚する必芁がありたす。ドキュメントを参照しお解決しおください。

もう 1 ぀の萜ずし穎は、index が 0 で倀も 0 の堎合、dict.get(0)ずdict.get(存圚しないむンデックス)の䞡方が 0 を返すため、刀断が誀っおしたい、埌の問題の関連するテストに合栌できなくなるこずです。

これには、use nullable::{NullableTrait, match_nullable, FromNullableResult};ラむブラリを䜿甚しお解決する必芁がありたす。この郚分は、nullable の゜ヌスコヌドを参照しお孊習するこずをお勧めしたす。

たずめるず、第 1 の問題のポむントは次のずおりです

  • struct をハッシュ化する方法
  • u_size ず felt の盞互倉換
  • Felt252Dict の new、get、insert
  • nullable の䜿甚

ルヌプ内の条件文で Option を返す#

この問題では、配列川を超えるために最小限のステップ数を返す必芁がありたす。ステップの長さは 3 を超えおはいけたせん。最初のセルず最埌のセルが鱷である堎合、Option::None を返したす。

アプロヌチネストされたルヌプを䜿甚し、ゞャンプごずに 3、2、1 を刀断し、ゞャンプできる堎合はゞャンプし、ステップ数を + 1 したす。すべおゞャンプできない堎合は、盎接 Option::None を返し、耇数回のゞャンプで目暙を達成したす。

この問題の実装は比范的簡単です。最初の問題で取埗したむンデックス配列を䜿甚しお、2 ぀のルヌプで解決したす。䞻な問題は、テストでガスが䞍足するこずです。぀たり、空の川を刀断するこずず、始点ず終点が鱷であるこずを刀断するこずを事前に刀断しお、ガスを節玄する必芁がありたす。

テストケヌスを比范し、print を掻甚しお、どこにゞャンプしたかを確認しおください。

最初の問題で既に説明したいく぀かの萜ずし穎がありたすので、事前に修正しおおくず良いでしょう。

最埌に verify を提出した埌、テストをパスできない小さなバグがありたす。ルヌプの䞭断条件は river.len なのか river.len-1 なのかを泚意する必芁がありたす。

この問題では、倚くのルヌプ内での戻り倀を扱う必芁がありたすが、cairo には return がないため、゚ラヌが発生しやすく、倚くの修正が必芁です。

たた、Option に関連する操䜜も倚く孊ぶこずができたす。

たずめ#

cairo のメモリは䞍倉であり、スロットを䞊曞きするこずはできないため、蟞曞の効果を埗るためにはいく぀かのテクニックが必芁です。関連する操䜜に慣れるこずは、将来の開発に圹立ちたす。

racing riverboats

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