# Create an unlimited counterstring

A counterstring is some sort of self-describing test data that is used in software testing. Not sure it was actually invented by James Bach, but I know it from there.

The idea is as follows: the test data contains many asterisk (*). The number in front of the asterisk tells you how long the test data is at that point. If you need to know a position in the test data that is not an asterisk, find the last asterisk, look at the number before and add the number of digits that follow.

The sequence starts like this:

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


As you can see, the marked asterisk is at position 14.

If a file happens to be truncated as follows

[...]2045*20


then you can derive that there is a limit of 2047 characters somewhere (2045 where the asterisk is plus 2 for 2 and 0).

It's your task to create the shortest (this is ) program that outputs (std::out or file or whatever) an arbitrary long test string of that format. The length in characters is given as argument. The program shall support up to 2 GB test data (input value 2147483647 characters).

"Dangerous" positions in the 2 GB file:

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


This should answer @Leaky Nun's question if there is a decision to make between 995*999* and 995*1000* or similar: no.

The end of the 2 GB file with input value 2147483647 is:

2147483640*2147483

• If it does not halt then how do you test it? – Leaky Nun Aug 23 '16 at 21:24
• Is that length in characters? – TheBikingViking Aug 23 '16 at 21:31
• Can you prove that we would never have to choose between 995*999* and 995*1000* or anything like that? – Leaky Nun Aug 23 '16 at 21:36
• In the future, please use the Sandbox to iron out kinks in your challenges before posting them. – Mego Aug 23 '16 at 22:05
• @ThomasWeller If we can create a longer output, can we take no input and just produce the 2GB string? – xnor Aug 24 '16 at 7:43

As a function we get:

f=length.show

### NB

• Requires v5, since the -noNewLine parameter was finally added in that version.
• PowerShell will automatically up-convert from [int] to [double] (no, I don't know why it doesn't go to [long]), so this will properly handle input up to and greater than 2147483648, without problem. Theoretically, it will handle input somewhere up to around 1.79769313486232E+308 (max value of [double]) before complaining, but I expect the disk to fill up before that happens. ;-)

# Python 3, 126114 99 bytes

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


A function that takes input via argument of the character count at which to truncate the string, and prints to STDOUT.

How it works

The difference between the numbers in the string is initially 2. Every time an order of magnitude is passed, this difference is increased by 1; this can be achieved by taking the difference between the number of digits of the current number and the number of digits of the current number added to the difference, which is 1 only when required. The function simply loops while the length of the string is less than the input, appends to the string and updates the difference and number as required, and then truncates before printing.

Try it on Ideone

Infinite output version, 69 bytes

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


# R, 92 bytes

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


Example 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"

# Jelly, 2219 18 bytes

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


Try it online!

Find the first n numbers in the string then join the list with an asterisk. This will always be longer than n which was allowed by OP in the comments.

The program selectively updates the register with the current number in the sequence in the # loop with ¹©=¡. I was hoping this could be shorter, by putting © after the second µ for example, but unfortunately that doesn't work and I couldn't figure out any thing shorter.