共鳴共線性

Barbara Streisand
リリース: 2024-12-29 14:02:18
オリジナル
988 人が閲覧しました

Resonant Collinearity

コード 2024 の出現 8 日目

パート 1

わかると思います。やってもいいですか?

私が理解しているところ:

  • 同一の合字の各ペアについて
  • 一方の合字が 1N、もう一方の合字が 2N である点 X を見つけます。N は X からの距離です
  • グリッドの範囲内にある限り、答えにカウントします

これがビジュアルです:

...........
...........
...X.......
...........
.....Y.....   <---1N from top X, 2N from bottom X
...........
.......Y...   <---2N from top X, 1N from bottom X
...........
.........X.
...........
ログイン後にコピー
ログイン後にコピー

視覚的にも明らかです。

アルゴリズム的にそれを決定するにはどうすればよいですか?

1N と 2N をアルゴリズムで計算する

グリッドの例は次のとおりです:

............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
ログイン後にコピー
ログイン後にコピー

0 に焦点を当てます:

  • 4 つあります
  • 座標は 1,8、2,5、3,7、4,4 です。

最初の 2 つの比較:

1,8 vs. 2,5

1 row apart
3 col apart

2 possible antinodes:
0,11: 0 = min(1,2) - 1
3,2

For 0,11
0 = min(1,2) - 1
11 = ....
ログイン後にコピー
ログイン後にコピー

書いているときに、2 つの点を結ぶ線の傾きを本当に知る必要があることに気づきました。

そうすることで、腹の位置を決定するために各軸を加算するか減算するかを知ることができます。

坂道についての記憶を新たにする

式は次のとおりです:

(y2 - y1) / (x2 - x1)
ログイン後にコピー
ログイン後にコピー

結果は次の 4 つのうちの 1 つになります:

  • > 0 は正の傾きを意味します: 上右へ
  • < 0 は負の傾きを意味します: 右下へ
  • 0 は水平線を意味します
  • 無限は垂直線を意味します

例に戻る:

1,8 and 2,5

(5 - 8) / (2 - 1) = -3 / 1 = -3
ログイン後にコピー
ログイン後にコピー

え?負の傾き?いいえ、その線は正の傾きを持っています!

ああ...なるほど。

配列のインデックス作成のカウントは増加しますが、視覚的には減少しています。

インデックスを逆にカウントする必要があります。

次のようにする代わりに:

0 ............
1 ........0...
2 .....0......
3 .......0....
4 ....0.......
5 ......A.....
6 ............
7 ............
8 ........A...
9 .........A..
  ............
  ............
  0123456789
ログイン後にコピー
ログイン後にコピー

次のように数える必要があります:

  ............
  ........0...
9 .....0......
8 .......0....
7 ....0.......
6 ......A.....
5 ............
4 ............
3 ........A...
2 .........A..
1 ............
0 ............
  0123456789
ログイン後にコピー
ログイン後にコピー

もう少し計算が必要です:

array length - current row/col index
ログイン後にコピー

やってみます。

最上位の 0:

12 rows
Row index: 1
12 - 1 = 11

Column index: 8

Coordinates: 8,11
ログイン後にコピー

次の行の 0 について:

Row index: 2
12 - 2 = 10

Column index: 5

Coordinates: 5,10
ログイン後にコピー

そして坂道:

(10 - 11) / (5 - 8)
   -1     /    -3
         1/3
ログイン後にコピー

プラスの傾きです!そうです!

コーディングを始める

アンテナ座標のリストの作成

ネストされた for ループで満たされた空のオブジェクト:

let graph = input.split('\n').map(el => el.split(''))
let antennas = {}
for (let y = 0; y < graph.length; y++) {
  for (let x = 0; x < graph[0].length; x++) {
    if (graph[y][x] !== '.') {
      if (!(graph[y][x] in antennas)) {
        antennas[graph[y][x]] = []
      }
      antennas[graph[y][x]].push([graph.length - y,x])
    }
  }
}
ログイン後にコピー

入力例用にこのオブジェクトを作成します:

{
  '0': [ [ 11, 8 ], [ 10, 5 ], [ 9, 7 ], [ 8, 4 ] ],
  A: [ [ 7, 6 ], [ 4, 8 ], [ 3, 9 ] ]
}
ログイン後にコピー

素敵ですね!

次に、傾きを計算します。

過度に複雑な腹ファインダーの作成

私のスコープ関数は単純です:

function getScope(p1,p2) {
  return (p2[0] - p1[0]) / (p2[1] - p1[1])
}
ログイン後にコピー

これは 2 つの配列を想定しており、4 つの座標すべてを使用してスコープを返します。

類似周波数座標のすべてのペアを比較するときに、この関数を呼び出したいと思います。

この比較は、このスーパーネストされた for ループで行われます。

for (let freq in antennas) {
  let f = antennas[freq]
  for (let i = 0; i < f.length; i++) {
    for (let j = i + 1; j < f.length; j++) {
      // Comparing two antennas of the same frequency
    }
  }
}
ログイン後にコピー

