Buat counterstring tanpa batas

11

Sebuah counterstring adalah semacam data uji self-describing yang digunakan dalam pengujian perangkat lunak. Tidak yakin itu sebenarnya diciptakan oleh James Bach , tapi saya tahu itu dari sana.

Idenya adalah sebagai berikut: data uji berisi banyak asterisk ( *). Angka di depan tanda bintang memberi tahu Anda berapa lama data uji pada titik itu. Jika Anda perlu mengetahui posisi dalam data uji yang bukan tanda bintang, cari tanda bintang terakhir, lihat nomor sebelumnya dan tambahkan jumlah digit yang mengikuti.

Urutannya dimulai seperti ini:

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

Seperti yang Anda lihat, tanda bintang yang ditandai ada di posisi 14.

Jika suatu file terpotong sebagai berikut

[...]2045*20

maka Anda dapat memperoleh bahwa ada batas 2047 karakter di suatu tempat (2045 di mana tanda bintang plus 2 untuk 2dan 0).

Adalah tugas Anda untuk membuat program terpendek (ini adalah ) yang menampilkan (std :: out atau file atau apa pun) string uji panjang sewenang-wenang dari format itu. Panjang karakter diberikan sebagai argumen. Program harus mendukung hingga 2 GB data uji (nilai input 2147483647 karakter).

Posisi "Berbahaya" dalam file 2 GB:

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

Ini harus menjawab pertanyaan @Leaky Nun jika ada keputusan untuk membuat antara 995 * 999 * dan 995 * 1000 * atau serupa: tidak.

Akhir dari file 2 GB dengan nilai input 2147483647 adalah:

2147483640*2147483
Thomas Weller
sumber
Jika tidak berhenti maka bagaimana Anda mengujinya?
Leaky Nun
2
Apakah karakter itu panjang?
TheBikingViking
4
Bisakah Anda membuktikan bahwa kami tidak akan pernah harus memilih antara 995*999*dan 995*1000*atau sesuatu seperti itu?
Leaky Nun
1
Di masa depan, silakan gunakan Kotak Pasir untuk memperbaiki kekusutan dalam tantangan Anda sebelum mempostingnya.
Mego
1
@ThomasWeller Jika kita dapat membuat output yang lebih panjang, bisakah kita tidak mengambil input dan hanya menghasilkan string 2GB?
xnor

Jawaban:

4

Haskell, 60 58 byte

Sebagai fungsi kita dapatkan:

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

Program penuh, 72 70 byte

Ini menghasilkan counterstring tak terbatas untuk STDOUT:

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

Memasukkan panjang membutuhkan 20 byte tambahan:

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

Ini berfungsi hingga kira-kira ukuran RAM Anda, karena Haskell default tipe integral numerik untuk Integer.

ThreeFx
sumber
3

Pyth, 25 17 15 14 byte

<uu++GlN\*k)Qk

Cobalah online.

Panjang diambil melalui STDIN.

PurkkaKoodari
sumber
2

Python 2, 74 72 66 64 61 Bytes

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

Mengambil bilangan bulat n dan menghasilkan panjang hitung mundur n.

versi program, 69 Bytes:

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

Mengambil integer n dari stdin dan mencetak counterstring dengan panjang n.

Versi alternatif yang lebih pendek, tetapi hanya berfungsi, hampir:

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

PowerShell v5, 97 byte

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

Mengambil input sebagai argumen baris perintah $n, menyetel helper $lyang kami gunakan untuk melacak panjang integer kami. Lalu, kita putar dari 0atas ke $n. Setiap iterasi, kami bertambah $idengan .lengthstring yang terbentuk dari $idan tanda bintang. Kemudian, jika .lengthdari $iberubah (misalnya, kami pindah dari 2 digit ke 3 digit), kita kenaikan kedua pembantu $lvariabel ength dan $i(untuk akun untuk digit tambahan). Kami kemudian menggunakan add-contentperintah untuk menambahkan "$i*"file .\odalam direktori saat ini, dengan -noNewLine.

