Обычная строка выглядит так:
Hello,IAmAStringSnake!
И струнная змея выглядит примерно так:
Hel
l rin
o,IAmASt g
S
!ekan
Твое задание
Строковые змеи опасны, поэтому вы должны создать программу, которая принимает строковую змею в качестве входных данных и выводит ее как обычную строку.
Характеристики
- Ввод может быть многострочной строкой или массивом строк.
- Каждая строка ввода будет дополнена пробелами для формирования прямоугольной сетки.
- Персонажи в змее могут подключаться только к смежным персонажам сверху, снизу, слева или справа от них (как в игре Snake). Они не могут идти по диагонали.
- Персонажи-змеи никогда не будут соседствовать с другой частью змеи, только с подключенными персонажами.
- Первый символ строки - это конечный символ с самым коротким манхэттенским расстоянием от верхнего левого угла входной сетки (т. Е. Минимальное количество ходов, которое потребуется змее, чтобы перейти непосредственно от конечного символа к верхнему левому углу). угол). Оба конца никогда не будут иметь одинаковое расстояние.
- Строка может содержать любой символ ASCII между точками кода 33 и 126 включительно (без пробелов и переносов).
- Длина строки будет от 2 до 100 символов.
- Самый короткий код в байтах побеждает.
Тестовые случаи
(Входная сетка с последующей выходной строкой)
Hel
l rin
o,IAmASt g
S
!ekan
Hello,IAmAStringSnake!
----------
Python
Python
----------
P ngPu Code
r i z d G
o m z n o
gram lesA lf
ProgrammingPuzzlesAndCodeGolf
----------
~ zyx tsr XWVUTSR
}|{ wvu q Y Q
! p Z `ab P
"#$ 6789:; o [ _ c O
% 5 < n \]^ d N
('& 432 = m e M
) 1 > lkjihgf L
*+,-./0 ? K
@ABCDEFGHIJ
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
----------
tSyrep
r p
in Sli
g Sile
Snakes n
Ser ylt
a eh ilS
fe w t
emo h
Sre
SlipperyStringSnakesSilentlySlitherSomewhereSafe
Ответы:
APL, 55 байт
Эта функция принимает символьную матрицу со строкой змея в ней.
Пример:
Объяснение:
(,⍵≠' ')/,⍳⍴⍵
: получить координаты всех не пробелов(⊂0 0)
: начинаются с (0,0) (что является недопустимой координатой){
...}
: следуй за змеей, учитывая положение и змею:1<⍴⍵:
: если осталось более 1 элемента:∆←⍵~⍺
: удалить текущую позицию из змеи и сохранить ее в∆
.+/¨|⍺-∆
: найти расстояние между текущей позицией и каждой точкой в остальной части змеи∆[⊃⍋...
] `: получить ближайшую точку на змее∇
: запустите функцию снова, с ближайшей точкой в качестве новой текущей точки и укороченной змеей в качестве новой змеи.⍺,
: добавить текущую позицию к результату этого⋄⍺
: в противном случае просто верните текущую позицию1↓
: удалить первый элемент из результата (это позиция (0,0))⍵[
...]
: получить эти элементы из ⍵, в том порядкеисточник
JavaScript (ES6) + SnakeEx , 176 байт
Помните SnakeEx? Хорошо, потому что я тоже! Предложения по игре в гольф приветствуются.
источник
MATL , 80 байт
Спасибо @LevelRiverSt за исправление
Ввод осуществляется в виде двумерного массива char с разделенными строками
;
. Тестовые случаи в этом форматеПопробуйте онлайн!
объяснение
Координаты каждого непространственного символа представлены комплексным числом. Для каждого текущего символа следующий получается как ближайший (минимальная абсолютная разница их комплексных координат).
Чтобы определить начальный символ, необходимо найти две конечные точки. Это делается следующим образом. Конечная точка - это непространственный символ, имеющий ровно одного непространственного соседа. Количество соседей получается путем двухмерной свертки с подходящей маской. Начальная точка - это конечная точка, комплексная координата которой имеет наименьшую сумму действительной и мнимой частей; т.е. на Манхэттене самое близкое расстояние к комплексному числу 0 или, что эквивалентно 1 + 1j, которое является комплексной координатой верхнего левого угла.
источник
The initial point is the endpoint whose complex coordinate has the least absolute value
Осторожно: Евклидово расстояние! = Манхэттенское расстояние. например, точка 7 + 7j имеет евклидово расстояние 9,8994 и манхэттенское расстояние 14. 10j дальше по евклидову расстоянию, но значительно ближе по манхэттенскому расстоянию. Кроме этого, отличная концепция!C
198190179180181 байтРедактировать: Использовал подсказку user81655 и удалил скобки в тройном операторе, спасибо! Я также изменил громоздкий (S & 1) тест на равномерность для более подходящего (и более короткого!) S% 2.
Edit2: Использование * стиля адресации в значительной степени сделало меня слепым к очевидным оптимизациям в определении S, то есть замене * (a + m) на [m] и т. Д. Затем я заменил сам S на T, что по существу делает половина того, что делает С. Код также теперь использует возвращаемое значение putchar.
Edit3: исправлена ошибка, которая возникала с самого начала, критерии остановки поиска на Манхэттене a <b + m верны, только если a уже уменьшено. Это добавляет 2 байта, но один восстанавливается, сделав определение m глобальным.
Edit4: мой гольф прошел минимум и сейчас идет не в ту сторону. Еще одно исправление, связанное с поиском на Манхэттене. Первоначально у меня были встроенные проверки на месте, и без них поиск продолжается для больших входных массивов (где-то около 50x50) за пределами массива b. Следовательно, этот массив должен быть расширен как минимум вдвое по сравнению с предыдущим размером, что добавляет еще один байт.
Разгромил и объяснил:
источник
a[1]
иa[-m]
т. Д., И сделайтеm
глобальным -m=103;main()
.C 272 байта
Посмотрите на источник @ Zunga. Теперь посмотри на мою. Хотите знать, как я получил дополнительные 91 байт?
Ungolfed:
источник
Python (2 и 3),
640 624 604 583 575 561 546538 байтЯ все еще играю в гольф n00b, так что это немного больше.
Изменить: Спасибо @porglezomp за предложения! Я не удалил все операторы 'и', так как это сломало бы Python 3.
Edit2: Спасибо @Aleksi Torhamo за комментарий о isspace (). Результирующее сокращение компенсирует исправление, которое я вставил. Также спасибо anonymous за подсветку синтаксиса!
Edit3: Спасибо @ mbomb007 за несколько дополнительных байтов.
А вот и моя предварительная версия для гольфа
источник
S=lambda s:s.isspace()
и затем сделавS(s)
вместоs.isspace()
.and
на<
, посколькуf() < g() < h()
это то же самое, что иg = g(); f() < g and g < h()
с точки зрения побочных эффектов (короткое замыкание цепей сравнения), и вы все равно игнорируете результат сравнений.m[(x,y)]=
такой же, как и более короткийm[x,y]=
S=str.isspace
S
и использование<'!'
в каждом случае может иметь одинаковую длину, открывая возможность сэкономить больше. Изменениеif 1-S(v[x]):
кif(v[x]<'!')<1:
, например. И, возможно, вы могли бы удалить некоторые скобки в последующих сравнениях, сделав это таким образом.JavaScript (ES6), 195
Смотрите объяснение внутри тестового фрагмента.
Контрольная работа
источник
););}
?for
заголовка, где нужны 2 двоеточия. Вторым является разделитель дляfor
телаLua,
562535529513507504466458 байтБезусловно, мой самый большой гольф на данный момент,
я думаю,что я все еще могу отрезать 100 байтов, к которым я буду стремиться, но разместив его как ответ, поскольку это уже заняло некоторое время :).Я был прав, я вырубил более 100 байтов! Я не думаю, что есть много возможностей для улучшения.эта функция должна вызываться с двумерным массивом, содержащим один символ на ячейку.
Благодаря ему удалось сэкономить 40 байт при работе с @KennyLau !
Woohoo! До 500!
Ungolfed
Пояснения придут, как только я закончу играть в гольф, на данный момент я одолжу вам читаемую версию этого исходного кода: DВот и объяснения!Изменить: не обновляется с последней модификацией, все еще игра в гольф перед обновлением. То же самое касается объяснений
Итак, вот некоторые подробные объяснения о том, как работает эта программа.
Прежде всего, давайте рассмотрим цикл с меткой
a
, он позволяет нам найти ближайший конец к верхнему левому углу. Это будет цикл навсегда, если нет конца, но это не проблема: D.На сетке 4x4 здесь указаны расстояния между змеями (слева) и порядок их просмотра (справа)
Для каждого этого символа, чтобы быть в конце, он должен проверить два условия: - не быть пробелом - быть окруженным ровно 3 пробелами (или ровно 1 не пробел)
Эти условия проверяются следующим фрагментом кода
Проверка, если символ не пробел, достигается выражением
m[i][j]~=s
.Проверка того, что мы окружены только одним незаполненным пространством, достигается путем изменения указанных выше условий для нашего окружения, это можно записать как
И, наконец, если все вышеперечисленное оценено как true, троичный вернет то, что в последнем
and
->m[i][j]
. Остальное мы дадимr
неустановленным :)Теперь, когда у нас есть голова змеи, давайте пройдем весь путь до другого конца! Итерации змеи в основном достигаются следующими вложенными троицами:
Мы переустанавливаем
i
иj
в то же время избегаем использования манекенов для хранения старых значений. Они оба имеют одинаковую структуру и используют простые условия, поэтому я представлю их в виде вложенныхif
, это должно позволить вам прочитать их легче. :)Можно перевести на:
Проверь это!
Вот код, который я использую для запуска, вы можете проверить его онлайн , скопировав его.
источник
Луа, 267 байт
Требуется Lua 5.3.
Использование:
источник
Python 3,
245243241236 байтs
является входной строкой,n
выводится ли вывод на стандартный вывод:Редактировать: Спасибо @Cees Timmerman за сохранение 5 байтов!
источник
c>' 'and
иprint n
в Python 2.if
вместоelif
?s
переменная - многострочная строка; последний символ строки должен быть символом новой строки (это необходимо для прохожденияPython
контрольного примера)Python, 537
Мое первоначальное решение:
Немного сжал, но оставил как метод:
источник
Java 7,
927924923 байтаХорошо, это заняло некоторое время. В некоторых языках программирования не имеет значения, находятся ли ваши массивы x и y за пределами 2D-массива, но с Java это вызовет
ArrayIndexOutOfBoundsExceptions
, так что все должно быть проверено ...Сначала я определяю начальную точку, а затем использую рекурсивный метод для построения строки оттуда. Кроме того, я использую список, чтобы отслеживать координаты, с которыми я уже столкнулся, поэтому он не будет переходить в цикл «вперед-назад-назад» (в результате возникает исключение StackOverflowException).
Это, пожалуй, самый длинный ответ, который я написал до сих пор, но, хотя некоторые части можно сыграть в гольф, я не думаю, что эта проблема может быть намного короче в Java. Java просто не подходит для того, чтобы следовать по пути в сетке. Тем не менее, это было забавное испытание. :)
Ungolfed и тестовые случаи:
Попробуй это здесь.
Выход:
источник
PHP,
199184182 байтаможет еще иметь небольшой потенциал для игры в гольф
принимает ввод как многострочную строку из командной строки, ожидает перевод строки в стиле Linux.
Бегать
php -r '<code>' '<string>'
; избежать разрывов строк.сломать
источник
C #, 310
(Изменить: исправление ошибки)
Функция с многострочным строковым параметром, возвращающая строку.
Включая запрошенный
using
в подсчет байтов.Это портирование моего ответа javascript.
Тест на идеоне
С пробелами
источник
Python 2, 251 байт
Или, если вам нужны ведущие символы новой строки в ваших тестовых случаях, 257 байт:
Проходит все тестовые случаи.
Результаты в:
источник
b.append(...)
наb+=[...]
иdef n(x,y):return ...
сn=lambda x,y:...
' '
.~-x
вместоx-1
, вам не придется использовать скобки.Japt
-P
, 106 байтПопробуйте онлайн!
Это ... хм ... мерзость
Распаковано и как это работает
Примечательным моментом является то, что я использовал приоритет оператора между операторами присваивания и запятой в JS, чтобы упаковать несколько строк и сохранить возможность использования ярлыка
@
(XYZ{
).источник