# Make a (somewhat) self-referential string

You want to make a string where the (1-indexed) character at index n is n. When n is less than 10, this is easy: "123456789". When n is 12, for example, it becomes impossible, since numbers greater than 9 (in base 10) take up more than one character. We can compromise by dividing the string into two-character substrings: "020406081012". Now the index of the end of each substring n is n.

This can be generalized for any d-digit number. Here's an explanation for the "0991021" part of the string for a three-digit number:

Index:     ... * 97  98  99*100 101 102*103 ...
*           *           *
*---+---+---*---+---+---*---+
Character: ... * 0 | 9 | 9 * 1 | 0 | 2 * 1 | ...
*---+---+---*---+---+---*---+


If you haven't figured it out yet, you are to write a program/function that takes a string or integer and output its self-referential string as specified above. You can also output an array of single-digit numbers, chars, or single-character strings.

The given integer will always be positive and divisible by its length (e.g. 126 is divisible by 3; 4928 is divisible by 4). Your program should theoretically work for an arbitrarily large input, but you can assume it is smaller than your language's maximum integer and/or string length.

Some observations if you still don't get it: The length of the output will always be the input itself, and the numbers that appear in the output will be divisible by the number of digits in the input.

This is , so shortest answer in bytes wins.

## Test cases

1    => 1
9    => 123456789
10   => 0204060810
105  => 003006009012015018021024027030033036039042045048051054057060063066069072075078081084087090093096099102105
1004 => 00040008001200160020002400280032003600400044004800520056006000640068007200760080008400880092009601000104010801120116012001240128013201360140014401480152015601600164016801720176018001840188019201960200020402080212021602200224022802320236024002440248025202560260026402680272027602800284028802920296030003040308031203160320032403280332033603400344034803520356036003640368037203760380038403880392039604000404040804120416042004240428043204360440044404480452045604600464046804720476048004840488049204960500050405080512051605200524052805320536054005440548055205560560056405680572057605800584058805920596060006040608061206160620062406280632063606400644064806520656066006640668067206760680068406880692069607000704070807120716072007240728073207360740074407480752075607600764076807720776078007840788079207960800080408080812081608200824082808320836084008440848085208560860086408680872087608800884088808920896090009040908091209160920092409280932093609400944094809520956096009640968097209760980098409880992099610001004


# C, 64 bytes

l,i;main(n){for(scanf("%d%n",&n,&l);i<n;)printf("%0*d",l,i+=l);}


Takes a single integer as input on stdin.

## JavaScript (ES6), 83 bytes

n=>[...Array(n/(l=${n}.length))].map((_,i)=>${+1e${l}+l*++i}.slice(1)).join  Yes, that's a nested template string. 79 bytes in ES7: n=>[...Array(n/(l=${n}.length))].map((_,i)=>${10**l+l*++i}.slice(1)).join  # Jelly, 12 bytes VRUmLDUz0ZFU  I/O is in form of digit arrays. Try it online! or verify all test cases. ### How it works VRUmLDUz0ZFU Main link. Argument: A (digit array) V Eval; turn the digits in A into an integer n. R Range; yield [1, ..., n]. U Upend; reverse to yield [n, ..., 1]. L Yield the length (l) of A. m Modular; keep every l-th integer in A. D Decimal; convert each kept integer into the array of its digits. U Upend; reverse the digits of each integer. z0 Zip/transpose with fill value 0. Z Zip again. This right-pads all digit arrays with zeroes. F Flatten the resulting 2D array. U Upend/reverse it.  • Look 'ma, no Unicode! Aug 12, 2016 at 1:59 • Yet it looks like some angry driver. Aug 12, 2016 at 2:11 # MATL, 15 14 bytes VntG3$:10YA!1e


Try it online!

