Задача
Напишите подпрограмму, которая принимает строку печатных символов ASCII s и возвращает строку, содержащую те же символы, что и s , переупорядоченную таким образом, чтобы ни одна из двухсимвольных подстрок не появлялась более одного раза. Программа должна обработать все строки тестов (см. Ниже) менее чем за одну минуту на современном компьютере . Я также присуждаю специальный бонус в 50 повторений к ответу с наименьшей оценкой, который обрабатывает любую действительную строку из 30 символов менее чем за минуту.
Например, если заданы входные данные Mississippi
, допустимым будет вывод issiMspiips
(двухсторонние подстроки не появляются дважды), а недопустимый вывод будет ipMsispiiss
(поскольку подстрока is
появляется дважды).
Процедура может принимать форму:
- полное чтение программы из
stdin
(или эквивалентной) или из командной строки и вывод вstdout
(или эквивалентную) - функция, принимающая один строковый аргумент и возвращающая строку
Вы можете предположить, что входная строка всегда допускает хотя бы один допустимый вывод.
Соревнование
Ваша процедура должна содержать 5 или более строк кода, разделенных символами новой строки. Пустые строки (включая строки, содержащие только пробелы) игнорируются во всех контекстах и не учитываются в общем количестве строк.
Замена любых двух строк в вашем исходном коде должна привести к фатальной ошибке. Под «фатальной ошибкой» мы понимаем любое из следующих условий:
- исходный код не компилируется, компилятор / интерпретатор объявляет фатальную ошибку
- процедура прерывается с фатальной ошибкой во время выполнения или необработанным исключением во время выполнения
- подпрограмма принудительно завершается внезапным, ненормальным завершением программы, которое не выдает никаких выходных данных, за исключением возможного сообщения об ошибке и / или дампа стека
В качестве альтернативы , вместо строк могут использоваться непрерывные блоки кода, не содержащие символов новой строки. Каждый из этих блоков должен отображаться на отдельной строке в исходном файле с пониманием того, что новые строки удаляются перед компиляцией / интерпретацией исходного кода.
Например, код
aaaa
bbbb
cccc
будет конденсироваться до
aaaabbbbcccc
перед оценкой.
В этом режиме условие фатальной ошибки применяется к замене любых двух блоков кода (и, таким образом, к обмену строк в исходном коде до удаления новых строк). Следовательно, в приведенном выше примере подпрограммы aaaaccccbbbb
, bbbbaaaacccc
и ccccbbbbaaaa
все они должны вызывать фатальные ошибки, либо во время компиляции, либо во время выполнения.
Материалы, использующие этот альтернативный режим, должны декларировать его использование.
счет
Позвольте n быть числом непустых текстовых строк в вашем исходном файле, с n ≥ 5. Позвольте c быть количеством байтов, включенных самой длинной текстовой строкой (длиной в байтах) в вашем исходном файле, не считая никакой завершающей новой строки.
Оценка представления дается с ( n + 10).
Представление с самым низким счетом является победителем.
Удачи. ;)
Тестовые строки
Abracadabra Alacazam
Is Miss. Mississauga Missing?
Ask Alaska's Alaskans
GGGGAAAATTTTCCCCgggaaatttccc
A Man A Plan A Canal Panama
CooliO
, выходoOoCli
?Mspiisiipss
действительным, поскольку единственное повторение,ii
которое не происходит вMississippi
?Ответы:
PHP, оценка = 289 (17 × (7 + 10))
Встроенные функции PHP позволяют легко сделать это плохо. Следующий код просто перемешивает строку, пока не будет получен правильный результат:
Ориентиры
Среднее и максимальное время выполнения рассчитывается с использованием следующего кода:
Результаты:
* Я изменил
ä
на,a
чтобы избежать многобайтовых проблем† Это была самая сложная строка из 30 символов, которую я мог придумать. На самом деле это первые 30 символов последовательности Де Брюйна для k = 'abcdef' и n = 2, причем первый 'b' перемещен, чтобы избежать мгновенного совпадения.
источник
Dyalog APL (11 (5 + 10) = 165)
Доказательство:
⍵
появлению вне функции, которая являетсяSYNTAX ERROR
.b
, поэтому ее нельзя поменять местами на строки3
или4
, которые зависят отb
. Там будетVALUE ERROR
. (И это, очевидно, не может быть заменено1
или5
либо.)c
, поэтому она не может быть заменена на строку4
, которая зависит отc
. (И мы уже доказали, что никакая другая строка не может быть заменена на другую3
.)источник
APL (Dyalog), 6 (5 + 10) = 90
Я использую альтернативу, так что:
Это тот же старый алгоритм.
Пояснение
2,/⍵
дает массив пар символов во входной строке,+/∘.≡⍨
генерирует числовой массив того, сколько пар равняется каждой паре (включая себя)1∧.=
проверяет, равен ли каждый элемент этого массива 1, и логически И результаты вместе:⍵
Если это правда (1
), вернуть входную строку∇⍵[?⍨⍴⍵]
иначе зашифруй входную строку и сделай рекурсивный вызовПерестановка
Если строка 1 поменялась местами со строкой 2, то в итоге вы получите
+/∘.≡⍨{...}
просто беспорядок функций и операторов, которые даютSYNTAX ERROR
.Если строка 1 поменялась местами со строкой 3 или 4, то у вас нет
⍵
определения функции, и это aSYNTAX ERROR
.Если строка 1 поменяется местами со строкой 5, несбалансированные фигурные скобки вызовут
SYNTAX ERROR
, поэтому не беспокойтесь о других 4 синтаксических ошибках.Если строка 5 поменялась местами со строкой 2/3/4, опять же у вас нет
⍵
определения функции. (SYNTAX ERROR
)Если строка 2 поменялась местами со строкой 3, вы в конечном итоге
1∧.=2,/⍵:⍵
. Этот синтаксис называется охранником (думайте об этом как об условном). Условие защиты должно быть равно0
или1
или массиву из 1 элемента0
или1
. Здесь он оценивается как нечто более сложное (скаляр, содержащий массив из 2 элементов). Так что этоDOMAIN ERROR
.Если строка 2 поменялась местами со строкой 4, вы получите инструкцию
1∧.=
, которая пытается применить функцию∧.=
без обязательного левого аргумента. (SYNTAX ERROR
).Если строка 3 поменялась местами со строкой 4, снова вы получите беспорядок функций и операторов (
1∧.=+/∘.≡⍨
), так что вы получитеSYNTAX ERROR
.Тесты
(числа в миллисекундах)
Я все еще думаю о разных расколах. Также у меня есть детерминированный, систематический способ выполнения задачи. Я просто не могу превратить его в алгоритм (убрать творческую часть «правильных чисел») и не могу убедиться, что он работает каждый раз.
источник
Haskell, 129 = 3x (33 + 10)
это использует альтернативный режим.
или в читаемой форме:
Хаскель - очень строгий язык. например,
import
должен прийти первым; определенияs
должны объединяться; все типы должны быть согласованы, и между ними нет способа разыграть и так далее. это приводит к тому, что нефатальная ошибка почти невозможна. на самом деле наличие фатальной ошибки во время выполнения слишком почти невозможно.заметит , что если
g
действительная функция , но имеет неправильный тип (любой тип , отличающееся то[a]->[a]
илиString -> String
и тому подобное) , чем это фатальная ошибка , потому что это невозможно применитьg
к входам.выходы:
источник