入力例で動作することを確認します:

[ 11, 8 ] [ 10, 5 ]
[ 11, 8 ] [ 9, 7 ]
[ 11, 8 ] [ 8, 4 ]
[ 10, 5 ] [ 9, 7 ]
[ 10, 5 ] [ 8, 4 ]
[ 9, 7 ] [ 8, 4 ]
[ 7, 6 ] [ 4, 8 ]
[ 7, 6 ] [ 3, 9 ]
[ 4, 8 ] [ 3, 9 ]
ログイン後にコピー

9 つの比較。そうです!

それぞれのスコープは?

ありがたいことに、それらも正しく見えます。

次に、非常に複雑な部分について説明します。

4 つのスロープ タイプすべての処理

それらは次のとおりです:

...........
...........
...X.......
...........
.....Y.....   <---1N from top X, 2N from bottom X
...........
.......Y...   <---2N from top X, 1N from bottom X
...........
.........X.
...........
ログイン後にコピー
ログイン後にコピー

これを処理しましょう。

たくさんありますが、各条項内の微妙な点が重要です:

............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
ログイン後にコピー
ログイン後にコピー

ありがたいことに、特定された腹はすべて正しく配置されているようです。

次に、範囲外のものを除外します

境界外の腹を除く

さらに条件を入力してください!

1,8 vs. 2,5

1 row apart
3 col apart

2 possible antinodes:
0,11: 0 = min(1,2) - 1
3,2

For 0,11
0 = min(1,2) - 1
11 = ....
ログイン後にコピー
ログイン後にコピー

各座標が 0 から行または列の長さまでの間にあるかどうかをチェックしています。

次に、アンチノードファインダーの各節の最後で、考えられる両方のノードで関数を呼び出します。

(y2 - y1) / (x2 - x1)
ログイン後にコピー
ログイン後にコピー

そして、私の答えは有効なセットのサイズになります。

これは実際に機能しますか?

実行すると 12 が生成されます。14 ではありません。

なぜそうしないのですか?

...

いくつかのデバッグの後、次のエラーが見つかりました:

1,8 and 2,5

(5 - 8) / (2 - 1) = -3 / 1 = -3
ログイン後にコピー
ログイン後にコピー

行の割り当てが 1 つずれています。 1 つ少ない値が必要です:

0 ............
1 ........0...
2 .....0......
3 .......0....
4 ....0.......
5 ......A.....
6 ............
7 ............
8 ........A...
9 .........A..
  ............
  ............
  0123456789
ログイン後にコピー
ログイン後にコピー

これで問題は解決します。

今は 14 個あります。

パズル入力で実行してみましょう。

...

正解です!!!

予想よりもかなり時間がかかりましたが、やり遂げました!

パート 2 で何が必要になるかは想像することしかできません。

ゴクゴク

パート 2

うん。特定すべき腹点はさらにたくさんあります。

比較的簡単な調整かもしれませんが、これは難しく感じられます。

それについて考えてみましょう。

...

正しい答えを導き出す自信が低い状態で取り組む

主な原因は次のとおりです:

同じ周波数の少なくとも 2 つのアンテナと正確に一致しています

私はこの基準を理解していると思います

私の直感では、任意の周波数が 3 つある限り、3 つのアンテナはすべて腹でもあると考えられます。

もし私が間違っているとしたら、おそらくそれが私の答えが間違っている理由でしょう。アンテナを腹と間違えているのです。

しかし、私にはすべての新しい腹を特定するための戦略があると思います。

Enter: 行をたどるためにさらに while ループを追加します

私の現在のアルゴリズムは、2 つのアンテナの両端の腹を見つけます。

代わりに、境界線から出そうになるまで、線に沿って両方向に歩きたいと思います。

これには、いくつかのリファクタリングが必要になります。

準備はできました。

正の傾斜線の更新された条件は次のとおりです:

  ............
  ........0...
9 .....0......
8 .......0....
7 ....0.......
6 ......A.....
5 ............
4 ............
3 ........A...
2 .........A..
1 ............
0 ............
  0123456789
ログイン後にコピー
ログイン後にコピー

何が変わったのか:

  • 数学を最初に 1 回実行します
  • while ループ内で座標を追加し、対応する diff によって各座標をインクリメントまたはデクリメントします
  • 条件は、座標を自動的に追加する代わりにブール値を返す更新された関数を使用します

これを条項ごとに行う必要がありました。

私は少し間違えたので、入力例を使用すると 1 倍ずれた答えが得られ、非常に奇妙なグリッドが表示され、どの句が誤動作しているかを診断するのに役立ちました。

最終的に、サンプル入力で動作するようになりました。

次に、パズル入力でそれを実行しました。

そして...

正しい答えを生成しました!!!

私は自分自身をとても誇りに思っています!

そして、私のパズル入力に卑劣なエッジケースがなかったことにとても感謝しています!

うわー、これをやり遂げるには数日間の受動的思考が必要でした。

苦労して獲得した 2 つの金星を獲得して、次の日へ。

以上が共鳴共線性の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート