BMINAIEV_BLOG Telegram 59
Соседние клетки

Я редко пишу что-то в этот канал, потому что на интересные посты обычно нужно потратить много времени. Но само его наличие мне очень нравится! Например, часто в комментарии приходят умные люди и рассказывают, как на самом деле что-то надо было сделать :)

Так вот, представим, что у нас есть клеточное поле размером width*height и вы пишете bfs на нем. Есть текущая клетка (row, col). Как обойти всех непосещенных соседей (по стороне) этой клетки?

В совсем крайнем случае можно написать 4 похожих куска кода:
if row + 1 < height && !used[row + 1][col] {
used[row + 1][col] = true;
queue.push((row + 1, col));
}
if col + 1 < width && !used[row][col + 1] {
...
}


Но дублировать код не хочется. Если забыть на секундочку о типах, то можно написать примерно так:
for (dr, dc) in [(0, 1), (1, 0), (0, -1), (-1, 0)] {
let nrow = row + dr;
let ncol = col + dc;
if 0 <= nrow && nrow < height && 0 <= ncol && ncol < width && !used[nrow][ncol] {
used[nrow][ncol] = true;
queue.push((nrow, ncol));
}
}


Это бы нормально работало, если бы все переменные были типа i32. Но в Rust массивы индексируются только типом usize, который беззнаковый. Поэтому в каком-то месте придется приводить типы. Условно:
used[nrow as usize][ncol as usize]

И это выглядит некрасиво. Плюс придется из-за этого сделать width и height типа i32, а интуитивно кажется, что они должны быть usize, иначе придется много где добавлять лишние касты.

Так вот, как проще всего писать такой код на Rust?

P. S. Я еще видел такой вариант (overflowing_add и .0 это обычное сложение, которое разрешает переполнение):
for (dr, dc) in [(0, 1), (1, 0), (0, !0), (!0, 0)] {
let nrow = row.overflowing_add(dr).0;
let ncol = col.overflowing_add(dc).0;
if nrow < height && ncol < width && !used[nrow][ncol] {
used[nrow][ncol] = true;
queue.push((nrow, ncol));
}
}
💩4👍3



tgoop.com/bminaiev_blog/59
Create:
Last Update:

Соседние клетки

Я редко пишу что-то в этот канал, потому что на интересные посты обычно нужно потратить много времени. Но само его наличие мне очень нравится! Например, часто в комментарии приходят умные люди и рассказывают, как на самом деле что-то надо было сделать :)

Так вот, представим, что у нас есть клеточное поле размером width*height и вы пишете bfs на нем. Есть текущая клетка (row, col). Как обойти всех непосещенных соседей (по стороне) этой клетки?

В совсем крайнем случае можно написать 4 похожих куска кода:

if row + 1 < height && !used[row + 1][col] {
used[row + 1][col] = true;
queue.push((row + 1, col));
}
if col + 1 < width && !used[row][col + 1] {
...
}


Но дублировать код не хочется. Если забыть на секундочку о типах, то можно написать примерно так:
for (dr, dc) in [(0, 1), (1, 0), (0, -1), (-1, 0)] {
let nrow = row + dr;
let ncol = col + dc;
if 0 <= nrow && nrow < height && 0 <= ncol && ncol < width && !used[nrow][ncol] {
used[nrow][ncol] = true;
queue.push((nrow, ncol));
}
}


Это бы нормально работало, если бы все переменные были типа i32. Но в Rust массивы индексируются только типом usize, который беззнаковый. Поэтому в каком-то месте придется приводить типы. Условно:
used[nrow as usize][ncol as usize]

И это выглядит некрасиво. Плюс придется из-за этого сделать width и height типа i32, а интуитивно кажется, что они должны быть usize, иначе придется много где добавлять лишние касты.

Так вот, как проще всего писать такой код на Rust?

P. S. Я еще видел такой вариант (overflowing_add и .0 это обычное сложение, которое разрешает переполнение):
for (dr, dc) in [(0, 1), (1, 0), (0, !0), (!0, 0)] {
let nrow = row.overflowing_add(dr).0;
let ncol = col.overflowing_add(dc).0;
if nrow < height && ncol < width && !used[nrow][ncol] {
used[nrow][ncol] = true;
queue.push((nrow, ncol));
}
}

BY Боря программирует


Share with your friend now:
tgoop.com/bminaiev_blog/59

View MORE
Open in Telegram


Telegram News

Date: |

Invite up to 200 users from your contacts to join your channel There have been several contributions to the group with members posting voice notes of screaming, yelling, groaning, and wailing in different rhythms and pitches. Calling out the “degenerate” community or the crypto obsessives that engage in high-risk trading, Co-founder of NFT renting protocol Rentable World emiliano.eth shared this group on his Twitter. He wrote: “hey degen, are you stressed? Just let it out all out. Voice only tg channel for screaming”. Hashtags With Bitcoin down 30% in the past week, some crypto traders have taken to Telegram to “voice” their feelings. More>>
from us


Telegram Боря программирует
FROM American