Sınırsız bir karşı iplik oluşturma


11

Bir karşı dizgi , yazılım testinde kullanılan bir tür kendini tanımlayan test verisidir. Aslında James Bach tarafından icat edildiğinden emin değilim , ama oradan biliyorum.

Fikir aşağıdaki gibidir: test verileri birçok yıldız işareti ( *) içerir . Yıldız işaretinin önündeki sayı, test verilerinin o noktada ne kadar süreceğini gösterir. Test verilerinde yıldız işareti olmayan bir konum bilmeniz gerekiyorsa, son yıldız işaretini bulun, önceki sayıya bakın ve takip eden basamak sayısını ekleyin.

Dizi şu şekilde başlar:

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

Gördüğünüz gibi, işaretli yıldız işareti 14 konumundadır.

Bir dosya aşağıdaki gibi kısaltılırsa

[...]2045*20

o zaman 2047 karakter yerde (2045 yıldız artı 2 bir sınırı olduğunu türetebilirsiniz 2ve 0).

Bu formatta gelişigüzel uzun bir test dizesi (std :: out veya file ya da neyse) çıktısı veren en kısa ( ) programı oluşturmak sizin görevinizdir . Karakter cinsinden uzunluk bağımsız değişken olarak verilir. Program 2 GB'a kadar test verisini desteklemelidir (giriş değeri 2147483647 karakter).

2 GB dosyasındaki "Tehlikeli" konumlar:

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

995 * 999 * ile 995 * 1000 * arasında bir karar veya benzeri bir karar varsa, bu @Leaky Nun'in sorusuna cevap vermelidir : hayır.

2147483647 giriş değerine sahip 2 GB dosyasının sonu:

2147483640*2147483

Durmazsa, nasıl test edersiniz?
Leaky Nun

2
Bu uzunluk karakter olarak mı?
TheBikingViking

4
Asla 995*999*ve 995*1000*bunun gibi bir şey arasında seçim yapmak zorunda olmadığımızı kanıtlayabilir misiniz ?
Leaky Nun

1
Gelecekte, göndermeden önce zorluklarınızdaki karışıklıkları gidermek için lütfen Sandbox'ı kullanın.
Mego

1
@ThomasWeller Daha uzun bir çıktı oluşturabilirsek, girdi alamaz ve sadece 2GB dizeyi üretebilir miyiz?
xnor

Yanıtlar:


4

Haskell, 60 58 bayt

Bir fonksiyon olarak:

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

Tam program, 72 70 bayt

Bu, STDOUT'a sonsuz bir karşı çıktı üretir:

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

Uzunluğun girilmesi için 20 ek bayt gerekir:

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

Haskell varsayılan sayısal integral türlerini varsayılan olarak kullandığından, bu yaklaşık RAM boyutunuza kadar çalışır Integer.



2

Python 2, 74 72 66 64 61 Bayt

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

N tamsayısını alır ve n uzunluğunda bir karşı dikiş üretir.

program sürümü, 69 Bayt:

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

Stdin'den n tamsayısını alır ve n uzunluğunda bir karşı baskı yapar.

Daha kısa, ancak sadece neredeyse çalışan alternatif versiyon:

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

1

PowerShell v5, 97 bayt

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

Komut satırı argümanı olarak girdi alır, tamsayı uzunluğumuzu takip etmek için kullandığımız $nyardımcıyı ayarlar $l. Sonra 0yukarıdan döngüye $n. Her yineleme biz artırmak $itarafından .lengtholuşturulan dize $ive bir yıldız işareti. Sonra, .lengthbir $ideğiştirilebilir (örneğin, biz 3 basamak 2 basamaklı taşındı) şekilde, yardımcı hem artırmak $length değişken ve $i(ilave basamak için hesaba). Daha sonra oNewLine ile geçerli dizine dosya add-contenteklemek "$i*"için komutu kullanırız..\o-n

