JavaRush /Java блог /Random /Покорение CodeWars (Решаем задачу 4kyu)
Сергей Цехмистренко
15 уровень
Минск

Покорение CodeWars (Решаем задачу 4kyu)

Статья из группы Random
Всем привет! Это не история успеха, но пару слов о себе я должен сказать. Покорение CodeWars (Решаем задачу 4kyu) - 1Начал учить Java в феврале этого года (конечно же на нашем любимом JavaRush), и в какой-то момент понял, что нужно больше ЗОЛОТА практики. Таким образом я наткнулся на CodeWars. Чтобы там зарегистрироваться вы должны выполнить тестовое задание, которое в феврале я успешно не смог решить, однако вернувшись в апреле я пробил эту стену. Все начинают с ранга в 8kyu, самый высокий 1kyu. Когда я начал, сразу начал решать 7kyu, что у меня успешно получилось, потом за пару дней решил еще пару заданий рангов 6kyu -7kyu и одно 5kyu. Таким образом успешно получил 6kyu. И тут началось.... Я захотел подняться выше, однако задания 5-3kyu, повышают свою сложность в какой-то геометрической прогрессии (про 1 и 2 разговоров вообще нет😬). Однако я продолжал в итоге прорешав парочку 5, 4 и одну 3 прыгнул на ранг 5kyu, где сейчас и сижу. P.S. самое приятное на CodeWars это то, что после решения задания ты можешь посмотреть как его решали другие (а там ребята жесткие сидят). В общем попробуйте. Ссылку давать не буду, подумают что реклама) Переходим к десерту, решим интересную задачу 4Kyu (хотя я бы ее оценил как 5kyu). Условие: Все знают про игру судоку, где матрицу 9x9 мы должны заполнить числами от 1 до 9. При этом в каждой строке и столбце цифры не должны повторяться, а также цифры не должны повторяться в квадратах 3х3 (Загляните в википедию:))/ Мы должны написать метод, который будет проверять матрицу на правильность заполнения в случае чего возращать true. Если в матрице есть 0, то данный элемент считается незаполненным, соответственно false. (Ссылку на эту кату, задачу могу скинуть в лс) Решение: Решение придется разбить на три блока иначе, код отобразиться не коректно (научен горьким опытом)

public class SudokuSolutionValidator {
    public static void main(String[] args) {
        int[][] matrix = {
                        {5, 3, 4,  6, 7, 8,  9, 1, 2},
                        {6, 7, 2,  1, 9, 5,  3, 4, 8},
                        {1, 9, 8,  3, 4, 2,  5, 6, 7},
                        {8, 5, 9,  7, 6, 1,  4, 2, 3},
                        {4, 2, 6,  8, 5, 3,  7, 9, 1},
                        {7, 1, 3,  9, 2, 4,  8, 5, 6},
                        {9, 6, 1,  5, 3, 7,  2, 8, 4},
                        {2, 8, 7,  4, 1, 9,  6, 3, 5},
                        {3, 4, 5,  2, 8, 6,  1, 7, 9}};
        System.out.println(validSolution(matrix));
    }

