Алиса - стажер в компании, которая использует Brainfuck в качестве основного языка как для разработки на стороне клиента, так и на стороне сервера. Алиса только что написала свой первый код, и она немного нервничает, готовясь к своему первому обзору кода.
Алиса хочет, чтобы ее код был правильно отформатирован и выглядел красиво, но у нее нет времени, чтобы прочитать руководство по стилю кода компании на 328 страниц, поэтому она решила отформатировать его как идеальный квадрат . Увы, длины кода может быть недостаточно для формирования квадрата, поэтому она решила оставить прямоугольный пробел в середине. Разрывы должны быть идеально отцентрированы и как можно ближе к квадрату .
Примеры
++++++ +++++ +++++ +++++ +++++ +++++
++++++ +++++ +++++ + ++ ++ ++ +++++
++++++ ++ ++ + + + ++ + +
++++++ +++++ +++++ +++++ ++ ++ +++++
++++++ +++++ +++++ +++++ +++++ +++++
Perfect OK Acceptable Unacceptable No way! Nope.
Напишите программу или функцию, чтобы помочь Алисе. Учитывая код Алисы в качестве входной строки, выведите правильно отформатированный код, как описано ниже, если это возможно. Если форматирование невозможно, выведите плачущие смайлики :~(
.
Это код-гольф, поэтому ответы оцениваются в байтах, а целью является меньшее количество байтов.
Ограничения
- Ваша программа или функция должна принимать одну строку в качестве входных данных и выводить одну или несколько строк текста (или возвращать многострочную строку или массив строк, если вы реализуете функцию).
- Входная строка может содержать любые символы ASCII, включая пробелы.
- Все пробелы во входных данных должны игнорироваться. Они не должны учитывать длину кода и не должны использоваться в выводе.
- Входная строка содержит хотя бы один непробельный символ.
- Отформатированный код должен иметь те же непробельные символы в том же порядке, что и во входном коде.
- Форматированный код должен быть идеальным квадратом, то есть все строки должны иметь одинаковую длину, а количество строк должно быть равно длине строк.
- Отформатированный код может содержать пробел в середине.
- В пробеле можно использовать только пробелы (код ASCII 32).
- Разрыв (если имеется) должен быть прямоугольным.
- Каждая строка отформатированного кода должна содержать хотя бы один непробельный символ, т.е. ширина зазора должна быть строго меньше ширины квадрата (зазор 5x1 недопустим для квадрата 5x5).
- Зазор должен быть горизонтальным, то есть ширина зазора должна быть больше или равна высоте зазора.
- Разрыв должен быть идеально отцентрирован.
- Следовательно, четность ширины и высоты зазора должна быть такой же, как четность ширины квадрата (например, для зазора 5x5 может быть 1x1, 3x1 или 3x3).
- Если возможно, выведите квадрат без зазора.
- В случае нескольких решений выберите одно с зазором, ближайшим к квадрату, т. Е. Разница между шириной и высотой зазора минимальна (например: зазор 10x10 предпочтительнее, чем 8x6, и 8x6 предпочтительнее, чем 6x2).
- Если все еще есть связь, выберите решение с минимальной площадью зазора (например, зазор 2x2 предпочтительнее, чем 4x4).
- Если вообще невозможно отформатировать код, выведите
:~(
. - Новая строка после последней строки необязательна.
- [Новое] Вы можете смело предположить, что любой символ с кодом ниже 33 является пробелом. Я надеюсь, что это поможет вам для игры в гольф.
тесты
Input Output Code length Comment
+++++++++ +++ 9 Alice is lucky,
+++ her code perfectly fits a square.
+++
++++++++ +++ 8 Though code length isn't enough for a square,
+ + a small gap fixes it.
+++
++++++ :~( 6 No luck, code cannot be formatted.
Hello, Hell 12 Input may contain any ASCII characters,
World! o , but whitespaces in input should be ignored.
W o
rld!
+++++ + +++++ +++++ 22 Gap is not required to be a square,
+++++ + +++++ +++++ it can be a rectangle.
+ +
+++++
+++++
+++ + +++ ++++++++ 28 There exists another solution:
+++ + +++ + + 6x6 square with 4x2 gap,
+++ + +++ + + but in Alice's opinion square gap
+++ + +++ + + makes code more readable.
+ +
+ +
+ +
++++++++
Хитрые тесты
This must be Thism 24 7x7 with 5x5 gap looks good,
5x5 with 1x1 ustbe but 5x5 with 1x1 gap is better,
gap. 5x 5w because gap area is smaller.
ith1x
1gap.
+++ +++ +++ :~( 18 In case you tried 5x5 square
+++ +++ +++ with 7x1 gap ;)
Ресурсы
Для экономии места вы можете найти образец кода и дополнительные тестовые примеры на tio.run
[Новое] Вы можете взглянуть на таблицу принятых решений для ввода длиной до 100 символов . Я поменял местами ширину и высоту, потому что это выглядит более интуитивно.
Вдохновлен: квадрат текста
изменения
Добавлено 2 теста, исправлена ошибка в примере кода.
Добавлена таблица решений до 100, добавлено уточнение пробелов.
Ответы:
C (gcc) , 354 байта
Попробуйте онлайн!
источник
isspace(x)
наx<33
.JavaScript (ES6),
284 ... 274270 байтСохранено 4 байта благодаря @Shaggy
Возвращает массив строк.
Попробуйте онлайн!
источник
This must be 5x5 with 1x1 gap.
(24 символа)[\s\n]
быть просто\s
?++w>x-2
w++>=x-2
w++>=x
\s
Stax , 80 байт
Запустите и отладьте его
Как это работает?
Распаковано, разглажено и прокомментировано это выглядит так.
Запустите этот
источник
Древесный уголь , 120 байт
Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:
Удалите пробелы из входных данных, затем переверните их и разделите на символы, чтобы позже мы могли более легко зацикливать символы.
Начните с размера ноль, указывая, что результат не найден (пока).
Проверьте все длины сторон до длины строки. (Добавление деления, конечно, сделает код быстрее.)
Если в результате получится идеальный квадрат, сохраните размер квадрата и установите его в качестве размера границы.
Обведите все возможные значения высоты и ширины границы (ширина границы не превышает высоту границы, поэтому высота зазора не превышает ширину зазора).
Если размер границы - желаемая длина, и у нас пока нет решения, или оно не такое квадратное, как это решение, то обновите решение с помощью этого квадрата и размеров границы.
Если у нас есть решение ...
Нарисуйте прямоугольник произвольного символа с заданным размером квадрата.
Если граница достаточно мала, чтобы оставить зазор, стереть зазор. (Команда рисования будет рисовать вверх и влево для отрицательных значений и вообще не любит нулевые значения.)
Замените все (оставшиеся) символы на символы из ввода.
В противном случае вывод
:~(
.источник
Желе ,
9185 байтПопробуйте онлайн!
Монадическая ссылка, которая принимает входную строку в качестве аргумента и возвращает строку либо с форматированным выводом, либо
:~(
.источник
Python 2,
287281279 байтПопробуйте онлайн!
Использует сравнение лексикографического списка Python, используя одинаковые значения как для выбора решения, так и для его печати. Я уверен, что
1042 или около того байта все еще можно сбрить.объяснение
Удалите пробелы, разделив их пробелами и присоединившись к ним
""
, а затем преобразуйте входные данные в список для дальнейшего использования. Также инициализируйтеl
для длины фактического кода иp
для списка допустимых возможностей.Переберите все возможности размеров зазора от
0*0
доl*l
. Вычислить длину ребра квадрата с помощьюl
символов кода иx*y
пробелов какs
.Проверьте, соответствуют ли следующие условия:
s % 1 == 0
т.е. будет сформирован идеальный квадратx < s-1 > y
то естьx
иy
находятся не болееs-2
и вписываются в квадратs % 2 == x % 2 == y % 2
т. е. обаx
иy
соответствуют четности края и могут быть центрированыx < 1
, т.е.x == 0
игнорировать все, кроме требования идеального квадратаЕсли условия совпадают, добавьте следующие элементы в кортеж,
p
чтобы найти оптимальный:abs(x-y)/2
; сначала найдите минимальную разницуx
иy
получите самый квадратный разрыв. Это всегда даже так, мы делим на 2.int(s)
; затем найдите минимальную длину стороны. Такs
как является целым числом и увеличивается как область разрываx*y
, это сортирует по области разрыва.-x
; Затем найдите максимальную ширину, чтобы предпочесть горизонтальные промежутки. Это происходит после области из-за того, как она была разработана, но область такая же,x*y
иy*x
поэтому она работает.Если мы нашли какие-либо допустимые макеты, найдите оптимальный, как описано выше. Вычислите горизонтальную границу
b
и инициализируйте номер строкиY
в 0.Если номер строки
Y
находится внутри пробела (вертикальная граница -b+d
сd
кортежем), добавьте значение ширины пробела после горизонтальной границы вc
. (Модификацияc
- это то, почему нам нужно, чтобы это был список.) Затем выведите линию квадрата и удалите ее изc
. Повторитеs
время, увеличивая номер строки.Если макеты не найдены, произойдет сбой.
источник
"some\ntext"
разделителем. (input()
оценивает строку ввода как код Python.) Если это не приемлемо, пожалуйста, дайте мне знать. Длина 22 также работает для меня.Pyth ,
9998 байтовПопробуйте онлайн!
При этом используется тот же алгоритм, что и в моем ответе на Python, но многие детали значительно изменены, чтобы быть короче в Pyth.
Здесь Pyth показывает свой возраст, поскольку он не обновлялся годами и использует только печатаемые символы ASCII (для кода, а не для данных), тратя много места.
Интересно, что если бы Pyth использовал тот же тип упаковки 256, что и Stax, эта программа могла бы иметь размер log98 log 256 95 81 = 81 байт, в непосредственной близости от Stax (80 байт) и Jelly (85 байт). Я думаю, что это хорошо показывает, насколько близки языки игры в гольф даже с их совершенно разными парадигмами.
Объяснение (только немного менее нечитаемо, чем код)
#
оборачивает все в,while True:
что подавляет сообщение и выходит из-за ошибки.JscQ)
c
вход хмеля (Q
s
выполняет прыжок ) в пустом месте, объединяет части и сохраняет результат вJ
.^UJ2
составляет список индексов (U
)J
и принимает его2
декартову степень (^
), в результате чего все пары[h,w]
с0<=h<len(J)
и0<=w<len(J)
.+L@+lJ*Fd
: для всех (L
) таких парd
добавляет (+
) квадратный корень (@
…2
) из (l
длинаJ
плюс (+
) продукта (*F
) парыd
) к левой стороне пары, создавая триплет[side length, gap height, gap width]
.f!|%hT1&eT|t{%R2TgeStThT
:f
ilter для тройниT
где!|
):hT
) по модулю 1 (%
…1
) не равна нулю&
):eT
) не равна нулю|
):R
) по модулю 2 (%
…2
) с дубликатами ({
t
удаленными ) и первым уникальным ( ) непустоeS
) высоты зазора и ширины зазора (tT
) большеg
или равно длине стороны (hT
)S
сортирует триплеты лексикографически (по длине стороны, затем по высоте зазора).oaFtN
затемo
вычисляет тройки поa
абсолютной разнице между высотой зазора и шириной зазора (tN
).В этот момент, если у нас нет действительных решений,
|
оценивается его второй аргумент\n":~("
, который печатает и возвращает:~(
.h
принимает оптимальное решение (или,":"
если его нет), и оно сохраняется вK
. Затемh
принимает длину стороны (или,":"
если ее нет),s
преобразует ее в целое число (или терпит неудачу и завершает работу, если ее нет), и она сохраняется (=
) вQ
.Затем каждое из (
m
)[gap height, gap width]
(tK
) вычитается (-
) из длины стороны (Q
), а результат делится на 2 (/
…2
). РезультатыA
подписаны наG
иH
.Наконец, мы входим в
W
петлю.Z
начинается с 0 и каждую итерацию мы увеличиваем, но используем старое значение (~hZ
подумайтеZ++
на С).W
) старое значение находится в ({
)r
angeG
to (side length -G
) (-QG
), присвойте (=
)J
следующее:c
переходитеJ
в position (]
)H
иj
разбейте половинки с шириной промежуткаeK
times (*
) a space (d
). Если значение не было в диапазоне, просто вернитеJ
. Если этот результат пуст, остановите цикл.>
) первыеQ
символы изJ
и назначьте (~
) результатJ
. Из старого значенияJ
возьмите (<
) первыеQ
символы и напечатайте их.Наконец,
#
цикл начинается снова, ошибки и выход, потому чтоcQ)
сQ
содержащим число недопустимо.источник
05AB1E ,
9589 байтНесколько байтов здесь и там определенно можно сыграть в гольф.
Первые три шага программы навеяны ответом Stax от @recursive , так что постарайтесь поддержать его!
Попробуйте онлайн или проверьте все контрольные примеры .
Объяснение:
Шаг 1: Удалите все пробелы:
Шаг 2: Создайте все возможные триплеты[ а , б , в ] , где a это размер результирующего а × а квадрат и б × с это размер разрыва. Мы делаем это, создавая все возможные триплеты, используя целые числа в диапазоне[ 0 , a ] , И затем мы фильтруем их, где все следующее верно для триплета:
Например:L = 28 приведет к тройняшкам
[[6,2,4],[6,4,2],[8,6,6]]
.Шаг 3: Проверьте, остались ли еще триплеты. Если нет, вывод( a b s ( b - c ) , b × c ) ,
":~("
; если мы это сделаем, определите, какой использовать, сортируя и оставляя только первое. Мы делаем это путем сортировки кортежейНапример: тройки
[[6,2,4],[6,4,2],[8,6,6]]
будут отсортированы[[8,6,6],[6,2,4],[6,4,2]]
, после чего останутся только[8,6,6]
.Шаг 4: Создайте список того, как мы должны разделить строку, чтобы вставить пробелы. Это делается так:
Данный[ а , б , в ] создайте список с помощью:
Например: триплет
[7,3,5]
приведет к появлению списка[15,2,2,35]
.Шаг 5: И, наконец, мы разбиваем строку на основе этого списка, соединяем его вместе сс количество пробелов, разбить его на части размера с и присоединяйся к ним вместе с помощью новых строк. Например:
Строкас = 5 количество мест до а = 7 к этому:
"Alongtesttoseeifitworksasintended."
разделена в соответствии со списком[15,2,2,35]
приведет к:["Alongtesttoseei","fi","tw","orksasintended."]
. Затем к нему присоединяются"Alongtesttoseei fi tw orksasintended."
. А затем разделить на части размера["Alongte","sttosee","i f","i t","w o","rksasin","tended."]
. К которому затем добавляются новые строки для вывода.источник