Advent of Codeをデータ分析ツールAlteryxでやってみるシリーズ、2024年8日目です。
※過去記事はこちら。AlteryxユーザーのためのAdvent of Codeの始め方、1日目、2日目、3日目、4日目、5日目、6日目、7日目。
Day 08「Resonant Collinearity」
タイトルは「共鳴共線性」。
ストーリーとしては、街中のアンテナが共振するポイントを調べることになりました(正直なんでやねん状態)。共振が起こるポイントは、周波数が同じアンテナ間でのみ発生し、それぞれのアンテナの距離と同じ直線上の位置に発生します。周波数は同じアルファベットもしくは数字なのでわかるようになっています。
Part1の場合、例えば、「a」という周波数のアンテナ間では、以下の「#」の場所で共振が起こります。
..........
...#......
..........
....a.....
..........
.....a....
..........
......#...
..........
..........
例えば以下のようなインプットの場合、
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
以下のようになります。
......#....#
...#....0...
....#0....#.
..#....0....
....0....#..
.#....A.....
...#........
#......#....
........A...
.........A..
..........#.
..........#.
Part2では、共振が起こるポイントが増えており、今までは左右に一箇所しか発生しなかったですが、エリア内で何度も共振が発生します。つまり、Tというアンテナの場合、以下のように共振します。
T....#....
...T......
.T....#...
.........#
..#.......
..........
...#......
..........
....#.....
..........
クイズの答えは、地図内の共振ポイントの数です。Part2については、アンテナの位置も含んでいます。
・ネ
・
・タ
・
・バ
・
・レ
Part1,2を解いてみる
まぁ、よくあるタイプの地図問題です。若干頭が混乱するかもしれませんが、時間をかければできるでしょう・・・。
まず、同じ周波数間ですべての組合せを作ります。これは結合ツールを使ってアンテナの周波数で結合すれば簡単に作れます。
難しいのは、地図上で共振ポイントを落とすところです。2つのアンテナの位置関係で計算をうまくしていく必要があります。様々なアプローチがあると思いますが、私の場合はアンテナの組合せを作った時にX軸上で左側に来るアンテナ、右側に来るアンテナを特定するようにしました。こうすることで、左側のポイントから左側を作成し、右側のポイントから右側を作成するようにでき、複雑さがやわらぎます。さらにY軸に対してもどちらが上にあるのか下にあるのかを見極め、Y軸に対して足し算なのか、引き算なのか、を決定して計算する必要があります(ここにかなり時間がかかりました・・・)。
つまり以下のようになっているとしますが、直線上で左側にあるポイントを作成するには、P1のxからP1とP2のx軸の距離を引けばいいのですが、組合せを作った時点ではP1とP2はどっちがどっちかわからないため、それを確定させる必要があります。もしくは場合分けで、P1のXが小さければ、P1側から引く、P2のXが小さければP2側から引く、ということになります。
私の場合は、これをP1とP2のX軸がP1側の方が小さくなるようにスワップすることで条件式ではなく、固定的にどちらから引き算をすればよいか確定的にしました。
ただ、Y軸についてはこれ以上スワップできないため(ここでY軸だけスワップすると存在しない点を作り出してしまいます)、P1が上にあるか、下にあるかを計算し、上にあった場合はP1のY軸からP1-P2間のY軸の距離を引きます。逆に下側にある場合は下の方に出現させないといけないので足し算を行います。
P2の右側に作るポイントも同じような考え方となります。X軸についてはP1側で足し算をするのは確定的です。Y軸についてはP1の左側に作るときと同じようにします。
Part1について難しいのはこれくらいです。このロジックはどの言語を用いても同じになると思います。
一方、Part2については、何個も作る必要がありますが、1つ作れれば単にP1-P2間の距離に対して整数倍すればよいだけです。ただしMAP内で何個作らないといけないか、というところを計算する必要があります。MAP外の点は簡単に破棄できるため雑に縦のマス目の数+横のマス目の数の文作っておけば事足ります。ただ、ポイントが多くなりすぎるのであれば、最低限の点になるように計算しましょう。ちなみに、私は計算するようにしました。
最終的なワークフローは以下のようになりました。ロジックが思ったより複雑になったので、横長のワークフローになっています。
まとめ
- ポイントを打つロジックの構築に苦労したため、思った以上に時間がかかりました。こういうのはパターン化しておいて時短したいものです。
- Private LeaderboardではPart1は6位、Part2は7位です。思ったより競争力がなかったですね。途中まではこれ簡単じゃんくらいだったんですが、なかなかうまくポイントが作れずハマってしまいました・・・。こういうのは手書きで絵を書きながらやった方が頭に入りますね、きっと・・・。結局トータルで1時間37分もかかってしまいました(Part1で54分)。トップの方は15~20分程度で解いているので全然ダメダメでした・・・。個人的には1時間以内に仕留めたかったです・・・。
- そろそろMAPに分解するマクロ作って少しでも時短した方が良い気がしてきました。チェック用のMAP化も・・・。
コメント