NB

  • -noNewLineParametre sonunda bu sürümde eklendiğinden v5 gerektirir .
  • PowerShell otomatik olarak yukarı-dönüştürme [int]yapacak [double](hayır, neden gitmediğini bilmiyorum [long]), bu yüzden girişi 2147483648sorunsuz ve daha büyük bir şekilde sorunsuz bir şekilde işleyecektir . Teorik olarak, şikayet etmeden önce bir yere kadar 1.79769313486232E+308(maksimum değeri [double]) giriş tutacak , ancak disk gerçekleşmeden önce doldurmak bekliyoruz. ;-)
  • Döngü koşullu kontrolü nedeniyle, dosya minimum giriş uzunluğunun çıktısını alır . Örneğin, giriş için 10bu değer çıkacaktır 2*4*6*8*11*, çünkü 11ilk $ideğer girişten daha büyüktür.

PowerShell v2 +, ayrıca 97 bayt (rakip olmayan)

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

Bu, bir dosyaya göndermek yerine, döngü yinelemelerini kapsül içine alır ve ardından -joinbunları bir dizeye ekler . Bu, v5'ten önceki sürümler için çalışmasına izin verir. Ancak, .NET tanımlar bir yana [string]böyle bir kurucu ile String(char c,Int32 length)bu sürüm yok değil çıktı dize taşması ve kusmuğu olacağından, maksimum giriş gereksinimi karşılamak.

Ayrıca, boru hattınızda ~ 2GB'lık bir dize olmasını istemeyebilirsiniz. Sadece söylüyorum'.


1.79769313486232E + 308 kesinlikle çalışmaz, çünkü bir şamandıraya küçük sayılar eklemek artık değeri değiştirmez. Bkz. Stackoverflow.com/questions/12596695/… Benim tahminim, "ikiye yükseltildi" bir kez çalışmayı durdurur
Thomas Weller

@ThomasWeller PowerShell [double]ler 64 bittir. Örneğin run for($i=2147483645;$i-lt2147483655;$i++){"$i - " + $i.GetType()}, sabit bir ilerleme gösterecek, $iancak üzerindeki Typedeğişiklikler 2147483648gösterecektir double. Bir noktada çalışmayı bırakacağından eminim, muhtemelen yaklaşık 15 basamaklı hassasiyet veya .ToStringkullanmaya başladığında e. [double]::MaxValueDaha ciddi bir üst sınır daha ıskarta şaka oldu.
AdmBorkBork

1

Piton 3, 126 114 99 bayt

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])

Dizeyi kısaltmak için karakter sayımının bağımsız değişkeni yoluyla girdi alan ve STDOUT'a yazdırılan bir işlev.

Nasıl çalışır

Dizedeki sayılar arasındaki fark başlangıçta 2'dir. Bir büyüklük sırası her geçtiğinde, bu fark 1 arttırılır; bu, mevcut sayının basamak sayısı ile farka eklenen mevcut sayının basamak sayısı arasındaki fark alınarak elde edilebilir, ki bu sadece gerektiğinde 1'dir. İşlev, dizenin uzunluğu girişten daha azken döngüye girer, dizeye eklenir ve farkı ve sayıyı gerektiği gibi güncelleştirir ve ardından yazdırmadan önce kısalır.

Ideone üzerinde deneyin

Sonsuz çıktı sürümü, 69 bayt

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

1

R, 92 bayt

    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)}

Örnek çıktı:

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 * 1" 102


0

Jöle , 22 19 18 bayt

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

Çevrimiçi deneyin!

nDizedeki ilk sayıları bulun ve listeye yıldız işareti ekleyin. Bu her zaman nOP'nin yorumlarda izin verdiğinden daha uzun olacaktır .

Program seçiciyi #döngüdeki sıradaki geçerli numarayla günceller ¹©=¡. Örneğin, ©ikinciden sonra bunun daha kısa olabileceğini umuyordum µ, ancak maalesef bu işe yaramadı ve daha kısa bir şey bulamadım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.