V        % Implicitly input number, n. Convert to string
n        % Length of that string, s
t        % Duplicate s
G        % Push n again
3$: % 3-input range (s,s,n): generates [s, 2*s, ... ] up to <=n 10YA % Convert each number to base 10. This gives a 2D array of char, with each % number on a row, left-padded with zeros if needed !1e % Reshape into a string, reading in row-major order. Implicitly display  # 05AB1E, 15 bytes Code: LD¹gÖÏvy0¹g×0ñ?  Explanation: L # Get the array [1, ..., input]. D # Duplicate this array. ¹g # Get the length of the first input. Ö # Check if it's divisible by input length. Ï # Keep those elements. vy # For each... ¹g # Get the length of the first input. 0 × # String multiply that with "0". 0ñ # Merge with the number. ? # Pop and print without a newline.  The merging is done like this: From these: 000 12  It results into this: 012  Uses the CP-1252 encoding. Try it online!. • Cool! Didn't know that ñ worked like that. Aug 11, 2016 at 23:30 • @Emigna Yeah, but it looks rather a bit long. I should probably make a builtin for that builtin :P. Aug 11, 2016 at 23:32 • A builtin for padding would be really useful as well. Aug 11, 2016 at 23:33 # Python 2, 78706864 63 bytes Actually basing on the idea of Destructible Watermelon makes it even smaller (using input is even better)(filling the string backward saves 4 bytes)(no () at while): n,s=input(),'' l=len(n) while n:s=n.zfill(l)+s;n-=l print s  Here is the old 70 byte approach (Saving 8 bytes by using backquotes instead of str and dropping the square brackets around generator thanks to Dennis): def f(n):l=len(n);print"".join(x.zfill(l)for x in range(l,n+l,l))  • I forgot about zfill... darn. Aug 12, 2016 at 0:00 • You can use ​x​ instead of str(x). Also, you don't need the [] around the generator. Aug 12, 2016 at 0:01 • You outgolfed me again... serous times call for serious measures: I'm gonna have to change to python 2 Aug 12, 2016 at 0:13 • goddamnit you did it again! Aug 12, 2016 at 0:32 • You don't need the parens in while(n). Aug 12, 2016 at 2:18 # Python 2, 63 bytes def f(n):l=len(n);print'%%0%dd'%l*(n/l)%tuple(range(l,n+1,l))  Test it on Ideone. • Dat format string °_° Aug 12, 2016 at 1:32 # JavaScript (ES6), 66 Recursive, input n as a string (not a number) and limiting the output string size to 2GB (that is above the string limit of most javascript engines) f=(n,i=1e9,s='',l=n.length)=>s[n-1]?s:f(n,i+=l,s+(i+'').slice(-l))  Test f=(n,i=1e9,s='',l=n.length)=>s[n-1]?s:f(n,i+=l,s+(i+'').slice(-l)) function test() { var v=I.value; Alert.textContent=v % v.length ? 'Warning: input value is not divisible by its string length':'\n'; Result.textContent=f(v); } test() <input type=number id=I value=105 oninput='test()' max=500000> <pre id=Alert></pre> <pre id=Result></pre> # R, 6664 62 bytes edit: x=nchar(n<-scan());paste0(str_pad(1:(n/x)*x,x,,0),collapse="") first golf attempt... • Hi, and welcome to PPCG! Nice first post! Aug 12, 2016 at 17:55 # 2sable, 13 bytes Code: g©÷F®N>*0®×0ñ  Uses the CP-1252 encoding. • why didn't you name this 05AB1F? :3 Aug 11, 2016 at 23:28 • @ConorO'Brien I actually thought about that, but then the names would look really similar and confusing :p. Aug 11, 2016 at 23:31 • you mean 15AB1E Aug 12, 2016 at 1:23 # Python 3 2, 7974696568 67 bytes Thanks Dennis! def f(n):i=l=len(n);s='';exec n/l*"s+=i.zfill(l);i+=l;";print s  byte count increase from bad output method • Shouldnt it be len(x) instead of f and then save bytes by assigning it to a variable? Aug 12, 2016 at 0:09 • I don't think so.. what do you mean. Also, I would have outgolfed you with python 2, but some stupid stuff it happening right now ._. Aug 12, 2016 at 0:27 • You seem to have switched to Python 2. Also, per consensus on meta, using backspace to overwrite part of the output is only allowed in ASCII art challenges. Aug 12, 2016 at 0:44 • In Python 2, / performs integers division foe.integer arguments. Aug 12, 2016 at 2:18 # Brachylog, 53454237 28 bytes lB,?ybeN:B%0,N:ef:{,"0":"9"y:?m.}acAl:Br-:"0"rjb:Acw\ lB,?ybeN:B%0,10:B^:N+:ef:{,"0":"9"y:?m.}acbw\ lB,?ybeN:B%0,10:B^:N+:ef:{:16+:@Prm.}acbw\ lB,?ybeN:B%0,10:B^:N+:efbe:16+:@Prmw\ lB,?ybeN:B%0,10:B^:N+:efbew\  Try it online! # Bash, 31 22 bytes seq -ws ''${#1}{,} $1  Test it on Ideone. Thanks to @izabera for golfing off 6 bytes! # Ruby, 52 48 + n flag = 49 bytes ((l= ~/$/)..$_.to_i).step(l){|j|$><<"%0#{l}d"%j}

