※過去記事はこちら。AlteryxユーザーのためのAdvent of Codeの始め方、1日目、2日目、3日目、4日目、5日目、6日目、7日目、8日目、9日目、10日目、11日目、12日目、13日目、14日目、15日目、16日目、17日目、18日目、19日目、20日目、21日目、22日目、23日目。
第弐拾肆話「Never Tell Me The Odds」
タイトルは「確率を教えてはいけません」です。
前回雪を降らそうとしたのに、雹を形成しているようです。この雹を砕く方法を探ります。
雹は以下の条件(パズルのインプット)のような直線的な軌道を描いています。
19, 13, 30 @ -2, 1, -2
18, 19, 22 @ -1, -1, -2
20, 25, 34 @ -2, -2, -4
12, 31, 28 @ -1, -2, -1
20, 19, 15 @ 1, -5, -3
@の左側は時刻0の時の雹の位置です。頭からx、y、z座標を示しています。右側は速度です。それぞれの軸方向の速度を示しています。1ナノ秒間にそれぞれの軸を動く距離が示されています。
また、これを観測するエリアも指定されており、このサンプルデータでは、7~27を観測します。Part1では、z軸は無視して、x、y軸を考えたときに衝突するかどうか(つまり移動するときに描く軌道の直線が指定エリア無いで交差するかどうか)、衝突する可能性のある雹の数をカウントします。なお、tがマイナス(過去)の場合はカウントしません。
Part2では、1つの石を投げてすべての雹を破壊できる位置と速度を求めます。初期位置の座標の合計がパズルの答えです。
・ネ
・
・タ
・
・バ
・
・レ
Part1,2を解いてみる
Part1は、すべての雹の組み合わせに対して衝突するかどうか、つまり交点を調べていきます。交点がエリア内にあるかどうかを調べます。また、時間マイナスのものはカウントしません。
まず、x、y座標で方程式を作ります。y=ax+bですね。
これのすべての組み合わせをフィールド付加ツールで作り、交点を求めていきましょう。ちなみに、時刻はそれぞれの雹で異なります(t1、t2としています)。
時刻がマイナスでないもの、交点(x、y)が指定の領域内にあるかどうかをフィルタすれば、あとはカウントを取って完了です。
Part2は、、、大ヒントをもらってクリアです。最初は方程式をがんばって解いたのですが、大きすぎる整数になり、どうにもなりませんでした・・・。
みたいな方程式を書きましたが、以下のようなエラーがでて撃沈です(固定小数点でも桁が足りません)。
他のプログラミング言語だと、連立方程式のSolverなどで解決するのですが、Alteryxにはありません。ということで、トリックを使います(このトリックは、サンプルデータではデータが少なすぎて成り立ちません)。
まずいくつかの特殊なケースについて考えていきます。つまり軸方向の速度が同じ雹がいくつかあります。まずそれを探しましょう。その上で、軸方向の速度が同じ速度の雹は常に距離が一定になります。そして、その距離は我々が投げる岩との速度差の倍数になります(これにはMOD関数を使います)。
MOD(([px]-[Source_px]),([SPEED]-[vx]))
我々が投げる岩自体は、ブルートフォース的に適当に作り(±1000の値で試行しています)、同じ速度を持つ雹すべてがこの条件にあてはまる速度を求めます。
これによって岩のvx、vy、vzが求まります。
また、岩と雹が同じ速度を持つ場合、初期ポイントが同じ時だけ衝突するので、いずれかの軸の初期値がこれで求まります(自分のデータでは、z軸が合致しました)。
あとは方程式を解けば完成です。
まず、適当な雹を持ってきて、衝突時間を求めます。今回は、zの初期値(pz)がわかっているので、雹と岩のZ座標が一致するということで以下のt1を求める方程式が成り立ちます。
t1:vz2、pz2は適当な雹の速度、初期位置
([pz2]-[pz])/([vz]-[vz2])
次は、pyです。時間がわかっているので、時間t1のy座標の位置が雹と岩で一致するということで以下の方程式でpyが求まります。
([vy2]-[vy])*[t1]+[py2]
同様に、px。
([vx2]-[vx])*[t1]+[px2]
あとは、px+py+pzで解答が出ます。
ワークフロー全景です。
まとめ
- ロジック、、、というか、数学の問題ですかね、、、。特にPart2はトリックの問題でしょうか。むずい。連立方程式を解けるSolverがあればぶちこむだけかもしれませんが、AlteryxにはさすがにそんなSolverありません・・・。
- Part2でブルートフォース的に時間を手当たり次第にやってみる、、、というところ意外はAlteryxである必要がないという、、、どちらかというと、ペンと紙を使う時間が長い問題でした。
- ヒントは東京Alteryxユーザーグループのgawaさんにいただきました。さすがPrivateLeaderboard1位の男です!
- Private Leaderboardで、Part1は4位(約1時間)、Part2は8位でした。Part1は最速であれば30分くらいあれば解けますが、Part2は解き方がなかなかわからないとのことで、かなりの時間がかかります・・・。
コメント