Tape Measure String
Python, 50 48 47 46 bytes
f=lambda x:x*"1"if x<2else f(x-len(`-x`))+`-x`
Explanation
Pretty simple recursive lambda solution
Our base cases are 1 and 0 which are covered by "1"*x
otherwise we get the string of -x
with `-x`
and prepend the result of calling the function on len(`-x`)
less.
Mathematica, 67 57 bytes
Thanks to Martin Ender for jettisoning 10 bytes!
""["1"][[#]]/._@__:>#0[#-1-IntegerLength@#]<>ToString@-#&
Unnamed function taking a nonnegative integer argument and returning a string. Pretty much the obvious recursive algorithm: make sure the string ends with the input number preceded by a "-"
, and then call the function again using #0
.
But there's golfy fun to be had in implementing the algorithm. ""["1"][[#]]
denotes the #
th argument of the expression ""["1"]
: the 0th argument is the head ""
and the 1st argument is visibly "1"
, which provides the base cases of the recursion. If #
exceeds 1, then ""["1"][[#]]
throws an error message and remains as an unevaluated function. But then /._@__:>
is a rule that takes any unevaluated function and transforms it into the expression that comes next, which is the recursive call to the original function.
Original submission:
If[#<2,""["1"][[#]],#0[#-1-IntegerLength@#]<>"-"<>IntegerString@#]&
JavaScript (ES6), 49 bytes
f=(n,s='',t=''+-n)=>n>1?f(n-t.length,t+s):n?n+s:s
<input type=number oninput=o.value=f(this.value)><br><textarea id=o></textarea>