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

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! – Dennis Aug 12 '16 at 1:59
• Yet it looks like some angry driver. – Jonathan Allan Aug 12 '16 at 2:11

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.

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 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. – Emigna Aug 11 '16 at 23:30 • @Emigna Yeah, but it looks rather a bit long. I should probably make a builtin for that builtin :P. – Adnan Aug 11 '16 at 23:32 • A builtin for padding would be really useful as well. – Emigna Aug 11 '16 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. – Destructible Lemon Aug 12 '16 at 0:00 • You can use ​x​ instead of str(x). Also, you don't need the [] around the generator. – Dennis Aug 12 '16 at 0:01 • You outgolfed me again... serous times call for serious measures: I'm gonna have to change to python 2 – Destructible Lemon Aug 12 '16 at 0:13 • goddamnit you did it again! – Destructible Lemon Aug 12 '16 at 0:32 • You don't need the parens in while(n). – Dennis Aug 12 '16 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 °_° – Karl Napf Aug 12 '16 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! – Rɪᴋᴇʀ Aug 12 '16 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 – Conor O'Brien Aug 11 '16 at 23:28 • @ConorO'Brien I actually thought about that, but then the names would look really similar and confusing :p. – Adnan Aug 11 '16 at 23:31 • you mean 15AB1E – ASCII-only Aug 12 '16 at 1:23 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 '16 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 – Value Ink Aug 12 '16 at 18:37

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? – Karl Napf Aug 12 '16 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 ._. – Destructible Lemon Aug 12 '16 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. – Dennis Aug 12 '16 at 0:44
• In Python 2, / performs integers division foe.integer arguments. – Dennis Aug 12 '16 at 2:18

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. – user81655 Aug 12 '16 at 5:33
• @user81655 - it gives me Uncaught SyntaxError: Invalid or unexpected token. Haven't debugged yet as I'm just awake :D – eithed Aug 12 '16 at 7:16
• Hmmm. It might be hidden characters which are sometimes added to SO comments. Try writing it out. – user81655 Aug 12 '16 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)),"")[][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)),"")[][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[][i]

• try using str_pad() – hedgedandlevered Aug 12 '16 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 – Frédéric Aug 22 '16 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)";$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
e[   e# Left pad
}/

PHP, 83 78 bytes

<?$a=$argv;$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 is the int.

Thanks to:

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

• You can change echo sprintf(...) -> printf(...) – Alex Gittemeier Aug 25 '16 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 at 4:17