首頁 >web前端 >js教程 >穀神星搜尋

穀神星搜尋

DDD
DDD原創
2024-12-08 09:14:15139瀏覽

Ceres Search

代碼來臨 2024 年第 4 天

第 1 部分

X 標記(數百個?)點

令我驚訝的是,到目前為止還沒有像這樣的文字搜尋謎題。

這似乎令人畏懼,但我的策略是:

Find the index of each X in the grid
For each X
  Check the next three letters in a straight path in each of the eight directions
  If the path ends up spelling XMAS
    Add one to a running total

在範例中檢查此策略使我相信這是一種成功的方法。

現在是令人興奮的部分:從頭開始編碼整個事情!

找到網格中每個 X 的索引...最終

首先,我必須將輸入解析為二維字元陣列:

let grid = input.split('\n').map(line => line.split(''))

我在網格謎題中經常遇到的一個障礙是考慮越界索引。

如果我從邊界單元格 - 或靠近邊界的單元格開始 - 並朝邊緣方向走這麼遠,我最終會遇到越界的行或列。

我有兩種策略來處理這個問題:

  1. 向我的條件添加檢查以查找不存在的行或列
  2. 用足夠的行和列填滿網格,這樣就不會出現越界的風險

對於這個挑戰,我選擇#2。

用 3 個單元格厚邊框填滿網格,如下圖所示:

grid = grid.map(line => ['.','.','.',...line,'.','.','.'])
grid = [
  new Array(grid[0].length).fill('.'),
  new Array(grid[0].length).fill('.'),
  new Array(grid[0].length).fill('.'),
  ...grid,
  new Array(grid[0].length).fill('.'),
  new Array(grid[0].length).fill('.'),
  new Array(grid[0].length).fill('.')
]

範例網格現在如下所示:

................
................
................
...MMMSXXMASM...
...MSAMXMSMSA...
...AMXSXMAAMM...
...MSAMASMSMX...
...XMASAMXAMM...
...XXAMMXXAMA...
...SMSMSASXSS...
...SAXAMASAAA...
...MAMMMXMMMM...
...MXMXAXMASX...
................
................
................

現在我準備好對填充網格中每個 X 的座標進行編目:

let Xs = []
for (let row = 0; row < grid.length; row++) {
  for (let col = 0; col < grid[0].length; col++) {
    if (grid[row][col] == "X") {
      Xs.push([row, col])
    }
  }
}

成功:在範例網格中找到了所有 19 個 X!

從每個X向八個方向走三步

所有八個相對座標都編碼為 8 元素數組:

let dirs = [
  [-1,-1],
  [-1,0],
  [-1,1],
  [0,-1],
  [0,1],
  [1,-1],
  [1,0],
  [1,1]
]

現在主要演算法:

For each X
  For each direction
    Create an array that starts with X
    Do 3 times
      Move one cell in this direction
      Add the value of that cell to the array
    Check whether the concatenation of all four values is "XMAS"
      If it is, increment a tally

在 JavaScript 中:

Xs.reduce((total, coord) => {
  dirs.forEach((dir) => {
    let [row, col] = coord;
    let [y, x] = dir;
    let word = ["X"];
    for (let i = 0; i < 3; i++) {
      row += y;
      col += x;
      word.push(grid[row][col]);
    }
    if (word.join("") == "XMAS") {
      total++;
    }
  });
  return total;
}, 0);

它為範例輸入產生正確的答案!

當我在拼圖輸入上運行它時會發生什麼? ! !

我得到一個數字:幾千個「XMAS」

這是正確答案嗎?

就是這樣! ! !

嗚呼! ! !

迫不及待想看看第二部有什麼精彩內容......

第2部分

哦天哪。這變得有點複雜了。但可行!

在第 1 部分中,我一直在尋找 X。

現在,我正在尋找

女士

在第 1 部分中,我將字母寫成一條直線來組成單字。

現在,我正在尋找 5 單元短語的四種配置:

M S   M M   S M   S S
 A     A     A     A
M S   S S   S M   M M

一個 M 可以是多個 X-MAS 的一部份。

透過檢查每一個M,我很可能會遇到好幾次。

我需要為每場比賽建立一個字串化座標的 Set()。這樣,我只佔一個 X-MAS 實例一次。

突然——輝煌! - 主意

我不會檢查每一個M。

我會檢查每一個A。

我將按順時針順序檢查對角線相鄰的四個單元格。

X-MAS 比賽將符合以下四種模式之一:

Find the index of each X in the grid
For each X
  Check the next three letters in a straight path in each of the eight directions
  If the path ends up spelling XMAS
    Add one to a running total


`

唷!這比我最初的想法要簡單得多。

而且我應該能夠重新利用我的大部分第 1 部分程式碼!

複製貼上調整

在網格中找到所有 As:
js
令 As = [];
for (let row = 0; row for (let col = 0; col if (網格[行][列] == "A") {
As.push([行, 列]);
}
}
}

建立要檢查的相對座標順序:
js
讓阿迪爾斯 = [
[-1, -1],
[-1, 1],
[1, 1],
[1, -1],
];

將比賽的得分相加:
js
令part2 = As.reduce((總計, 座標) => {
設順時針 = Adirs.map((dir) => {
令 [行,列] = 座標;
令 [y, x] = dir;
返回網格[行y][列x];
});
if (["MSSM", "MMSS", "SMMS", "SSMM"].includes(順時針.join(""))) {
總計;
}
回傳總計;
}, 0);

它為範例輸入產生正確的答案!

現在檢查我的拼圖輸入...

確實! ! !正確答案! ! !

我很高興我突然想到使用 As 而不是 Ms.

我確信,為我節省了數小時的時間來解決頭痛問題。

這是另一個有趣且容易上手的謎題!

我想知道第五天會發生什麼事。

以上是穀神星搜尋的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn