Это первый из серии испытаний Island Golf. Следующая задача
Учитывая остров в ASCII-искусстве, выведите оптимальный путь для его обхода.
вход
Ваш ввод будет прямоугольной сеткой, состоящей из двух символов, представляющих землю и воду. В приведенных ниже примерах земля есть, #
а вода есть .
, но вы можете заменить любые два разных символа по вашему желанию.
...........
...##......
..#####....
..#######..
.#########.
...#######.
...#####.#.
....####...
...........
Там всегда будет хотя бы одна плитка земли. Плитки земли все будут смежными (то есть есть только один остров). Водяные плитки также будут смежными (т.е. там нет озер). Внешняя граница сетки будет водяной плиткой. Плитки земли не будут связаны по диагонали: то есть вы никогда не увидите ничего подобного
....
.#..
..#.
....
Выход
Ваш код должен выводить ту же сетку с нарисованной кратчайшей круговой навигацией. В приведенных ниже примерах путь кругового плавания начертан o
, но вы можете заменить любого персонажа, если он отличается от ваших символов земли и воды.
Кругосветное является простой замкнутой кривой, составленный полностью на воде плитки, которая полностью окружает все наземные плитки на сетке. Диагональные соединения будут разрешены. Например, это кругосветное плавание над островом (но не самое короткое):
.ooooo.....
o..##.oo...
o.#####.o..
o.#######o.
o#########o
ooo#######o
..o#####.#o
..oo####..o
....oooooo.
Длина кругового плавания вычисляется следующим образом: для каждой пары соседних плиток на пути, если они соединены горизонтально или вертикально, добавьте 1; если они связаны по диагонали, добавьте √2. Длина указанного пути составляет 22 + 7√2 (≈ 31,9).
Самым коротким кругосветным плаванием является кругосветное плавание с наименьшей возможной длиной. Ваша программа должна выводить любой путь, который удовлетворяет этому условию. Для большинства островов будет несколько возможных решений. Вот одно решение для указанного острова длиной 10 + 13√2 (≈ 28,4):
...oo......
..o##oo....
.o#####oo..
.o#######o.
o#########o
.o.#######o
..o#####.#o
...o####.o.
....ooooo..
Детали
Ваше решение может быть полной программой или функцией . Любой из методов ввода и вывода по умолчанию является приемлемым.
Ваш ввод и вывод может быть многострочной строкой или списком строк. Если ваш язык имеет символьный тип, отличный от односимвольных строк, вы можете заменить «список символов» на «строку» в предыдущем предложении. Если вашему языку нужно ввести высоту и / или ширину сетки, вы можете сделать это. Ваш вывод может (опционально) иметь один завершающий перевод строки. Как упоминалось выше, вы можете использовать любые три различных символа вместо #.o
(пожалуйста, укажите в своем представлении, какие символы вы используете).
Контрольные примеры
А. Острова с уникальными кратчайшими кругосветными плаваниями:
...
.#.
...
.o.
o#o
.o.
......
.####.
......
.oooo.
o####o
.oooo.
......
......
..##..
...#..
......
......
......
..oo..
.o##o.
..o#o.
...o..
......
.......
.#####.
...#...
...#...
.#####.
.......
.ooooo.
o#####o
o..#..o
o..#..o
o#####o
.ooooo.
.......
...#...
...#...
.#####.
...#...
...#...
.......
...o...
..o#o..
.o.#.o.
o#####o
.o.#.o.
..o#o..
...o...
.......
.#####.
.##..#.
..#..#.
.......
.ooooo.
o#####o
o##..#o
.o#..#o
..oooo.
Б. Пример острова с несколькими возможными решениями:
........
....##..
...####.
..###...
.#####..
.#####..
..##....
........
Возможные выводы:
....oo..
...o##o.
..o####o
.o###.o.
o#####o.
o#####o.
.o##oo..
..oo....
....oo..
...o##o.
..o####o
.o###.o.
o#####o.
o#####o.
.o##.o..
..ooo...
....oo..
...o##o.
..o####o
.o###..o
o#####.o
o#####o.
.o##oo..
..oo....
....oo..
...o##o.
..o####o
.o###..o
o#####.o
o#####o.
.o##.o..
..ooo...
Это код-гольф : выигрывает самый короткий код на каждом языке.
Ответы:
Mathematica (версия 9), 165 байт
Хорошая, короткая
ConvexHullMesh
функция, которую использовал Грег Мартин, была представлена только в Mathematica версии 10, поэтому я решил сделать попытку без нее, используя мою древнюю версию Mathematica 9. Хотя мне удалось немного ее сократить! Это функция , которая принимает и возвращает список строк (с.
,#
и ,o
как и символы).Объяснение:
Characters@# /. {"."->0, "#"->1}
превращает вход в матрицу0
s и1
s."o"MorphologicalTransform[MorphologicalComponents[#,Method->"ConvexHull"],Max[#(1-#[[2,2]])CrossMatrix@1]&]+"#"#
затем использует мощные (но чрезвычайно байтно…) возможности обработки изображений Mathematica, чтобы сначала заполнить выпуклый корпус острова (именно такую форму вы получите, если протянете кусок веревки вокруг него), а затем взять его границу. Затем мы умножаем эту матрицу на строку,"o"
чтобы получить матрицу0
s и"o"
s (благодаря впечатляющей адаптируемости Mathematica в отношении типов), и добавляем это к"#"
временам матрицы острова.""<>#& /@ (... /. {0->"."})
превращает эту матрицу"o"
s,"#"
s и0
s в матрицу"o"
s,"#"
s и"."
s и объединяет каждую строку в строку.Когда мы проверяем это на примере B , мы получаем вывод
[Редактировать, спасибо Грегу Мартину:] Если нам разрешено использовать массивы символов вместо списков строк, мы можем сократить это до 144 байт:
источник
MorphologicalComponents[#, Method->"ConvexHull"]
:) Вы можете сохранить еще больше байтов, предполагая, что ввод уже разделен на символы, а также возвращая двумерный массив символов.MorphologicalComponents
до сегодняшнего дня!f[{"...",".#.","..."}]
и получил некоторые ошибки.f
. (Ну, строго говоря, это вещи после точки с запятой.) Чтобы вызвать функцию, введите всю эту вещь в окно Mathematica, а затем[
свой ввод и]
, таким образом, он должен выглядеть примерно такf@m_:=m(1-m[[2,2]]) . . . #/.{"."->0,"#"->1}]&[{"...", ".#.", "..."}]
(сокращенно для пробела).(Но идите на голосование против Нотри , лучше!)
Mathematica, 168 байт
Чистая функция, принимающая двумерный массив символов в качестве входных данных и возвращающая двумерный массив символов. Более удобная для чтения версия:
Линия 1 определяет функцию,
n
которая создает (наименьшее) расстояние между точкойx
на плоскости и наборомy
других точек. Строка 2 инициализирует переменнуюi
для ввода, чтобы как позже разрешить неоднозначность каррирования, так и иметь возможность изменить ее для получения конечного результата; Строка 2 также определяет функцию,p
которая возвращает координаты всех вхождений своего ввода вi
.В строке 3
p["#" | "."]
представляет каждую отдельную координату из входной карты (поскольку все ее символы либо либо,"#"
либо"."
), такt
же как и функция, которая выбирает только те координаты, которые удовлетворяют пока неопределенному свойству. В строке 4i~Part~## = "o"
будет изменено несколько записейi
символа"o"
; эти символы будут выбраны из набора возможных координат в соответствии с материалом в строках 5-8. И строка 9 просто возвращает ответ, как только он вычислен.Хорошо, инфраструктура сделана, теперь к фактическим вычислениям.
ConvexHullMesh
является встроенным в Mathematica для вычисления выпуклой оболочки набора точек (самый маленький выпуклый многоугольник, содержащий эти точки). С моральной точки зрения это должно «заполнить» бухты и фьорды острова (то естьs = p@"#"
), чтобы исключить их из нашего кругосветного плавания. Есть небольшая проблема,ConvexHullMesh
когда этот набор точек находится в одной строке (спасибо, тестовый пример № 2), которую мы решаем, добавляя слегка смещенную версиюs
к себе в строке 7. Этот вывод является многоугольником, поэтому строки 7 -9 (t[...~RegionMember~# &]
) создает список точек с целочисленными координатами в этом многоугольнике. Наконец, строка 5 и конец строки 9 вычисляют все точки, которые находятся на расстоянии ровно 1 (следовательно, не 0) от этого набора целых точек; этот набор становится кругосветным путем.Ниже приведен вывод для большого контрольного примера по ссылке ОП. Обратите внимание, что в левом верхнем углу необычный выбор того, когда идти на запад, а не на юго-запад, намекает на то, что он затеняет невидимую линию наклона -2/3 между двумя полуостровами (указанный отрезок является частью границы выпуклой оболочки).
источник
char
тип; в этом случаеchar
вместо строки можно использовать массив.Python 3, 779 байт (отступ с вкладками)
Это целая программа. Он читает входные данные из стандартного ввода и выводит их на стандартный вывод. Stdin должен заканчиваться EOF. Пример запуска с большим вводом: https://ideone.com/XIfYY0
Идея проста: он вычисляет наименьшие восьмиугольные границы и рисует ячейки, которые находятся внутри всех вычисленных границ и пересекают хотя бы одно из ребер.
источник
sys.stdin
качестве входных данных.input()
получение многострочногоR(0,x)
сR(x)
P
иf
;L(generator expression)
=>[generator expression]
;F
,r
и,B
кажется, используются только один раз за штуку и, таким образом, могут быть встроены.JavaScript (ES6),
369343 байтаОбъяснение: Строка разбита на массив символов (мне неясно, допустим ли ввод массива символов). Массив затем повторяется и позиции всех площадей земли. Ограничивающая линия , заданные уравнения
x - y = o
,x = p
,x + y = q
,y = r
,y - x = t
,-x = u
,-x - y = v
,-y = w
определяется таким образом, чтобы максимально возможный параметр выбран , где все земли находятся за пределами линии. Это имеет эффект включения острова в восьмиугольник. Координаты углов восьмиугольника легко вычисляются из параметров, и ячейки на его краю заполняются. Массив затем соединяется обратно в строку. Причина, по которой достаточно восьмиугольника, заключается в следующем:Рассмотрим угол восьмиугольника. В некоторый момент вдоль двух краев путь будет ограничен землей, потому что мы построили восьмиугольник, чтобы коснуться земли как можно ближе. Если в самом углу нет земли, путь может проходить по альтернативным маршрутам, как показано справа, но это все равно то же количество ортогональных и диагональных шагов, поэтому расстояние не меняется.
источник
rest of arguments
параметр....p
в разных местах.) Разрушение это что-то другое (хотя оператор распространения может быть использован при разложении).Python 3,5,
224, 263, 234218 байтОтбросьте еще 16 байтов, избавившись от вложенной функции и сделав ее однострочной.
Гольф от 29 байтов:
Ввод - это одна строка, использующая «~» для океана, «X» для земли и «o» для границы. (Использование «X» сохраняет байт для «>» вместо «==»)
Менее гольф-версия с комментариями:
источник
C # 7 -
414369327 байтРедактировать : переключился на 1D зацикливание, вычисления
i
иj
на летуРедактировать : изменил метод ввода, свернул таблицу поиска и переключился на четко определенные начальные границы ... и удалил бессмысленное пространство в последнем внешнем цикле for
Попробуйте онлайн
Полная программа, принимает входной сигнал в стандартный дюйм, печатает на стандартный выход, использование
#
,.
иo
. Для каждой ячейки он вычисляет «профиль» (который представляет собой расстояние по 8 направлениям (кажется, для удобства он вычисляет девятое0
), и записывает максимум каждого из них. Затем записывает всю карту снова, и заменяет любую ячейку, которая находится как на границе, так и вне ее, на «о». Приведенный ниже код поясняет, как все это работает.Согласно моему ответу « Спасти гусей от вымирания» , получается самый маленький восьмиугольник (действительное кругосветное плавание с наибольшей площадью), который ограничивает остров.
Обратите внимание : что раз в жизни я использую что-то из текущего десятилетия, и этот код требует C # 7 для компиляции. Если у вас нет C # 7, есть одна строка, которую нужно заменить, которая четко обозначена в коде.
Пример использования и вывод:
Отформатированный и закомментированный код:
источник