Appending String Lengths

Challenge:

Given a string s on the characters a-z, A-Z, 0-9, append the length of s to itself, counting the additional character(s) in the length as part of the total length of s.

Input:

Just a string of arbitrary length (can be empty).

Output:

The same string, but with its length appended to the end. The characters that represent the length should also be counted as part of the length. In cases where there are multiple valid lengths to append, choose the smallest one possible (see test cases for examples).

Test Cases:

INPUT     -> OUTPUT       // Comment
aaa       -> aaa4
-> 1            // Empty string
aaaaaaaa  -> aaaaaaaa9    // aaaaaaaa10 would also normally be valid, but violates using the smallest number rule mentioned above
aaaaaaaaa -> aaaaaaaaa11
a1        -> a13          // Input can contain numbers at the end of the string, you do not have to handle the fact that it looks like 13 rather than 3.

Longer test case(s):

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102


Rules:

This is , so shortest code in bytes wins. Standard loopholes are forbidden. Submissions may be an entire program or a function, and you may either print the result to stdout or return it as a variable from a function.

• What characters can appear in the input? Dec 16, 2016 at 21:48
• @MartinEnder Alphanumerical characters only, 0-9 and A-Z/a-z. So yes, you can have strings with numbers at the end. I'll add a test case for one. Dec 16, 2016 at 22:42

JavaScript (ES6), 32 bytes

f=(s,n=0)=>(s+n)[n]?f(s,n+1):s+n


How it works

f = (s, n = 0) =>   // given a string 's' and starting with n = 0:
(s + n)[n] ?      // if the Nth character of (s + n) exists:
f(s, n + 1)     //   try again with n + 1
:                 // else
s + n           //   return s + n


Starting with N=0, we test the Nth character (0-based) of the string made of the concatenation of the original input string and the decimal representation of N. We increment N until this character doesn't exist anymore.

Example:

N =  0 : abcdefghi0
^
N =  1 : abcdefghi1
^
N =  2 : abcdefghi2
^
...
N =  8 : abcdefghi8
^
N =  9 : abcdefghi9
^
N = 10 : abcdefghi10
^
N = 11 : abcdefghi11    -> success
^


Test cases

f=(s,n=0)=>(s+n)[n]?f(s,n+1):s+n

console.log(f("aaa"));       // -> aaa4
console.log(f(""));          // -> 1
console.log(f("aaaaaaaa"));  // -> aaaaaaaa9
console.log(f("aaaaaaaaa")); // -> aaaaaaaaa11
console.log(f("a1"));        // -> a13

• Wow, JS is much terser than Python for this. Dec 16, 2016 at 22:57
• @Arnauld I cannot get my head around this. Do you mind explaining how this code works? Dec 18, 2016 at 15:46

LaTeX, 108/171

\newcounter{c}\def\s#1#2]{\stepcounter{c}\def\t{#2}\ifx\empty\t\arabic{c}\else#1\s#2]\fi}\def\q[#1]{\s#10]}


\q[] //1

• Whoa, I don't think I've ever seen a latex answer on ppcg before. Dec 17, 2016 at 16:02

JavaScript (ES6), 37 bytes

f=(s,t=s,u=s+t.length)=>t==u?t:f(s,u)
<input oninput=o.textContent=f(this.value)><pre id=o>

• When I clicked on Run Code Snippet I get to see an error message. I have no knowledge of Javascript - I was just trying Dec 17, 2016 at 8:42
• @Prasanna Works for me in Firefox; which browser are you using?
– Neil
Dec 17, 2016 at 10:54
• @Prasanna Works on latest Google Chrome. Are you sure you aren't using IE11 or older, Opera or anything that doesn't support ES6? Dec 17, 2016 at 20:41
• I'm using an old good chrome (Version 48.0.2564.97). I will try this with IE too. Can't update my chrome - office security issues Dec 19, 2016 at 8:38

Lua 5.2, 32 Bytes