    public static boolean validSolution(int[][] matrix) {
//  Проверяем нашу матрицу на наличие 0
        for (int[] array : matrix) {
            for (int element : array) {
                if (element == 0) return false;
            }
        }
        if ((checkVerticalAndHorizontal(matrix))&&(check3v3squares(matrix)))
            return true;
        else return false;
    }

//   В методе checkVerticalAndHorizontal() проверим на правильность заполнения
//   наши строки и столбцы
    private static boolean checkVerticalAndHorizontal (int[][] matrix) {

//  4 переменные, предназначение которых вы узнает ниже)
        int vertical = 0;
        int horizontal = 0;
        int horizontalCount = 0;
        int verticalCount = 0;

        for (int i = 0; i < 9; i++) {
            for (int j = 1; j < 10; j++) {

                for (int k = 0; k < 9; k++) {
                    if (matrix[i][k] == j) {
                        horizontalCount++;
//  В данном случае, мы проверяли наличие повторов в строках,
//  Если вы уберете break (выход из цикла "k"), и раскомментируйте
//  код ниже, вы увидите какого числа не хватает, а какой элемент дублируется дважды и более
//  System.out.println("matrix[i][k] = " + matrix[i][k] + "значение элемента = " + j+"_______"+ "индекс элемента в строке "+k);
                        break;
                    }
                }


                for (int k = 0; k < 9; k++) {
//  А тут проверяем столбцы. Как вы понимаете, наличие
//  ошибки в строке свидетельствует об ошибке в столбце :D
                    if (matrix[k][i] == j) {
                        verticalCount++;
//              элемент совпал +, элемент не совпал 0.
//              еще раз повторюсь, break нужен для того, чтобы не ловить повторы.
                        break;
                    }
                }
//  Далее закомментирована метка, которая служит навигатором по циклам
//               System.out.println("______________________");

            }
            if (horizontalCount == 9) horizontal++;
            if (verticalCount == 9) vertical++;
            horizontalCount = 0;
            verticalCount = 0;
//  Две конструкции if выше как раз и реализуют мою основную идею проверки столбцов и строк,
//  а именно при переборе всех значений (от 1 до 9) в циклах k мы проверям соответствует ли
//  строка и столбец заданному условию или нет.
        }
//  если наши переменные vertical и horizontal равны 9 каждая,
//  значит со столбцами и строками проблем нет.
        if ((vertical == 9)&&(horizontal==9)) return true;
        else return false;
    }

//  В методе check3v3squares() переходим к сладкому, проверка квадратов 3на3
    private static boolean check3v3squares(int[][] matrix) {

        int transitionDown = 0;
        int transitionRight = 0;
        int lastCount = 0;
//  По квадратам будем двигаться вниз, дойдя до низа на шаг влево.
//  По достижению правого нижнего квадрата выходим из цикла. ( в сумме 9 квадратов (3на3), соответственно
//  внешний круг должен содержать 9 итераций)

        for ( int x = 0; x<9; x++) {
            if(transitionDown == 9) {
                transitionRight +=3;
                transitionDown = 0;
            }
//  В циклах ниже я реализовали движение по квадратам 3х3 и их проверку.
//  Переменная key нужна для того, чтобы избежать повторной проверки одного
//  и того же числа (тоесть при наличии 2 одинаковых чисел, мы увеличиваем счетчик на 1, а не 2)
            for (int k = 1; k < 10; k++) {
                int key = 0;
                for (int i = 0; i < 3; i++) {
                        for (int j = 0; j < 3; j++) {
                        if ((k == matrix[i+transitionDown][j+transitionRight])&&(key!=k)) {
                            lastCount++;
                            key = k;
                        }
                    }
                }
            }
            transitionDown += 3;
        }
//  Счетчик lastCount должен вернуть число 81, если оно меньше, то не обошлось без повторов
        if(lastCount == 81) return true;
        else return false;
    }
}

Получилось поместить код целиком:) Не судите строго, в бущем будет лучше. На днях постараюсь еще интересную задачку найти и выложить:) Благодарю вас за прочтение:) Еще одна статья от меня: Создание "Магического квадрата"
Комментарии (8)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Zelimkhan Уровень 26
17 мая 2020
Какая же боль , эти матрицы)))
Islam Laipanov Уровень 30
17 мая 2020
пхахаха помню как решал эту же задачку на codewars на питоне, тогда у меня ушел целый день и +100 строчек кода, а потом оказалось, что парень решил то же самое за 14 строчек кода. это была боль...
Alukard Уровень 37 Expert
16 мая 2020
Спасибо, возьму на заметку🙃
контент 666 Уровень 2
16 мая 2020
спасибо, сохранил через пару месяцев попробую пробится , а пока под наберусь знании тут.