NB

  • Membutuhkan v5, karena -noNewLineparameter akhirnya ditambahkan di versi itu.
  • PowerShell akan secara otomatis mengkonversi dari [int]menjadi [double](tidak, saya tidak tahu mengapa itu tidak masuk [long]), jadi ini akan menangani input hingga dan lebih dari 2147483648, tanpa masalah. Secara teoritis, ini akan menangani input di suatu tempat hingga sekitar 1.79769313486232E+308(nilai maks [double]) sebelum mengeluh, tapi saya berharap disk untuk diisi sebelum itu terjadi. ;-)
  • Karena pemeriksaan bersyarat loop, ini akan menampilkan ke file minimum dari panjang input. Sebagai contoh, untuk input 10ini akan menghasilkan 2*4*6*8*11*, karena 11nilai pertama $ilebih besar dari input.

PowerShell v2 +, juga 97 byte (tidak bersaing)

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

Alih-alih mengirim ke file, ini merangkum iterasi loop dan kemudian -joinmereka bersama-sama menjadi sebuah string. Ini memungkinkannya bekerja untuk versi yang lebih awal dari v5. Namun, sejak. NET mendefinisikan [string]dengan konstruktor seperti String(char c,Int32 length), versi ini tidak memenuhi persyaratan input maks, karena string output akan meluap dan muntah.

Juga, Anda mungkin tidak ingin memiliki string ~ 2GB melayang di dalam pipa Anda. Katakan saja.

AdmBorkBork
sumber
1.79769313486232E + 308 tentu tidak akan berfungsi, karena menambahkan angka kecil ke pelampung tidak akan mengubah nilai lagi. Lihat stackoverflow.com/questions/12596695/... Jadi saya kira itu berhenti bekerja setelah "ditingkatkan" menjadi dua kali lipat
Thomas Weller
@ThomasWeller PowerShell [double]s adalah 64-bit. Sebagai contoh, menjalankan for($i=2147483645;$i-lt2147483655;$i++){"$i - " + $i.GetType()}akan menunjukkan perkembangan yang stabil dari $itetapi Typeperubahan di 2147483648ke double. Saya yakin pada titik tertentu itu akan berhenti bekerja, kemungkinan sekitar ~ 15 digit presisi atau ketika .ToStringmulai menggunakan e. Itu [double]::MaxValuelebih seperti lelucon membuang-buang daripada batas atas yang serius.
AdmBorkBork
1

Python 3, 126 114 99 byte

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

Fungsi yang mengambil input melalui argumen jumlah karakter yang digunakan untuk memotong string, dan mencetak ke STDOUT.

Bagaimana itu bekerja

Perbedaan antara angka-angka dalam string awalnya 2. Setiap kali urutan besarnya dilewati, perbedaan ini meningkat sebesar 1; ini dapat dicapai dengan mengambil perbedaan antara jumlah digit dari angka saat ini dan jumlah digit dari angka saat ini ditambahkan ke perbedaan, yaitu 1 hanya bila diperlukan. Fungsi ini hanya loop sementara panjang string kurang dari input, ditambahkan ke string dan memperbarui perbedaan dan nomor yang diperlukan, dan kemudian memotong sebelum dicetak.

Cobalah di Ideone

Versi keluaran tanpa batas, 69 byte

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

R, 92 byte

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

Contoh output:

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 "

JDL
sumber
0

Jelly , 22 19 18 byte

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

Cobalah online!

Temukan nangka pertama dalam string kemudian gabungkan daftar dengan tanda bintang. Ini akan selalu lebih lama dari nyang diizinkan oleh OP dalam komentar.

Program secara selektif memperbarui register dengan nomor saat ini dalam urutan dalam #loop dengan ¹©=¡. Saya berharap ini bisa lebih pendek, dengan menempatkan ©setelah µcontoh misalnya, tapi sayangnya itu tidak berhasil dan saya tidak dapat menemukan hal yang lebih pendek.

dylnan
sumber