• Maybe you don’t need to chop if you assume input is passed without a trailing newline? I’m not sure if that’d work. Or how about assuming there always is one, and writing l=~-size?
– Lynn
Aug 12, 2016 at 11:28
• @Lynn calling size like that doesn't work for me. Oh well, I remembered a trick I had used in an earlier answer that's shorter anyways Aug 12, 2016 at 18:37

# zsh, 28 bytes

printf %0$#1d {$#1..$1..$#1}


# zsh + seq, 2120 bytes

This is pretty much the same answer as Dennis but in 20 bytes because zsh

seq -ws '' $#1{,}$1


f n|k<-length$show n=[k,2*k..n]>>=tail.show.(+10^k)  ## Perl, 40 bytes 39 bytes code + 1 for -n. $}=y///c;printf"%0$}d",$i+=$}while$i<$_  ### Usage echo -n 9 | perl -ne '$}=y///c;printf"%0$}d",$i+=$}while$i<$_' 123456789 echo -n 10 | perl -ne '$}=y///c;printf"%0$}d",$i+=$}while$i<$_' 0204060810 echo -n 102 | perl -ne '$}=y///c;printf"%0$}d",$i+=$}while$i<$_' 003006009012015018021024027030033036039042045048051054057060063066069072075078081084087090093096099102 echo -n 1000 | perl -ne '$}=y///c;printf"%0$}d",$i+=$}while$i<$_' 0004000800120016002000240028003200360040004400480052005600600064006800720076008000840088009200960100010401080112011601200124012801320136014001440148015201560160016401680172017601800184018801920196020002040208021202160220022402280232023602400244024802520256026002640268027202760280028402880292029603000304030803120316032003240328033203360340034403480352035603600364036803720376038003840388039203960400040404080412041604200424042804320436044004440448045204560460046404680472047604800484048804920496050005040508051205160520052405280532053605400544054805520556056005640568057205760580058405880592059606000604060806120616062006240628063206360640064406480652065606600664066806720676068006840688069206960700070407080712071607200724072807320736074007440748075207560760076407680772077607800784078807920796080008040808081208160820082408280832083608400844084808520856086008640868087208760880088408880892089609000904090809120916092009240928093209360940094409480952095609600964096809720976098009840988099209961000  # k4, 27 {,/"0"^(-c)$$c*1+!_x%c:#$x}


Not really golfed at all, just a straight-forward implementation of the spec.

                        $/ string # / count c: / assign to c x% / divide x by _ / floor ! / range (0-based) 1+ / convert to 1-based c* / multiply by count$             / string
(-c)               / negative count
/ pad (negative width -> right-aligned) "0"^ / fill blanks with zeros ,/ / raze (list of string -> string)  # Javascript - 76 n=>eval('c="";for(a=b=(""+n).length;a<=n;a+=b)c+={+1e${b}+a}.slice(1)')  or 71 if allowing for string arguments: n=>eval('c="";for(a=b=n.length;a<=n;a+=b)c+=${+1e${b}+a}.slice(1)')  Thanks to @user81655! Ungolfed: function x(n) { c = "", a = b = (""+n).length; while(a<=n) { c=c+"0".repeat(b-(""+a).length)+a a+=b; } return c; }  much place for improvement, but i'm tired right now • Nice! I found a few improvements that could be made (76 bytes): n=>eval('c="";for(a=b=(""+n).length;a<=n;a+=b)c+=${+1e${b}+a}.slice(1)'). The main bits are using a for loop and Neil's 1e${b} trick. Aug 12, 2016 at 5:33
• @user81655 - it gives me Uncaught SyntaxError: Invalid or unexpected token. Haven't debugged yet as I'm just awake :D Aug 12, 2016 at 7:16
• Hmmm. It might be hidden characters which are sometimes added to SO comments. Try writing it out. Aug 12, 2016 at 7:21

# R, 149142 138 bytes

