Я был активен на различных сайтах по программированию более 4 лет и решил более тысячи различных задач, используя более 40 разных языков.
Если вы попытаетесь решить столько проблем, вы в конечном итоге наткнетесь на несколько, в которых просто найдете идеальное решение. Или, по крайней мере, решите его так элегантно, чтобы он оказался на вершине рейтинга.
Я решил собрать некоторые из моих самых популярных решений, где я также являюсь первоначальным автором, и ни у кого другого не было такого решения.
Судоку
Учитывая двумерный массив, представляющий судоку, проверьте, правильно ли оно решено:
Это мой любимый. Он простой, элегантный и выглядит очень очевидным, но, видимо, не так-то просто придумать.
Он просто делает именно то, что вы хотите:
- Возьмите каждую строку с
board
. - Возьмите каждый столбец с
(partition 9 (apply interleave board))
- Возьмите каждый квадрат с помощью
(map flatten (partition 3 (apply interleave (map #(partition 3 %) board))))
- Проверьте, равен ли каждый массив
1..9
при сортировке.
Шахматы
Вы получаете двумерный массив, представляющий шахматную доску. Выясните, находится ли белый король под шахом.
Решение Python:
is_check=lambda b:bool(__import__('re').search(r"♔(.{7}|.{11}|.{18}|.{20})♞|♞(.{7}|.{11}|.{18}|.{20})♔|♟(.{8}|.{10})♔|♔(.{9} )*.{9}[♛♜]|[♛♜](.{9} )*.{9}♔|[♛♜] *♔|♔ *[♛♜]|[♛♝]((.{8} )*.{8}|(.{10} )*.{10})♔|♔((.{8} )*.{8}|(.{10} )*.{10})[♛♝]","--".join(map(''.join,b))))
Красивый код не обязательно должен быть читабельным. Правильно? В то время я только что решил проблему проверки «крестики-нолики» с помощью регулярного выражения и решил, что могу использовать его и для решения более сложных задач. Я потратил слишком много времени на создание этого. И даже больше времени на попытки его максимально оптимизировать.
Но как это работает?
Это может показаться устрашающим, но на самом деле решение довольно элегантно и легко для понимания.
Если вы посмотрите на шахматную доску выше и посчитаете поля между пешкой и королем, вы получите 6:
[‘ ‘,’ ‘,’ ‘,’♟’,’1',’2',’3',’4'],
[‘5’,’6',’♔’,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘],
И если вы переместите пешку в левый верхний угол от короля, она станет 8.
[‘ ‘,’♟’,’1',’2',’3',’4',’5',’6'],
[‘7’,’8',’♔’,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘],
Теперь мы знаем, что король находится под шахом, если пешка находится на 8 или 6 полей слева от короля.
Однако это не работает, когда пешка находится в конце ряда.
[‘ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’♟’],
[‘1’,’2',’3',’4',’5',’6',’7',’8'],
[‘♔’,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘],
Мы можем решить эту проблему, добавив два тире в конец каждой строки, что сделает их 8 и 10.
[‘ ‘,’♟’,’1',’2',’3',’4',’5',’6',’-’,’-’],
[‘9’,’10',’♔’,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’-’,’-’],
Если пешка сейчас на конце, ничего страшного, так как между ними будет 12 полей.
[‘ ‘,’ ’,’ ',’ ',’ ',’ ',’ ',’♟',’-’,’-’],
[‘3’,’4',’5’,’6‘,’7‘,’8‘,’9‘,’10‘,’-’,’-’],
[‘♔‘,’ ’,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’ ’,’-’,’-’],
Теперь просто присоедините массивы к строке, и вы можете написать регулярное выражение для проверки: /♟(.{8}|.{10})♔/
Ладья
Аналогичный подход можно применить и с ладьей.
[‘ ‘,’ ’,’♜’,’1‘,’2‘,’3‘,’4‘,’5‘,’-’,’-’],
[‘8‘,’9’,’10‘,’11‘,’12‘,’13‘,’14‘,’15‘,’-’,’-’],
[‘18’,’19‘,’♔’,’ ‘,’ ‘,’ ‘,’ ‘,’ ‘,’-’,’-’],
Если между ними 9, 19, 29 .. квадратов - это проверка.
Но что, если между ними есть кусок, который блокирует проверку?
Нам просто нужно убедиться, что каждое 10-е поле между королем и ладьей является пустым.
/♜(.{9} )*.{9}♔/
или наоборот /♔(.{9} )*.{9}♜/
Вы можете экстраполировать эту идею, чтобы создать целое.
Как можно короче?
После написания вышеизложенного я сотрудничал с некоторыми другими пользователями, чтобы максимально свести его к минимуму, и мы получили это в рубине:
Должен любить регулярные выражения ❤️
Крестики-нолики
Вот мое решение крестики-нолики, которое вдохновило шахматное решение, оно возвращает -1 для незавершенной партии, 0 для ничьей, «X», когда X выигрывает, и «O», когда выигрывает O:
ticTacToeWinner=b=>(m=(b=b.map(e=>e.join("")).join("-")).match(/(X|O)((\1\1)|(.{4}\1){2}|(.{3}\1){2})/))?m[1]:/ /.test(b)?-1:0;
Математика
Оцените любое математическое выражение, содержащее () / * + -
. И вам явно не разрешено использовать eval
или аналогичные функции.
Пример: calc('123.45*(678.90 / (---2.5+ 11.5)-(80 -19) *33.25) / 20 + 11')
должен вернуть -12042.760875
Иногда написание самого нечитаемого кода приносит больше всего голосов 😄
Преобразование секунд в удобочитаемый формат
Превратите 242062374
в 7 years, 246 days, 15 hours, 32 minutes and 54 seconds
. Он должен быть грамматически правильным и не возвращать нули.
Мне это решение не очень нравится 🤷 Можете ли вы написать красивый код на Java? Тем не менее, это одно из моих самых популярных решений и решение этой проблемы, за которое проголосовали больше всего, так что, возможно, оно вам понравится. Он был написан, когда Java 8 был еще довольно новым, поэтому, возможно, он получил одобрение многих людей, все еще пишущих Java 7 (извините).
Обращение массива
Кто-то из SO спросил, как можно изменить массив в JS без использования reverse()
. Некоторые были немного сбиты с толку.
Фактор
В моем приключении, когда я решал задачи на 40 разных языках, Factor был, пожалуй, самым интересным.
Я бы не рекомендовал писать это в продакшене, но это довольно забавный язык, чтобы попробовать. Это было похоже на решение головоломки.
Вы можете понять, что это должно решить?