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

Підкорення CodeWars (Вирішуємо задачу 4kyu)

Стаття з групи Random UA
Всім привіт! Це не історія успіху, але кілька слів про себе я маю сказати. Підкорення CodeWars (Вирішуємо задачу 4kyu) - 1Почав вивчати Java у лютому цього року (звичайно ж на нашому улюбленому JavaRush ), і в якийсь момент зрозумів, що потрібно більше ЗОЛОТА практики. Таким чином я натрапив на CodeWars. Щоб там зареєструватися, ви повинні виконати тестове завдання, яке в лютому я успішно не зміг вирішити, проте повернувшись у квітні я пробив цю стіну. Всі починають з рангу в 8ку, найвищий 1ку. Коли я почав, відразу почав вирішувати 7kyu, що в мене успішно вийшло, потім за пару днів вирішив ще пару завдань рангів 6ky -7kyu і одне 5kyu. Таким чином, успішно отримав 6kyu. І тут почалося .... Я захотів піднятися вище, проте завдання 5-3kyu, підвищують свою складність в якійсь геометричній прогресії (про 1 і 2 розмов взагалі немає). Однак я продовжував у результаті прорішував парочку 5, 4 і одну 3 стрибнув на ранг 5kyu, де зараз і сиджу. PS найприємніше на 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;
    }
}
Вийшло помістити код цілком:) Не судіть суворо, в майбутньому буде краще. Днями постараюся ще цікаве завдання знайти та викласти:) Дякую вам за прочитання:) Ще одна стаття від мене: Створення "Магічного квадрата"
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