Создать неограниченную контрструну


11

Counterstring является своего рода тестовых данных самоописываемых , который используется в тестировании программного обеспечения. Не уверен, что это действительно изобрел Джеймс Бах , но я знаю это оттуда.

Идея заключается в следующем: тестовые данные содержат много звездочек ( *). Число перед звездочкой говорит о том, как долго в этот момент находятся тестовые данные. Если вам нужно знать позицию в тестовых данных, которая не является звездочкой, найдите последнюю звездочку, посмотрите на число перед и добавьте число цифр, которые следуют.

Последовательность начинается так:

2*4*6*8*11*14*17*20*23*
             ^

Как видите, отмеченная звездочка находится в позиции 14.

Если файл обрезается следующим образом

[...]2045*20

тогда вы можете определить, что где-то существует ограничение в 2047 символов (2045, где звездочка плюс 2 для 2и 0).

Ваша задача - создать самую короткую (это ) программу, которая выводит (std :: out или file или что-то еще) произвольную длинную тестовую строку этого формата. Длина в символах указана в качестве аргумента. Программа должна поддерживать тестовые данные объемом до 2 ГБ (входное значение 2147483647 символов).

«Опасные» позиции в файле объемом 2 ГБ:

8*11*
98*102*
998*1003*
9998*10004*
99998*100005*
999995*1000003*
9999995*10000004*
99999995*100000005*
999999995*1000000006*

Это должно ответить на вопрос @Leaky Nun , если будет принято решение между 995 * 999 * и 995 * 1000 * или аналогичным: нет.

Конец файла размером 2 ГБ с входным значением 2147483647:

2147483640*2147483

Если он не останавливается, то как вы его тестируете?
Утренняя монахиня

2
Это длина в символах?
TheBikingViking

4
Можете ли вы доказать , что мы бы никогда не придется выбирать между 995*999*и 995*1000*или что - нибудь подобное?
Утренняя монахиня

1
В будущем, пожалуйста, используйте Песочницу, чтобы сгладить изломы в ваших задачах, прежде чем публиковать их.
Мего

1
@ThomasWeller Если мы можем создать более длинный вывод, можем ли мы не брать никаких данных и просто создавать строку размером 2 ГБ?
xnor

Ответы:


4

Haskell, 60 58 байт

В качестве функции мы получаем:

f=length.show
iterate(\n->1+n+(f$n+1+f n))2>>=(++"*").show

Полная программа, 72 70 байт

Это выводит бесконечную контрструну к STDOUT:

f=length.show
main=putStr$iterate(\n->1+n+(f$n+1+f n))2>>=(++"*").show

Ввод длины требует 20 дополнительных байтов:

main=interact(\j->take(read j)$iterate(\n->1+n+(f$n+1+f n))2>>=(++"*").show)

Это работает примерно до вашего объема оперативной памяти, так как по умолчанию Haskell использует числовые целочисленные типы Integer.



2

Python 2, 74 72 66 64 61 байт

f=lambda n,i=2:"%d*"%i+f(n,len(`i+2`)-~i)[:n-2]if i<n*2else""

Принимает целое число n и выводит контрструну длины n.

версия программы, 69 байт:

s,n,i="",input(),2
while i<2*n:s+="%d*"%i;i+=len(`i+2`)+1
print s[:n]

Берет целое число n из стандартного ввода и печатает контрструну длины n.

Короче, но только почти рабочая, альтернативная версия:

n,i=input(),2
while i<2*n:print("%d*"%i)[:n-i],;i+=len(str(i+2))+1

1

PowerShell v5, 97 байт

param($n)$l=1;for($i=0;$i-lt$n){$i+="$i*".length;if("$i".Length-gt$l){$i++;$l++};ac .\o "$i*" -n}

Принимает ввод в качестве аргумента командной строки $n, устанавливает помощник, $lкоторый мы используем для отслеживания нашей целочисленной длины. Затем мы делаем цикл от 0до $n. Каждую итерацию мы увеличиваем $iна .lengthстроку, образованную из, $iи звездочку. Затем, если .lengthиз $iменяется (например, мы перешли от 2 -х цифр до 3 цифр), мы увеличиваем как вспомогательная $lпеременная ength и $i(для учета дополнительной цифры). Затем мы используем add-contentкоманду для добавления "$i*"файла .\oв текущий каталог с помощью -noNewLine.

