Заполнение матрицы определенным шаблоном

Итак, у меня есть матрица с одинаковыми размерами, которая определяется следующим образом:

public void InitPositionsGrid()
    {
        int munberOfRows = 6;
        for(int i = 0; i < munberOfRows; i++)
        {
            if ( i % 2 == 0)
            {
                GridPositions[i] = new int[15];
            }
            else
            {
                GridPositions[i] = new int[14];
            }
        }
    }

Теперь мне нужен метод (рекурсивный или итеративный - что угодно), который будет заполнять эту матрицу, но с определенным шаблоном, чтобы она была равномерной во всех направлениях. Предполагается, что метод принимает 3 параметра, X и Y, которые определяют начальную позицию, и еще один, количество мест, которые необходимо заполнить. Должно выглядеть примерно так:

public void FillGridMatrix(int startingRow, int startingColumn, int numberOfPlacesToFill)
{
    //Fill the matrix with the following algorithm but don't go out of bounds
}

Вот картинка, показывающая пример алгоритма:

Заполнение матрицы определенным шаблоном

Идея такова: начните с текущего начального места, отметьте два пробела «выше» (должны быть x-1, y-1 и x-1, y), проверьте два смежных пробела (x, y-1 и x, y + 1) и, наконец, отметьте два пробела «снизу» (x + 1, y-1 и x + 1, y). Координаты могут быть не совсем такими, но это общая идея. Обратите внимание: когда больше нет места «вверху» или «внизу», места для заполнения должны быть одинаково слева и справа. Начальный ряд никогда не может быть ни первым, ни последним. Если место, которое в настоящее время проверяется, уже отмечено, пропустите это место. Максимальное количество мест для заполнения может быть 87, как и максимальное количество элементов в самой матрице. После первого раунда, если необходимо заполнить более 7 мест, алгоритм начинается с верхнего левого угла и заканчивается нижним правым «соседним» элементом из начальной позиции (2 и 7 в этом примере).

Есть идеи, какое лучшее решение для этого? C# предпочтительнее.

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

public int PopulateMatrixAroundCertainPosition(int[][] matrix, int row, int column, int availableNumbers)
    {
        if (availableNumbers <= 0)
        {
            return 0;
        }
        matrix[row][column] = 1;
        availableNumbers = PopulateSingleMatrixPosition(matrix, row - 1, column - 1, availableNumbers - 1);
        availableNumbers = PopulateSingleMatrixPosition(matrix, row - 1, column, availableNumbers - 1);
        availableNumbers = PopulateSingleMatrixPosition(matrix, row, column - 1, availableNumbers - 1);
        availableNumbers = PopulateSingleMatrixPosition(matrix, row, column + 1, availableNumbers - 1);
        availableNumbers = PopulateSingleMatrixPosition(matrix, row + 1, column - 1, availableNumbers - 1);
        availableNumbers = PopulateSingleMatrixPosition(matrix, row + 1, column, availableNumbers - 1);
        return availableNumbers - 1;
    }

    public int PopulateSingleMatrixPosition(int[][] matrix, int row, int column, int availableNumbers)
    {
        if (availableNumbers <= 0)
        {
            return 0;
        }
        if (matrix[row][column] == 1)
        {
            return availableNumbers + 1;
        }
        matrix[row][column] = 1;
        return availableNumbers;
    }

Попытайтесь решить эту проблему и задайте конкретный вопрос. Кажется, вы понимаете логику в том виде, в котором вы ее написали, поэтому попробуйте преобразовать ее в код. В противном случае кажется, что вы просите сообщество написать за вас ваш код, а SO не в этом.

Rufus L 06.08.2018 23:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
118
1

Ответы 1

