Створіть необмежений контрастний рядок


11

Контрастна струна - це якийсь опис тестових даних, що самоописується, що використовується при тестуванні програмного забезпечення. Не впевнений, що його насправді винайшов Джеймс Бах , але я знаю це звідти.

Ідея така: дані тесту містять багато зірочок ( *). Цифра перед зірочкою вказує на те, як довго тривають дані тесту в цій точці. Якщо вам потрібно знати позицію в тестових даних, яка не є зірочкою, знайдіть останню зірочку, подивіться на номер раніше і додайте кількість цифр, які слідують за цим.

Послідовність починається так:

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

Як бачите, позначена зірочка знаходиться в положенні 14.

Якщо файл має бути усічений наступним чином

[...]2045*20

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

Ваше завдання створити найкоротшу (це ) програму, яка виводить (std :: out або файл чи будь-що інше) довільну довгу тестову рядок цього формату. Довжина символів подається як аргумент. Програма повинна підтримувати до 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

Якщо це не зупиняється, то як ви це тестуєте?
Leaky Nun

2
Ця довжина в символах?
TheBikingViking

4
Можете чи ви довести , що ми б ніколи не доведеться вибирати між 995*999*і 995*1000*чи що - небудь подібне?
Leaky Nun

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

Пітон 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 від stdin та друкує контрредок довжиною 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/… Тому я гадаю, що він перестає працювати, коли його "модернізували" до подвоєння
Thomas Weller

@ThomasWeller PowerShell [double]s - 64-розрядні. Наприклад, біг 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 * 62 * 65 * 68 * 71 * 74 * 77 * 80 * 83 * 86 * 89 * 92 * 95 * 98 * 102 * 1 "


0

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

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

Спробуйте в Інтернеті!

Знайдіть перші nчисла в рядку, а потім приєднайтесь до списку зірочкою. Це завжди буде довше, ніж nце дозволило ОП у коментарях.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.