NB

  • Требуется v5, так как -noNewLineпараметр был наконец добавлен в этой версии.
  • PowerShell автоматически преобразует с повышением частоты [int]в [double](нет, я не знаю, почему это не так [long]), поэтому он будет правильно обрабатывать ввод до и более чем 2147483648без проблем. Теоретически, он будет обрабатывать ввод где-то примерно до 1.79769313486232E+308(максимальное значение [double]), прежде чем жаловаться, но я ожидаю, что диск заполнится до того, как это произойдет. ;-)
  • Из-за условной проверки цикла это выведет в файл минимальную длину ввода. Например, для ввода 10это будет выводить 2*4*6*8*11*, так 11как это первое $iзначение больше, чем вход.

PowerShell v2 +, также 97 байт (не конкурирует)

param($n)$l=1;-join(&{for($i=0;$i-lt$n){$i+="$i*".length;if("$i".Length-gt$l){$i++;$l++};"$i*"}})

Вместо отправки в файл это инкапсулирует итерации цикла и затем -joinпомещает их вместе в строку. Это позволяет ему работать для версий более ранних, чем v5. Однако, поскольку .NET определяет a [string]с помощью конструктора String(char c,Int32 length), эта версия не удовлетворяет максимальному входному требованию, поскольку выходная строка будет переполнена и barf.

Кроме того, вы можете не захотеть иметь строку ~ 2 ГБ, плавающую в вашем конвейере. Просто говорю'.


1.79769313486232E + 308, конечно, не будет работать, потому что добавление небольших чисел в число с плавающей точкой больше не изменит значение. См. Stackoverflow.com/questions/12596695/… Поэтому я предполагаю, что он перестает работать после того, как его «обновили» до двойного
Томас Уэллер

@ThomasWeller PowerShell [double]s является 64-битным. Например, run for($i=2147483645;$i-lt2147483655;$i++){"$i - " + $i.GetType()}покажет устойчивую прогрессию, $iно Typeизменения в 2147483648к double. Я уверен, что в какой-то момент он перестанет работать, вероятно, около ~ 15 цифр точности или когда .ToStringначнут использовать e. Это [double]::MaxValueбыла скорее шутка, чем серьезная верхняя граница.
AdmBorkBork

1

Python 3, 126 114 99 байт

def f(x,s=''):
 i=t=2
 while len(s)<x:i+=len(str(t+i))-len(str(t));s+=str(t)+'*';t+=i
 print(s[:x])

Функция, которая принимает входные данные через аргумент счетчика символов для обрезания строки и печатает в STDOUT.

Как это работает

Разница между числами в строке изначально равна 2. Каждый раз, когда передается порядок величины, эта разница увеличивается на 1; это может быть достигнуто путем взятия разности между количеством цифр текущего номера и количеством цифр текущего номера, добавленных к разнице, которая равна 1 только при необходимости. Функция просто зацикливается, в то время как длина строки меньше входной, добавляет к строке и обновляет разность и число по мере необходимости, а затем усекает перед печатью.

Попробуйте это на Ideone

Версия с бесконечным выводом, 69 байт

s=i=2
while 1:i+=len(str(s+i))-len(str(s));print(end=str(s)+'*');s+=i

1

R, 92 байта

    N=nchar;f=function(n){z=0;y="";while(z<n){z=z+N(z+N(z)+1)+1;y=paste0(y,z,"*")};strtrim(y,n)}

Пример вывода:

f (103) [1] "2 * 4 * 6 * 8 * 11 * 14 * 17 * 20 * 23 * 26 * 29 * 32 * 35 * 38 * 41 * 44 * 47 * 50 * 53 * 56 * 59 * 65 * 62 * 68 * 71 * 74 * 77 * 80 * 83 * 86 * 89 * 92 * 95 * 98 * 102 * 1"


0

Желе , 22 19 18 байт

2µṾL+®‘¹©=¡=µ³#j”*

Попробуйте онлайн!

Найдите первые nчисла в строке, затем присоедините к списку звездочку. Это всегда будет дольше, чем nбыло разрешено OP в комментариях.

Программа выборочно обновляет регистр с текущим номером в последовательности в #цикле с ¹©=¡. Я надеялся, что это может быть короче, положив©µ например, после второго , но, к сожалению, это не сработает, и я не могу понять, что короче.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.