※過去記事はこちら。AlteryxユーザーのためのAdvent of Codeの始め方、1日目、2日目、3日目、4日目、5日目、6日目、7日目、8日目、9日目、10日目、11日目、12日目、13日目、14日目、15日目、16日目
17日目です。17日目クリア時点の画像に差し替えています。
タイトルは、「Pyroclastic Flow」です。火砕流。
今回の問題は、テトリスです。ただし、消さないテトリスで、どこまで積み上がるか、という問題です。
サンプルの入力データとしては、以下のようになっています。
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>
これは、落ちてくるブロックを動かす風です。「>」だと右に1マス、「<」だと左に1マス動かします。
ブロックの種類は以下のとおりです。
####
.#.
###
.#.
..#
..#
###
#
#
#
#
##
##
常にこの順番で落ちてきます。
また、ブロックを積む場所は、幅7マスとなっています。高さは無限大なのですが、ブロックが出現するのは床もしくは最も高いブロックの3マス上になります。
この風の影響を受けながら落ちてくるブロックが、2022個落ちてきたときに高さは何マスになるか、という問題です。
Part2は、1,000,000,000,000個(1兆)のブロックが落ちてきたときの高さを求めます。
・ネ
・
・タ
・
・バ
・
・レ
解いてみる
地道に風とブロックの動きをシミュレートする必要があります。ひたすら反復マクロ!可視化しながら地道にデバッグする必要があります。
さすがにマクロの中身もそれなりに複雑です・・・。このマクロは1マス落とすごとに繰り返すため、効率はよくありません(Alteryxの性質上、繰り返し回数が多いほうが遅いので)。落とす高さは3と決まっているので、出現から落とすまでを1回の反復にしたほうが早そうです(が、ツールの数自体は増えそうなので、標準マクロなども組み込んだほうが良さそうです。)
落下ブロックの結果をExcelで可視化したものです。
こちらは、Alteryxの空間ツールで可視化したものです。
Part2は、1兆個のブロックを落とすというファンキーな問題です。もちろん、実際に落とすわけにいかないので、周期性を見つけてそれを使って高さを出す必要があります。
Part2は未解決です。できたらアップします。ようやくできました!
パターンを見つけなければならない、ということはReddit見ていたらわかっていたのですが、パターンの取り方が間違っており時間がかかりました。最初は、ブロックの落ちた結果をマッチングかけていたのですが、うまくいかず、結局のところ、高さの差分、落としたブロックの種類をマッチングパターンに含める必要がありました。サンプルとしては100ブロック程度を取りました(が、サンプルのデータだと35ブロックで繰り返していたのに対し、本番データだと私の場合1700で繰り返していたので、ブロックの取り方はそれなりに多く必要かもしれません)。
パターンマッチングマクロは以下のとおりです。サンプルで取ったデータを一つずつずらしながらマッチングかけているだけです。
Part2を含んだ完全版のワークフローは以下のとおりです。
Part1で3~4分、Part2で21分かかるため、高速化のためには、テトリスマクロの高速化と、Part2ではマッチング用サンプルの取り方、サンプル取るために落とすブロック数(2399まではパターン化しておらず、2400ブロック目から1700周期でパターン化しているので、それでも5800個は必要?)を最適化すれば若干の高速化が図れそうです。
まとめ
- 17日目も、図形的な問題です。がんばってブロックと風の動きをシミュレーションしましょう。Part2はパターンマッチングを行う問題です。
- Part2まで解けている方はたったの3名です・・・。Part1までは地道にやれば解けますが、Part2が難易度高いです。とはいえ、わかってしまえばワークフロー作成の難易度はそれほど高くないように思います。1回実行するごとに結構時間がかかるので、パターンを見つけるために6000個落としたデータはyxdb形式にして別ワークフローでデバッグを行いました。毎回20分待っていられないので!
- 個人タイム:Part1はPrivateLeaderboardで一番乗りでした!Part2は時間かけてクリアしました!
コメント