Matrix neighbours

 avatar
unknown
golang
4 years ago
6.6 kB
7
Indexable
package main

import "fmt"

var input = [][]int{
	{9, 3, 0, 0, 8, 3},
	{9, 1, 6, 4, 2, 3},
	{3, 1, 3, 5, 8, 7},
	{9, 8, 3, 7, 4, 9},
	{5, 9, 2, 6, 0, 5},
	{1, 2, 6, 5, 6, 7},
}

func main() {
	// возможно, в самом начале имеет смысл сделать отдельные проверки на тот случай, если в матрице 0 элементов или только 1 элемент

	fmt.Println("Here's the input:")
	prettyPrint(input)

	// создаём пустую матрицу-результат, равную по размерам входной матрице, в шарпе это может делаться как-то иначе
	output := make([][]int, len(input))
	for i := 0; i < len(output); i++ {
		output[i] = make([]int, len(input[0]))
	}

	// цикл по строкам
	for row := 0; row < len(input); row++ {
		// цикл по столбцам
		for column := 0; column < len(input[row]); column++ {
			// находим массив соседей элемента
			neighbours := findNeighboursHard(input, row, column)

			// если все соседи меньше, чем сам элемент, то в выхлоп проставляем единицу; иначе ноль
			if isNeighboursSmallerThanItem(input[row][column], neighbours) {
				output[row][column] = 1
			} else {
				output[row][column] = 0
			}
		}
	}

	fmt.Println("\nHere's the output:")
	prettyPrint(output)
}

// функция принимает число и массив его соседей; возвращает boolean, отвечающий на вопрос "являются ли все соседи меньше данного числа"
func isNeighboursSmallerThanItem(item int, neighbours []int) bool {
	for i := 0; i < len(neighbours); i++ {
		// сравниваем каждого соседа с числом; если хотя бы один сосед >=, то остальных можно не проверять, выходим с false
		if neighbours[i] >= item {
			return false
		}
	}
	// если дошли до конца и не вышли с false, значит все соседи меньше; возвращаем true
	return true
}

// функция принимает весь массив + индексы нужного элемента; возвращает массив соседей этого элемента
// аналогична функцииfindNeighboursEasy по результату, но чуть покороче и посложнее для понимания
func findNeighboursHard(arr [][]int, row int, column int) []int {
	var result []int
	width := len(arr[row]) // объявляем для удобства ширину матрицы
	height := len(arr)     // высота матрицы, по идее матрицы всегда квадратные, но так оно будет работать с любым двумерным массивом

	// ходим по квадрату 3х3 (от -1 до 1) вокруг нашего элемента
	for i := -1; i < 2; i++ {
		for j := -1; j < 2; j++ {
			// скипнем центральный элемент, потому что это не сосед, а сам айтем, для которого мы ищем соседа
			if i == 0 && j == 0 {
				continue
			}

			// скипнем несуществующих соседей, которые вылезают за массив горизонтально
			if row+i < 0 || row+i >= width {
				continue
			}

			// то же самое, только вертикально
			if column+j < 0 || column+j >= height {
				continue
			}

			// если дошли досюда, то всё ок, добавляем соседа в результат
			result = append(result, arr[row+i][column+j])
		}
	}

	return result
}

// функция принимает весь массив + индексы нужного элемента; возвращает массив соседей этого элемента
// аналогична findNeighboursHard по результату, но чуть более тупая, потому что все соседи вручную проверяются
func findNeighboursEasy(arr [][]int, row int, column int) []int {
	var result []int
	width := len(arr[row]) // объявляем для удобства ширину матрицы
	height := len(arr)     // высота матрицы, по идее матрицы всегда квадратные, но так оно будет работать с любым двумерным массивом

	// сначала проверим трёх верхних соседей, если они вообще существуют
	if row-1 >= 0 {
		// проверка на верхнего левого соседа, если он есть, то добавляем в массив соседей
		if column-1 >= 0 {
			result = append(result, arr[row-1][column-1])
		}

		// добавляем верхнего среднего соседа, он по прошлому условию (row-1 >= 0) всегда существует
		result = append(result, arr[row-1][column])

		// проверка на верхнего правого соседа, если он есть, то добавляем в массив соседей
		if column+1 < width {
			result = append(result, arr[row-1][column+1])
		}
	}

	// проверим, существует ли левый сосед, и добавим его в результат, если да
	if column-1 >= 0 {
		result = append(result, arr[row][column-1])
	}

	// проверим, существует ли правый сосед, и добавим его в результат, если да
	if column+1 < width {
		result = append(result, arr[row][column+1])
	}

	// теперь проверим трёх нижних соседей, если они вообще существуют; всё аналогично верхним соседям, только row+1
	if row+1 < height {
		if column-1 >= 0 {
			result = append(result, arr[row+1][column-1])
		}

		result = append(result, arr[row+1][column])

		if column+1 < width {
			result = append(result, arr[row+1][column+1])
		}
	}

	return result
}

// это просто функция для красивой печати матрицы в терминале, чтоб не всё в одну строчку
func prettyPrint(arr [][]int) {
	for row := range arr {
		for column := range arr[row] {
			fmt.Print(arr[row][column], " ")
		}
		fmt.Print("\n")
	}
}
Editor is loading...