※過去記事はこちら。AlteryxユーザーのためのAdvent of Codeの始め方、1日目、2日目、3日目、4日目、5日目、6日目、7日目、8日目、9日目、10日目、11日目、12日目、13日目、14日目、15日目、16日目、17日目、18日目。
第拾玖話 「Aplenty」
タイトルは「たっぷり」。
機械の部品は前回たくさん作ったようですが、今度はパーツを整理していく必要があるようです。パーツは4つのカテゴリに分かれています。x、m、a、sのカテゴリです。
各パーツはワークフローを通じて送信され、受入検査が行われるようです。
ワークフローとパーツは以下のようなデータとして得られています。空白行の前の部分がワークフロー、下部分がパーツのリストです。
px{a<2006:qkq,m>2090:A,rfg}
pv{a>1716:R,A}
lnx{m>1548:A,A}
rfg{s<537:gd,x>2440:R,A}
qs{s>3448:A,lnx}
qkq{x<1416:A,crn}
crn{x>2662:A,R}
in{s<1351:px,qqz}
qqz{s>2770:qs,m<1801:hdj,R}
gd{a>3333:R,R}
hdj{m>838:A,pv}
{x=787,m=2655,a=1222,s=2876}
{x=1679,m=44,a=2067,s=496}
{x=2036,m=264,a=79,s=2244}
{x=2461,m=1339,a=466,s=291}
{x=2127,m=1623,a=2188,s=1013}
ワークフローを1ライン見てみましょう。「px{a<2006:qkq,m>2090:A,rfg}」となっていますが、これはワークフローのタグが頭の文字列「px」です。カッコ内はカンマ区切りで区切られていますが、以下のように展開できます。
a<2006:qkq
m>2090:A
rfg
これは、上から評価していくのですが、パーツのaが2006より小さければ、qkqというタグにジャンプします(すなわち「qkq{x<1416:A,crn}」を実行します。そうでなければ、次の行に進み、今度はmが2090より大きければ、A・・・すなわち受け入れ完了ということになります。mが2090以下ならrfgというタグにジャンプします。なお、Rのタグは受け入れ拒否、ということになります。
上のサンプルであれば結果として以下の通りとなるようです。※最初はタグが「in」から始まります。
{x=787,m=2655,a=1222,s=2876}: in -> qqz -> qs -> lnx -> A
{x=1679,m=44,a=2067,s=496}: in -> px -> rfg -> gd -> R
{x=2036,m=264,a=79,s=2244}: in -> qqz -> hdj -> pv -> A
{x=2461,m=1339,a=466,s=291}: in -> px -> qkq -> crn -> R
{x=2127,m=1623,a=2188,s=1013}: in -> px -> rfg -> A
最後に受け入れされたもの、すなわち1,3,5行目のx、m、a、sの値を合計し、3行すべてを合計して得られたものがパズルの答えとなります。
Part2は、愚かなエルフが妙なことを考えたようで、どの評価の組み合わせが受け入れオッケーとなるか、事前に判断したいと言い始めました。x、m、a、sの値は1~4000の間の値を取ることが可能です。これらを組み合わせたときに何通りのパターンが受け入れ可能となるか、を計算します。ここではパーツリストは捨ててワークフロー部分のみを見ます。
・ネ
・
・タ
・
・バ
・
・レ
Part1,2を解いてみる
久々にロジック勝負でした。大量のデータがあるわけでないですが、微妙に悩みポイントが多い感じで・・・。
Part1は素直に組むだけでしょうか。
マクロは以下の通り。入力がごちゃごちゃ多いのは、同じような処理をマクロ内で何度も繰り返したくなかったからです。
繰り返すものは以下のように、ワークフローを実行するタグ番号のみです。
それ以外に、結合用のパーツリスト、
各ワークフローの情報、
各ワークフロータグの条件に合わない場合の最後に来るもののリスト、先程のワークフローの情報にも入っています。
これらをごちゃごちゃと結合しながら答えを出していきます。最終的に合格しなかったもののリストが得られます。
なお、Part1だけでも最初のデータ加工などで結構ツールを使います。
Part2はなんとなく何をすればいけそうか、というのはわかりましたが、実現もタフでした・・・。
出発点は、1のワークフローのみ使います。これを加工していきます。
今回は、部品の判断をせずにinから順にワークフローを実行させ、パターンをすべて作りました。ただ、このパターンは、途中の判断基準は全く入っていません。これを1とします。
このパターンを作るマクロは以下の通り非常にシンプルです。
これにより、最終的に以下のようなデータが得られます。
これとは別に、各タグに対して条件を適用していきました。最初の行はそのままの条件ですが、次の行では条件が反転します。下に行くに連れて、直前の行は処理を反転しつつ、それ以上の行も積み重ねていきます。これを2とします。
1に2をくっつけることで、すべての条件を揃えることができるので、これを条件が絞られるように結合することで最終的な解答が得られます。
絞り方としては、最小値側は下限値のMaxをとり、最大値側は上限値のMinを取ることで比較的容易に得られます。インピュテーションツールでNullに指定値を入れたり、アレンジツールでデータの持ち方をごちゃごちゃ変えたりしています。
最終的にはこういう表が得られればあとはさくっと。
最終的なワークフローは以下のとおりです。必ずしも最適化されていないかもしれません。
まとめ
- Part1はそれほど時間をかけることなくできたように思います。Part2はかなり悩みながら作っていったので、かなり時間がかかりました。Private Leaderボードでは、Part1は9位(リアルタイムスタートじゃないので勘弁してください)、Part2では7位となりました。最速でも2時間はかかるので、かなりタフですね・・・。
- もうマラソン状態なので、お風呂に入ったりしてリフレッシュしたときに思いついたのが結構ハマります・・・。
コメント