a=arg[1]print(a..#a+#(''..#a+1))


Where the variable a is the input string.

C, 6765 61 bytes

x;f(*v){printf("%d",(int)log10(x=-~printf(v))*-~(x%10>8)+x);}


Wandbox

• Ohh, yeah, I shoulda printf'd... Anyways, congrats on having the shorter C solution :D +1
– cat
Dec 17, 2016 at 16:05

Pyth - 7 bytes

+Qfql+Q


Mathematica, 57 bytes

#<>ToString[(a=Length@#)+(i=IntegerLength)[a+i@a]~Max~1]&


Unnamed function taking an array of characters as input and returning a string. Uses the fact that if a is the length of the input, then the number to append to the input is a plus the number of digits in (a + the length of a), rather than just a plus the number of digits of a. Unfortunately it wouldn't give the right answer for the empty-string input without the ~Max~1 special case.

Pyke, 8 bytes (old version)

.f+liq)+


Explanation:

.f    )  -  first where (i++)
+      -    input + i
l     -    len(^)
iq   -   ^ == i
+ - input + ^


Try it here! (New version, 9 bytes)

• It always confuses me how buried the actual output is among warnings or other messages :-) Dec 16, 2016 at 23:28
• I should really get around to fixing the web bug in the copy link that automatically disables the warnings switch
– Blue
Dec 16, 2016 at 23:31

Python 2, 5448 46 bytes

Simple solution. Recursion ended up being shorter.

f=lambda s,n=0:f(s,n+1)if(s+n)[n:]else s+n


Try it online

• I think you can do (s+n)[n:] for n<len(s+n).
– xnor
Dec 16, 2016 at 22:48

f s=[l|i<-[0..],l<-[s++show i],length l==i]!!0


Usage example: f "aaaaaaaa" -> "aaaaaaaa9".

Simply try all numbers starting with 0 and take the first that fits.

Brachylog, 13 bytes

l<L$@:?rc.lL,  Try it online! Explanation Basically a description of the problem. It will try every value of L bigger than the length of the input until it finds one for which, when concatenated to the input, is the length of that concatenation. l<L length(Input) < L L$@            Convert L to a string
:?rc.       The Output is the concatenation of the Input with L as string
.lL,    The length of the Output is L itself


Perl 6,  46  35 bytes

{$_~(.chars,*.chars+.chars...{$^a==$^b})[*-1]}  {$_~(.chars,*.chars+.chars...*)[2]}


Try it

Expanded:

{   # bare block lambda with implicit parameter ｢$_｣$_  # the input

~   # concatenated with

(  # sequence generator

.chars,  # the number of chars in ｢$_｣ (seed the generator) *\ # Whatever lambda input (represents previous value) .chars # number of chars in that + # plus .chars # the number of chars in ｢$_｣

...     # keep doing that until

*       # indefinitely

)[2] # get the value at index 2 of the sequence
}


Brainfuck, 258 bytes

