вступление
Поэтому я снова тратил время на исследование алгоритмов сортировки суффиксов, оценку новых идей вручную и в коде. Но я всегда пытаюсь вспомнить тип моих суффиксов! Можете ли вы сказать мне, какой тип моих суффиксов?
Левый самый что?
Многие алгоритмы сортировки суффиксов (SAIS, KA, мое собственное daware) группируют суффиксы в разные типы для их сортировки. Существует два основных типа: суффиксы S-типа и L-типа . Суффиксы S-типа - это суффиксы, которые лексикографически меньше ( S maller), чем следующий суффикс, и L-типа, если они лексикографически больше ( L arger). Крайний левый S-тип ( LMS-тип ) - это просто суффикс S-типа, которому предшествует суффикс L-типа .
Особенность этих суффиксов типа LMS заключается в том, что как только мы их отсортируем, мы можем отсортировать все другие суффиксы за линейное время! Разве это не круто?
Соревнование
Учитывая, что строка предполагает, что она заканчивается специальным символом, который меньше, чем любой другой символ в этой строке (например, меньше, чем даже нулевой байт). Выведите тип соответствующего символа для каждого суффикса.
Вы можете свободно выбирать, какой символ использовать для какого типа, но я бы предпочел, L, S and *
чтобы L-, S- and LMS-type
все они печатались ( 0x20 - 0x7E
).
пример
Учитывая mmiissiissiippi
вывод строки (при использовании L, S and *
):
LL*SLL*SLL*SLLL
Например, первое L
связано с тем, что mmiissiissiippi$
лексикографически больше, чем miissiissiippi$
( $
символ представляет добавленный минимальный символ):
L - mmiissiissiippi$ > miissiissiippi$
L - miissiissiippi$ > iissiissiippi$
* - iissiissiippi$ < issiissiippi and preceeded by L
S - issiissiippi$ < ssiissiippi$
L - ssiissiippi$ > siissiippi$
L - siissiippi$ > iissiippi$
* - iissiippi$ < issiippi$ and preceeded by L
S - issiippi$ < ssiippi$
L - ssiippi$ > siippi$
L - siippi$ > iippi$
* - iippi$ < ippi$ and preceeded by L
S - ippi$ < ppi$
L - ppi$ > pi$
L - pi$ > i$
L - i$ > $
Еще несколько примеров:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Цель
Я здесь не для того, чтобы раздражать Питера Кордеса (я так собираюсь когда-нибудь сделать это на stackoverflow); Я просто очень ленив, так что это, конечно, код-гольф ! Самый короткий ответ в байтах побеждает.
Изменить: порядок символов определяется их байтовым значением. Это означает, что сравнение должно быть как у strcmp
.
Edit2: как указано в выводе комментариев должен быть один символ для каждого входного символа. Хотя я предполагал, что это будет пониматься как «вернуть строку», кажется, что хотя бы один ответ возвращает список из отдельных символов. Чтобы не сделать недействительными существующие ответы, я позволю вам вернуть список из отдельных символов (или целых чисел, которые при печати приводят только к 1 символу).
Советы по линейному времени:
- Это может быть сделано в 2 параллельных прямых итерациях или в одной обратной итерации.
- Состояние каждого суффикса зависит только от первых двух символов и типа второго.
- Сканируя ввод в обратном направлении, вы можете определить L или S следующим образом:
$t=$c<=>$d?:$t
(PHP 7), где$c
текущий символ$d
предыдущего и$t
предыдущего типа. - Смотрите мой ответ PHP . Завтра я буду награждать награду.
c++
строк стиля. Думайте об этом как двоичные данные.*
значит?*
означает, что соответствующий суффикс имеет типleft most s-type
.A S-type suffix that is preceeded by a L-type suffix.
,Ответы:
Haskell ,
64534842 байтаПопробуйте онлайн!
Ungolfed, с
Char
вместоInt
:источник
z=
можно удалить.go
функция принимает два аргумента. Первый - это символ, представляющий то, что следует использовать для описанияS
ситуации. Вторая строка. Он рекурсивно проходит через эту строку, удаляя первый символ на каждом шаге (вот чтоtail
делает). Хитрость заключается в том, что первый аргумент устанавливается,*
когда предыдущий результат былL
, илиS
иначе. Таким образом, в случае, когда должны использоваться*
или илиS
, этот первый аргумент может быть использован напрямую. Надеюсь, что это имеет смысл.Желе ,
25 23 21 2019 байтПолная программа, которая печатает список символов, используя:
(В качестве ссылки он возвращает список, в котором все элементы являются символами, кроме последнего, который равен нулю.)
Попробуйте онлайн! или посмотрите набор тестов (с преобразованием в
LS*
).Как?
источник
+
строки кажутся векторизованными, но лежащие в основе результаты на самом деле не итерируемые в Jelly, а строки (!) (Например, try+@/L€
or+@/L€€
or ...)+
выдает фактическую строку. Это недокументированная функция или то, что вы называете ошибкой.Python 3,
9287746965 байтИспользует
0
дляL
,1
дляS
и2
для*
. Оберните входную строку в кавычки; Я считаю, что это разрешено соглашением.Попробуйте онлайн!
Пример использования:
сэкономили 5 байтов благодаря Leaky Nun, 4 байта благодаря ovs
источник
JavaScript (ES6),
5145 байтСохранено 6 байтов благодаря @Neil.
Рекурсивное решение для упражнения.
источник
f=(c,d)=>c&&(d<(d=c<(c=c.slice(1))))+d+f(c,d)
JavaScript (ES6), 52 байта
Порт @ L3viathan ответ.
источник
c=1
какc=0
...C (лязг) , 88 байт
Попробуйте онлайн!
источник
Haskell ,
7775 байтов, линейное времяПопробуйте онлайн!
Как это работает
При этом используется рекурсия, удаляющая по одному символу за раз от начала строки. (Тип строки Haskell представляет собой односвязный список символов, поэтому каждый из этих шагов выполняется в постоянном времени.)
источник
S, L and *
?[1,1,2,0,1,1,2,0,1,1,2,0,1,1,1]
это список однозначных чисел, а не список одиночных символов. В моем случае, я думаю, что вывод списка чисел не спасет меня ни одного байта.Python 2 ,
6555 байтРекурсивная версия, основанная на ответе L3viathan , использующая
012
какLS*
:Попробуйте онлайн!
Python 3 ,
6559 байтРекурсивное решение с использованием
L
,S
и*
:Работает через строку с фронта, и заменяет все экземпляры
LS
сL*
Попробуйте онлайн!
источник
blah if s else''
→s and blah
сохраняет шесть байтов. В Python 2str(blah)
→`blah`
сохраняет еще три байта на втором решении.PHP, 82 байта, линейное время
Перебирает ввод справа налево и заменяет каждый символ типом.
Вычисляет тип с учетом текущего и предыдущего символа (-1 или 1). Если равно, тип не меняется.
источник
strtr
PHP , 70 байт
L = 1, S = 0, * = 2
Многобайтовая поддержка необходима для последнего Тестового случая с
§
+3 байтамиmb_substr
вместоsubstr
Попробуйте онлайн!
PHP , 71 байт
L = 1, S = 0, * = 2
Попробуйте онлайн!
PHP , 74 байта
Попробуйте онлайн!
источник
$s=&$argn
довольно умно! Я почти уверен, что есть лучший ответ;) Надеюсь, кто-тоmb_substr
вместо того,substr
чтобы вводить данные не в простом диапазоне ASCII. Нужно ли поддерживать последний тест?§