Никакой рекурсии не требуется. Просто продолжайте строить внутреннюю структуру. Я создал небольшой конечный автомат для решения головоломки:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        const int TOTAL_BUTTONS = 61;
        const int BUTTON_SIZE = 40;
        const int SPACE = 10;
        public Form1()
        {
            InitializeComponent();
            BuildMatrix();
        }
        public enum LOCATION
        {
            TOP_ROW,
            LEFT_BUTTON,
            RIGHT_BUTTON,
            BOTTOM_ROW
        }

        List<List<Button>> matrix = new List<List<Button>>();
        int numberButtons = 0;
        public void BuildMatrix()
        {
            int centerX = 0;
            int centerY = 0;

            int loopCounter = 1; //count of number of loops around matrix  

            int numberRows = 0;
            int rowCount = 0;
            int columnCount = 0;
            centerX = this.Width / 2;
            centerY = this.Height / 2;

            LOCATION location = LOCATION.TOP_ROW;
            List<Button> newRow = new List<Button>();
            Button newButton = null;
            Button buttonLeft = null;
            for (int buttonCount = 0; buttonCount < TOTAL_BUTTONS; buttonCount++)
            {
                switch (location)
                {
                    case LOCATION.TOP_ROW :
                        if (columnCount == 0)
                        {
                            newRow = new List<Button>();
                            if (numberRows++ == 0)
                            {
                                matrix.Add(newRow);
                                newButton = AddButton(centerY - (BUTTON_SIZE / 2), centerX - (BUTTON_SIZE / 2));
                                //add first button
                                newRow.Add(newButton);
                                loopCounter++;
                                continue;
                            }
                            else
                            {
                                matrix.Insert(0, newRow);
                                Button buttonDownRight = matrix[1][columnCount];
                                newButton = AddButton(buttonDownRight.Top - SPACE - BUTTON_SIZE, buttonDownRight.Left - ((SPACE + BUTTON_SIZE) / 2));
                            }
                        }
                        else
                        {
                            buttonLeft = matrix[rowCount][columnCount - 1];
                            newButton = AddButton(buttonLeft.Top, buttonLeft.Left + SPACE + BUTTON_SIZE);
                        }
                        //put new button above button below, move up one row, move left half column
                        newRow.Add(newButton);

                        if (++columnCount == loopCounter)
                        {
                            location = LOCATION.LEFT_BUTTON;
                            rowCount++;
                        }
                        break;

                    case LOCATION.LEFT_BUTTON :
                        Button buttonRight = matrix[rowCount][0];
                        newButton = AddButton(buttonRight.Top, buttonRight.Left - SPACE - BUTTON_SIZE);
                        matrix[rowCount].Insert(0, newButton);
                        location = LOCATION.RIGHT_BUTTON;
                        break;

                    case LOCATION.RIGHT_BUTTON :
                        buttonLeft = matrix[rowCount][matrix[rowCount].Count - 1];
                        newButton = AddButton(buttonLeft.Top, buttonLeft.Left + SPACE + BUTTON_SIZE);
                        matrix[rowCount].Add(newButton);
                        rowCount++;
                        if (rowCount >= numberRows)
                        {
                            location = LOCATION.BOTTOM_ROW;
                        }
                        else
                        {
                            location = LOCATION.LEFT_BUTTON;
                        }
                        columnCount = 0;
                        break;

                    case LOCATION.BOTTOM_ROW :
                        if (columnCount == 0)
                        {
                            newRow = new List<Button>();
                            matrix.Add(newRow);
                            numberRows++;
                        }
                        Button buttonTopLeft = matrix[rowCount - 1][columnCount];
                        newButton = AddButton(buttonTopLeft.Top + SPACE + BUTTON_SIZE, buttonTopLeft.Left + ((SPACE + BUTTON_SIZE) / 2));
                        matrix[rowCount].Add(newButton);
                        if (++columnCount == loopCounter)
                        {
                            location = LOCATION.TOP_ROW;
                            columnCount = 0;
                            rowCount = 0;
                            loopCounter++;
                        }


                        break;

                }
            }

        }
        public Button AddButton(int top, int left)
        {
            Button newButton = new Button();
            newButton.Width = BUTTON_SIZE;
            newButton.Height = BUTTON_SIZE;
            newButton.Top = top ;
            newButton.Left = left;
            numberButtons++;
            newButton.Text = numberButtons.ToString();
            this.Controls.Add(newButton);

            return newButton;
        }
    }
}

Другие вопросы по теме