,>+<----------[++++++++++>+[>+<-],----------]<[<]>[.>]>>>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>[-]>>[>++++++[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->++++++++<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]


The input must be terminated by a linefeed (LF). Only works for inputs with a length lesser than 256 (including the LF).

Try it online!

Explanation

# read first char and add one to cell #1
# the cell after the input will contain the length
,>+<
# subtract 10 to check for LF
----------
# while the input is not 10 (LF)
[
# restore the input to its original value
++++++++++
# add one to the length
>+
# cut and paste the length to the next cell, then read the input
[>+<-],
# subtract 10 to check for LF
----------
]
# for input abc, the tape here would be: a b c *0* 4
# rewind to the beginning of the input
<[<]>
# print the input string
[.>]>
# convert the length to ascii chars and output them
>>++++++++++<<[->+>-[>+>>]>[+[-<+>]>+>>]<<<<<<]>>[-]>>>++++++++++<[->-[>+>>]>[+[-
<+>]>+>>]<<<<<]>[-]>>[>++++++[-<++++++++>]<.<<+>+>[-]]<[<[->-<]++++++[->++++++++
<]>.[-]]<<++++++[-<++++++++>]<.[-]<<[-<+>]


Note: I used code from this SO answer to convert the length to ascii output; I hope this is acceptable on PPCG. This is my first Codegolf submission, and my second BF program. Feedback is welcomed.

• This isn't valid then, it must pass all test cases
– cat
Dec 17, 2016 at 16:05
• So supporting a length up to 999 would be enough? Dec 17, 2016 at 16:10
• The spec says "arbitrary length" which means "as long as your language is capable of handling or without running out of memory"
– cat
Dec 17, 2016 at 16:11
• The brainfuck interpreter you're using has 8-bit cells, so as long as your algorithm works for strings of arbitrary length, it should be fine if it fails for strings of length 256 or higher. The C and JavaScript submissions will also fail once the strings get too long. Dec 17, 2016 at 16:17
• Thank you Dennis, I will modify my submission accordingly Dec 17, 2016 at 23:11

Python, 39 bytes

lambda a:eval('a+str(len('*3+'a))))))')


Longer form:

lambda a:a+str(len(a+str(len(a+str(len(a))))))


Iteratively in Python 2 (41 bytes):

x=a=input();exec"x=a+len(x);"*3;print x


Starting with x as the input string a, applies the transformation x -> a + str(len(x)) three times. I'm still not clear why three applications are needed to always reach the fixed point.

• Why 3 times? First to append the length of text, second to adjust the length to include the number, third in case that adjustment added an extra digit. Jan 19, 2017 at 21:53

Retina, 22 bytes

\G
.
x
+r\d*._
x



Try it online!

Ah well, if it wasn't for digits appearing in the input, this would be merely 11 bytes:

+r\d*._


Ruby, 6258 56 bytes

s=gets.chomp;p s+"#{(s+"#{(s+"#{s.size}").size}").size}"


Tested in irb.

There's probably a better way to do this, but this was the first thing I came up with. Any help in golfing would be appreciated.

edit: I realized my use of parentheses was excessive.

• You only use l in one place. If you inline that, you will save 3 bytes l=;. But your solution will still be longer than mine ;) Dec 17, 2016 at 1:59

05AB1E, 11 bytes

