Всем привет!
Это не история успеха, но пару слов о себе я должен сказать.
Начал учить 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;
}
}
Получилось поместить код целиком:)
Не судите строго, в бущем будет лучше. На днях постараюсь еще интересную задачку найти и выложить:)
Благодарю вас за прочтение:)
Еще одна статья от меня: Создание "Магического квадрата"
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