x=rep(0,n);a=strtoi;b=nchar;for(i in 1:(n=scan()))if(!i%%b(a(n)))x[i:(i-b(a(i))+1)]=strsplit(paste(a(i)),"")[[1]][b(a(i)):1];cat(x,sep="")


Leaving nchar in the code gives a program with the same number of bytes than replacing it with b, but having random letters wandering around in the code makes it more... mysterious

Ungolfed :
Each nchar(strtoi(something)) permits to compute the number of numerals in a given number.

n=scan()   #Takes the integer
x=rep(0,n) #Creates a vector of the length of this integer, full of zeros

for(i in 1:n)
if(!i%%b(strtoi(n)))         #Divisibility check
x[i:(i-nchar(as.integer(i))+1)]=strsplit(paste(a(i)),"")[[1]][nchar(as.integer(i)):1];
#This part replace the zeros from a given position (the index that is divisible) by the numerals of this position, backward.

cat(x,sep="")


The strsplit function outputs a list of vectors containing the splitten elements. That's why you have to reach the 1st element of the list, and then the ith element of the vector, writing strsplit[[1]][i]

• try using str_pad() Aug 12, 2016 at 19:59
• @hedgedandlevered : well, this function needs a package (i.e. it cannot be run with vanilla R), and I don't want to use such while PPCG-ing Aug 22, 2016 at 20:40

# SQF - 164

Using the function-as-a-file format:

#define Q String""
l=(ceil log _this)+1;s='';for[{a=l},{a<=_this},{a=a+l}]do{c=([a]joinQ)splitQ;reverse c;c=(c+['0'])select[0,l];reverse c;s=format[s+'%1',c joinQ]}


Call as INTEGER call NAME_OF_COMPILED_FUNCTION

# PowerShell, 77 bytes

$x="$($args[0])";$l=$x.Length;-join(1..($x/$l)|%{"$($_*$l)".PadLeft($l,'0')})  Uses string interpolation to shorten string casts. The parts before the second semicolon shorten the names of reused things. Then, every integer up to the input - and only those that are multiples of the input's length - are padded to be as long as the input string and finally joined into one. ## Actually, 30 bytes ;╝R╛$l;)*@#"%0{}d"f╗#╜%MΣ╛@H


Try it online!

I'm not happy with the length of this code, but I'm not sure that it can be made much shorter (if at all).

Explanation:

;╝R╛$l;)*@#"%0{}d"f╗#╜%MΣ╛@H ;╝ duplicate input, push a copy to reg1 R range(1, input+1) ╛$l                          push input from reg1, stringify, length
;)                        duplicate and move copy to bottom of stack
*                       multiply range by length of input
@#                     swap range with length, make length a 1-element list
"%0{}d"f             "%0{}d".format(length) (old-style Python format string for zero-padding integers to length of input)
╗            save format string in reg0
#╜%M      for each value in range:
#            make it a 1-element list
╜%          format using the format string
Σ     concatenate
╛@H  take only the first (input) characters in the resulting string


# CJam, 19 bytes

q_,:V\i,%{V+sV0e[}/


Try it online. No one has posted in CJam yet, so this is the script I used for the test cases.

## Explanation

q_,:V  e# Store the length of the input as V
\i,    e# Push the range from 0 to the input
%      e# Keep only every V'th number in the array
{      e# Do this for each number:
V+   e# Add V to get the right number of leading zeroes
s    e# Convert to string for left padding
V    e# Push V, the length to bring each string to, and...
0    e# The character to add to the left
}/


## PHP, 83 78 bytes

<?$a=$argv[1];$i=$y=strlen($a);while($y<=$a){printf('%0'.$i.'d', $y);$y+=$i;}  Tips are more then welcome. Manage to golf it myself by one byte by changing it from a for loop to a while loop. This code assumes that this is being execute from the command line and that$argv[1] is the int.

## Thanks to:

@AlexGittemeier His suggestion (see comments) golfed this by 5 bytes to 78 bytes.

• You can change echo sprintf(...) -> printf(...) Aug 25, 2016 at 15:37

## Perl 6, 6959 46 bytes

{my \a=.chars;(a,2*a...\$_).fmt("%0"~a~"s","")}

• You can use fmt on the list instead of map, sprintf and [~]. 42 bytes
– Jo King
Mar 19, 2019 at 4:17