[¹¾JDg¾Q#¼\


Pretty straightforward bruteforce:

            Implicit i = 0
[           while true
¹¾J        Concatenate input and i -> str
Dg¾Q#   Break if length(str) == i
¼\ Else, i += 1


Try it online!

PHP, 42 bytes

while(++$n<strlen($a=$argv[1].$n));echo$a;  Run with -r. Test at OnlinePHPfunctions. bash, 47 bytes  for((n=-1;${#s} != $n;));{ s=$1$[++n];};echo$s


Save this as a script, and pass the input string as an argument.

It's a brute force implementation: try each number in turn until you find one which works.

><> (Fish) 35 bytes

i:1+?!v:o
ln;v9l<  >
*9+>:&)?!^1l&a


Takes input onto the stack, checks the length against values 9,99,999... and if the length is larger than add 1 to the stack length.

e=length
l%n|s<-show$l+1,n>e s=s|m<-n+1=(l+1)%m c s=s++e s%2  Try it online! Recursive solution. Usage: Prelude> c "aaaaaaaaa" "aaaaaaaaa11"  Ruby, 43 36 bytes Anonymous function, abusing the $. global.

->s{$.+=1while(t=s+"#$.").size>$.;t}  Call it like this: f = ->s{$.+=1while(t=s+"#$.").size>$.;t}
f[""]          # => "1"
f["a"]         # => "a2"
f["aaaaaaa"]   # => "aaaaaaa8"
f["aaaaaaaa"]  # => "aaaaaaaa9"
f["aaaaaaaaa"] # => "aaaaaaaaa11"


Vyxal, 6 bytes

LJL+LJ


Try it Online!

Append the length of the string, take the length of that, then append the new length to the original. This does work with digit overflows (9, 99, etc...).

• There's probably something I can do with iteratively adding and appending lengths until they are the same.... Oct 6, 2022 at 17:54
• The code looks especially funny if you change the + to an J, which works fine: LJLJLJ Oct 6, 2022 at 20:01
• You actually don't need the Ṡ flag. Oct 6, 2022 at 20:01
• 3(LJ for 4 bytes Nov 2, 2022 at 13:25
• oh..... but mine is funnier :p Nov 2, 2022 at 13:27

Pip, 8 bytes

L3Ya.#yy


Try It Online!

Explanation

Inspired by Pacmanboss256's Vyxal solution.

          ;; y is empty string; a is first command-line argument (implicit)
L3        ;; Loop 3 times:
a.     ;;  Concatenate a with
#y   ;;  Length of y
Y       ;;  Assign the result to y
y  ;; After the loop, output y


Some worked examples:

Input a        ""    "aaa"    "aaaaaaaaa"
Original y     ""    ""       ""
After loop 1   "0"   "aaa0"   "aaaaaaaaa0"
After loop 2   "1"   "aaa4"   "aaaaaaaaa10"
After loop 3   "1"   "aaa4"   "aaaaaaaaa11"

• +1, neat loop setup Oct 7, 2022 at 3:04

K (ngn/k), 31 bytes

{$[9>t:#x;x,$1+t;x,$#x,($1+t)]}


Try it online!

+22 bytes thanks to Dominic van Essen for pointing out a not-working test case (that should have worked)

• I think this fails for "aaaaaaaaa": it outputs "aaaaaaaaa10" which is 11 characters long... Dec 5, 2022 at 16:45
• @DominicvanEssen ohhhhhhhh... now I understand why.
– oeuf
Dec 8, 2022 at 8:35
• fails for the longer test cases (i.e. you dont handle strings of length 99+)
– mkst
Jul 14 at 10:21
• {x,$#x,$#x,$#x} for 15 bytes i think? – mkst Jul 14 at 10:25 • {{y,$#x}/4#,x} for 14 bytes, maybe golfable further?
– mkst
Jul 14 at 10:31

C#, 77 bytes

n=>{int a=n.Length;int c=(a+1).ToString().Length-1;return(n+(n.Length+1+c));}

• I don't now C#, but couldn't you use return(n+(a+1+c)) as a=n.Length ? Dec 16, 2016 at 23:44
• And also drop the -1 from int c=(a+1).ToString().Length-1 and the +1 from the return? Dec 16, 2016 at 23:46
• Wait, does this handle the larger test cases correctly? It looks like it returns aa...a100 instead of aa...a101 for the 99a test case. Dec 16, 2016 at 23:52

MATL, 11 bytes

G@Vhtn@>]&

      % Do...while
G    %   Push input
@    %   Push iteration index (1-based)
V    %   Convert number to string
h    %   Concatenate horizontally
t    %   Duplicate
n    %   Get length of concatenated string
@    %   Push iteration index
>    %   True if length of concatenated string exceeds iteration index
]      % End. Run next iteration if top of stack is true; else exit loop
&      % Specifiy that next function (implicit display) takes only one input
% Implicitly display top of the stack. This is the concatenated string
% that had a length equal to the iteration index


Ruby, 49 bytes (function)

Program (last newline is not necessary and thus unscored):

x=gets.strip
i=0
i+=1 until(y=x+i.to_s).size==i
p y


Function (last newline is scored):

def f x
i=0
i+=1 until(y=x+i.to_s).size==i
y
end


Factor, 55 bytes

It's a walk in the park! I came up with this in my head as soon as I read the question.

[ dup length dup log10 ⌈ + >integer 10 >base append ]


Clojure, 72 bytes

(defn f([s](f s 1))([s n](if(=(count(str s n))n)(str s n)(f s(inc n)))))
`