Подумайте об изображении простой , открытой двумерной кривой на сетке текста шириной W и высотой H, где она X
представляет часть кривой и .
представляет пустое пространство, а другие символы не используются.
Каждое пространство сетки имеет 8 соседних пространств сетки, его окрестности Мура . Сетки за пределами границ считаются пустыми.
Сетка содержит кривую, если она имеет ровно одно X
ИЛИ, если она имеет более одного, X
где:
- Ровно два человека
X
имеют только одного соседаX
. Это конечные точки кривой. - Каждая,
X
кроме конечных точек, соседствует ровно с двумяX
s. Они составляют основную часть кривой.
Например, эта сетка, где W = 9 и H = 4 содержит кривую:
....X.... .X.X.X.X. X..X..X.X .XX.....X
Аналогично, эти сетки (W = 4, H = 3) имеют кривые:
.... .X.. .... .... .X.X .... X..X ..X. XX.. X.X. ..X. .XX. .X.. .... ....
Эти сетки, однако, не содержат кривую:
.... .XX. ...X XX.. .... X.X. .... X..X ..XX XX.. .X.X .X.. .... .XX. .X.. .... ...X X.X.
Мы можем найти длину кривой, суммируя расстояния между всеми соседними парами X
s:
Расстояние между двумя ортогонально соседними
X
s составляет 1 единицу.XX
X X
Расстояние между двумя соседними по диагонали
X
s составляет √2 единицы.X. .X
.X X.
Например, длина кривой в сетке
XXX. ...X ..X.
может быть визуализирован как
так что мы можем видеть, что это 1 + 1 + √2 + √2 = 4.828427 ...
Длина кривой только с одним X
равна нулю.
Когда сетка не образует кривую, ее длина не является четко определенной.
Вызов
Если задана сетка текста X
s и .
s, выведите длину кривой, которую она содержит, либо выведите что-то вроде -1
или, Null
чтобы указать, что сетка не имеет кривой.
Для ввода вы можете использовать другие символы, чем X
и .
при желании, и H и W могут быть приняты в качестве ввода при необходимости. Ввод в виде вложенного списка или матрицы, заполненной 1 и 0 вместо строки, также подойдет.
Вы можете вывести число с плавающей запятой для длины кривой или, альтернативно, два целых числа A и B, где length = A + B*√2
.
Самый короткий код в байтах побеждает.
Тестовые случаи
XXX.
...X
..X.
2 + 2*√2 = 4.828427...
....X....
.X.X.X.X.
X..X..X.X
.XX.....X
3 + 8*√2 = 14.313708...
....
....
..X.
0 + 0*√2 = 0
.X..
X..X
.XX.
1 + 3*√2 = 5.242640...
....
..X.
.X..
0 + 1*√2 = 1.414213...
....
XX..
....
1 + 0*√2 = 1
.X.X
X.X.
....
0 + 3*√2 = 4.242640...
....
....
....
....
-1
.XX.
X..X
.XX.
-1
...X
..XX
.X..
-1
....
.X.X
...X
-1
X.X.
.X..
X.X.
-1
источник
[x.x,...,.x.]
не правильная кривая, верно?Ответы:
MATL ,
5251 байтВвод представляет собой матрицу нулей и единиц.
Выход есть
B
, тогдаA
. Не кривые дают негативA
.Попробуйте онлайн! Или проверьте все тестовые случаи .
объяснение
Для вычисления длины кривой используются две двумерные свертки 1 : одна с маской Мура, а другая с маской, содержащей только диагональных соседей. Результатом являются две матрицы с одинаковым размером входных данных, которые будут обозначаться как M и D соответственно. M дает общее количество соседей для каждой точки, а D - количество диагональных соседей.
Результаты в M и D должны быть отфильтрованы, чтобы отбросить точки, которые не принадлежат кривой. Кроме того, они должны быть разделены на 2, потому что «соседство» является симметричным отношением, поэтому каждая точка на кривой считается дважды.
Определение, является ли кривая действительной , более громоздко, чем я ожидал. Для этого код проверяет три условия:
2
? (То есть есть ли ровно две точки с одним соседом?)2
минус2
? (Вместе с условием 1 это проверяет, все ли ненулевые значения в M, кроме двух, равны2
)Кривая действительна, если выполнены условия 1 и 2 или если выполнено условие 3.
1 Свертка - ключ к успеху .
источник
Python 3 ,
316,315,311 байт.Я думаю, что это охватывает все случаи; по крайней мере, тестовые случаи работают.
Кроме того, конечно, есть еще много возможностей для игры в гольф, вероятно, в начале, когда рассматриваются крайние случаи.
Попробуйте онлайн!
Как это устроено:
d,R,C
1. список списков с 1 в качестве кривой и 0 в качестве фона, 2. количество строк и столбцовd
чтобы нам не пришлось беспокоиться о крае массива 2dСпасибо @Helka Homba за указание на пропущенное дело. Спасибо @TuukkaX и @Trelzevir за советы по игре в гольф.
источник
d=[[1,0,1],[0,1,0],[1,0,1]]
, здесь произойдет сбой (добавлен тестовый пример).s=sum
экономит 4 байта.Mathematica,
153150 байтПринимает двумерный массив с
0
s для.
s и1
s дляX
s. ВыходыNull
для не кривых.Mathematica имеет 45-байтовую встроенную для этого, но она выводит некоторые числа для не-кривых и 1 / sqrt (2) для ввода
{{1}}
. Исправление этих стоило 105 байт (может быть в гольфе?).источник