Advent of Codeをデータ分析ツールAlteryxでやってみるシリーズ、2024年13日目です。
※過去記事はこちら。AlteryxユーザーのためのAdvent of Codeの始め方、1日目、2日目、3日目、4日目、5日目、6日目、7日目、8日目、9日目、10日目、11日目、12日目。
Day 13「Claw Contraption」
タイトルは「爪の仕掛け」。中身の話はUFOキャッチャー的なものなので、その爪のことでしょうかね・・・。
ストーリー的にはなぜかクレーンゲームをすることになっています(なんでやねん)。
このクレーンゲームは、ボタンが2つついていてAボタンは3トークン、Bボタンは1トークンで押すことができます。また、各マシンのボタンは移動量がそれぞれ設定されており、商品は一つだけです。
インプットデータとしては以下のようになっています。
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400
Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=12748, Y=12176
Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=7870, Y=6450
Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=18641, Y=10279
ボタンの移動量はX、Y座標にそれぞれ数字で記載されています。また、商品の位置もX、Y座標で記載されています。そして、意地の悪いことにボタンの移動量のせいで商品が取れないクレーンゲームが存在しています。
例えば、一番上のクレーンゲーム、
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400
Aボタンを80回、Bボタンを40回おせば、商品の位置に爪が来て取れる、ということになります。
これによりかかったトークンは、A:80×3=240、B:40×1=40で合計280トークンとなります。
Part1では、景品が取れる装置で、取れるのにかかったすべてのトークンを計算することです。Part2では、製品の位置がなぜか間違っていたとのことで、製品の位置座標に10000000000000を足す必要があります(座標系の間違いだそうです)。これにより、最初の例は以下のような形になります。
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=10000000008400, Y=10000000005400
Button A: X+26, Y+66
Button B: X+67, Y+21
Prize: X=10000000012748, Y=10000000012176
Button A: X+17, Y+86
Button B: X+84, Y+37
Prize: X=10000000007870, Y=10000000006450
Button A: X+69, Y+23
Button B: X+27, Y+71
Prize: X=10000000018641, Y=10000000010279
このパターンでは、2番目と4番目のみが商品が取れます。Part2も求めるものはPart1と同じです。
・ネ
・
・タ
・
・バ
・
・レ
Part1,2を解いてみる
ボタンAを押す回数をaとし、ボタンBを押す回数をbとします。そうすると、
Button A: X+94, Y+34
Button B: X+22, Y+67
Prize: X=8400, Y=5400
は、94a+22b=8400、34a+67b=5400という方程式が成り立ちます。これをa、bに対して方程式を解けばあとは当てはめるだけです・・・。
ただ、このデータをちゃんと横並びのデータにする必要があります。これが若干めんどくさいです。リファクタリングしたワークフローでは正規表現ツールでInputをばらした後、列生成ツールで並びをキレイにすることができます。
例えば、以下のようなデータを
列生成ツールで処理すると、
となります。つまり、Z型になっているものを一直線にしてくれるツールです。これは便利。
あとは、方程式を解けば値を当てはめるだけで自動的に答えが出ます。ちなみに、回答が整数になったものだけを採用すればオッケーです(小数点がついたものは、商品が取れないクレーンゲームです)。
Part2も単純に足せばオッケーです(データ型はInt64にしないとNullになるので気をつけましょう)。
まとめ
- 見た瞬間「数学!」というのはわかりましたが、変な公式とかいらないやつで助かりました。
- 方程式を解くために鉛筆と紙を取り出すのがめんどくさいです
- 列生成ツールが使える貴重な機会!
- Part2で大きい数字が出てきたので、最小公倍数あたりを使うのかと思いましたが、普通にInt64で収まって良かったです。ただ、BruteForce(総当たり)でやると解けないようです・・・。
- Private Leaderboardでは、Part1は5位、Part2は3位でした。もっと真面目に取り組めばよかった、、、的な(最初やばそうに見えたので、ゆっくりやってました・・・)。
- とうとう半分超えました。個人的にはまだ宿題になっていないのが非常に良かったです。後半もこの調子で行きたいですが、ここからが本当にヘビーなのが出るんですよね・・・。
コメント