57
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ What characters can appear in the input? \$\endgroup\$ Commented Dec 16, 2016 at 21:48
  • \$\begingroup\$ @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. \$\endgroup\$
    – Yodle
    Commented Dec 16, 2016 at 22:42

51 Answers 51

1
2
1
\$\begingroup\$

Clojure, 72 bytes

(defn f([s](f s 1))([s n](if(=(count(str s n))n)(str s n)(f s(inc n)))))
\$\endgroup\$
1
\$\begingroup\$

R, 49 bytes

cat(a<-scan(,""),(t<-nchar(a))+nchar(t+1),sep='')

Pretty straightforward solution.

\$\endgroup\$
2
  • \$\begingroup\$ This doesn't work for me: Read 1 item Error in nchar(x + 1) : object 'x' not found. I found that (t<-nchar(a))+... did work. \$\endgroup\$
    – JAD
    Commented Dec 18, 2016 at 16:19
  • \$\begingroup\$ @JarkoDubbeldam : My bad ! \$\endgroup\$
    – Rudier
    Commented Dec 18, 2016 at 16:22
1
\$\begingroup\$

Wolfram, 56

#<>ToString@Nest[l+IntegerLength@#&,l=StringLength@#,2]&

Given l = StringLength[x] it appends l + IntegerLength[l + IntegerLength[l]] to x.

\$\endgroup\$
1
\$\begingroup\$

Labyrinth, 48 45 41 bytes

)"   10/{:@!
.,;: _ { _ ;
   })"}) 10-9!@

Try it online!

Saved 4 bytes thanked to @Martin Ender

\$\endgroup\$
0
1
\$\begingroup\$

ForceLang, 83 bytes

set s io.readln()
label 1
set n 1+n
set t s+n
if t.len=n
 io.write t
 exit()
goto 1
\$\endgroup\$
1
\$\begingroup\$

awk, 37 bytes

{FS="";r=$0;$0=r NF;$0=r NF;$0=r NF}1

That will work in any awk that splits lines into characters when FS is NULL e.g. GNU awk and most others. WIth other awks you'd have to use the length() function instead of NF to calculate the number of characters in the record, e.g. awk '{r=$0;$0=r length;$0=r length;$0=r length}1' file.

Breakdown:

FS=""    # split the record at every character so NF is a count of characters in the record
r=$0     # save the original record
$0=r NF  # append the original length to the original record and cause awk to recalculate NF
$0=r NF  # append the new length to the original record and cause awk to recalculate NF again
$0=r NF  # append the final length to the original record for output
1        # a true condition invoking awks default action of printing the current record

Example:

$ awk '{FS="";r=$0;$0=r NF;$0=r NF;$0=r NF}1' file
aaa4
1
aaaaaaaa9
aaaaaaaaa11
a13
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa101
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa102
\$\endgroup\$
1
\$\begingroup\$

Jelly, 12 bytes

Many thanks to Dennis for his help in writing this answer. Golfing suggestions welcome. Try it online!

D;³L=
LÇ1#;@

Explanation

LÇ1#;@  Main link. Argument: s
          Runs the helper link until a suitable x is found.
L       Yields the length of s.
 Ç1#    Calls the helper link until one match is found.
    ;@  Appends the matching x to s.

D;³L=  Helper link. Argument: x
         Appends x to s and checks if its length is equal to x.
D      Convert x from integer to decimal.
 ;³    Append to our original string.
   L=  Check if the length of this new string is equal to x.
\$\endgroup\$
1
\$\begingroup\$

Perl, 31 bytes

Just going through all the numbers until one fits:

perl -lpe '1while++$n<length$_.$n;$_.=$n'
\$\endgroup\$
1
\$\begingroup\$

Factor, 47 bytes

[ dup length dup log10 ⌈ + 1 /i >dec append ]

Attempt This Online!

small improvement to the previous answer.

>dec is polyfilled since it is a newer addition.

\$\endgroup\$
1
\$\begingroup\$

Ly, 26 14 bytes

iysp&ol`Syl+u;

Try it online!

This turned out to be trickier than I expected... Since strings of length 9, 99, etc... need an extra digit when the length it appended.

So the code computes the number of digits in the length of a string composed of the original string plus the length of that string. Then that length is added to the length of the original string to get the final length, which is appended to the original.

iysp&ol`Syl+u; - 
i              - read in the input string
 ysp           - get the length, stash it, delete from stack
    &o         - print the string
      l`       - load the string length and increment
        Sy     - split to digit, count them
          l+   - load the string length and add to digit count
            u; - print as number and exit (to avoid printing stack)

jq, 40 bytes

.+"\(length+(length+1|tostring|length))"

Try it online!

It's the same algorithm, just in jq for comparison. I couldn't find a shorter way to do it in jq even though using "length" three times seems like it should be golf-able...

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 4 bytes

3Fg«

Try it online or verify all test cases.

Explanation:

3F    # Loop 3 times:
  g   #  Pop the current string, and push its length
      #  (which will use the implicit input-string in the first iteration)
   «  #  Append this length to the (implicit) input-string
      # (after which the result is output implicitly)
\$\endgroup\$
4
  • \$\begingroup\$ This looks suspiciously similar to a port of @lyxal's comment. \$\endgroup\$
    – Neil
    Commented Dec 5, 2022 at 10:22
  • \$\begingroup\$ @Neil Your link goes to the question itself instead of a comment? But looking for Lyxal's comment I assume you mean this one on the Vyxal answer? It indeed appears to be the same, even though I came up with it independently a few hours ago. It's a pretty straight-forward approach when you use twice in a row and see that the 98-long test case requires a third tbh. 🤷 \$\endgroup\$ Commented Dec 5, 2022 at 10:32
  • \$\begingroup\$ Huh, your comment doesn't work for me, but I'll take your word for both your claims. \$\endgroup\$
    – Neil
    Commented Dec 5, 2022 at 10:34
  • \$\begingroup\$ @Neil Huh? Your linked comment didn't work for me though.. :/ \$\endgroup\$ Commented Dec 5, 2022 at 10:37
1
\$\begingroup\$

JavaScript, 29 bytes

s=>(g=x=>s+x.length)(g(g(s)))

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Thunno 2, 4 bytes

3{l+

Try it online!

Explanation

3{l+  # Implicit input
3{    # Repeat three times:
  l   #  Take the length of the top
      #  of stack (initially input)
   +  #  And append this to the input
      # (Three times is enough to handle
      #  digit overflows like 9, 99, etc.)
      # Implicit output
\$\endgroup\$
1
\$\begingroup\$

Pascal, 125 B

String capabilities and writeStr are defined by Extended Pascal, ISO standard 10206. The built‑in constant maxInt has been specified only for scoring reasons: you probably need to replace maxInt by a reasonably small value not exhausting available memory.

type t=string(maxInt);function f(s:t)=r:t;var n:integer;begin
r:=s;repeat n:=length(r);writeStr(r,s,n:1)until n=length(r)end;

Readablified:

type
    stringMaximum = string(maxInt);

function appendStringLength(protected s: stringMaximum) = result: stringMaximum;
    var
        printedLength: 0‥s.capacity;
    begin
        result ≔ s;
        
        repeat
        begin
            printedLength ≔ length(result);
            writeStr(result, s, printedLength:1)
        end
        until length(result) = printedLength
    end;
\$\endgroup\$
1
\$\begingroup\$

J, 11 bytes

(,":@#)^:3~

Attempt This Online!

(,":@#) is a dyadic hook which takes strings on the left and right and gives the left string joined with the right string's length.

^:3 means repeat 3 times.

~ means use the same value for both the right and left arguments, so in the first iteration the string gets joined with its own length, then in the second iteration the original string gets joined with the length of that, etc.

\$\endgroup\$
0
\$\begingroup\$

C, 75 bytes

Yes, there's another C answer but this (the same method as my Factor answer) is shorter:

i,z;f(char*s){i=strlen(s);z=1+log10(i);sprintf(realloc(s,i+z)+i,"%d",i+z);}

Ungolfed:

i, z;

g (char* s){
  i = strlen(s);
  z = 1 + log10(i);
  s = realloc(s, i + z);
  sprintf(s + i, "%d", i + z);
}

ceil(log10(n) is the number of digits in base 10 n, but 1+ is shorter than ceil().

Then, resize the string so we don't get a segfault, and format the number after the string part.

\$\endgroup\$
1
  • \$\begingroup\$ I don't believe this method works for 98 or 997 \$\endgroup\$
    – Blue
    Commented Dec 17, 2016 at 16:37
0
\$\begingroup\$

Under review

Powershell V2.0, 64 bytes

$s=$args[0]
$s+[string]($s.length+([string]($s.length)).length)

Example

PS C:\Users\***\Downloads\golf> .\str-length.ps1 'This is my strin3333333333333333333333333333333333333333333333333333
33333333333333333333333333333333333333333g'
This is my strin333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333g113
\$\endgroup\$
2
  • \$\begingroup\$ This outputs aaaaaaaaa10 when given input aaaaaaaaa, and not the correct aaaaaaaaa11. \$\endgroup\$ Commented Dec 19, 2016 at 16:34
  • \$\begingroup\$ You're right, I missed that somehow. \$\endgroup\$ Commented Dec 20, 2016 at 8:34
0
\$\begingroup\$

Scala, 75 bytes

def a(b:String,c:Int=0):String=if((b+c).length>c)a(b,c+1)else b+c
\$\endgroup\$
0
\$\begingroup\$

awk, 27 bytes

$0=$0length($0length($0NF))

Test it:

$ awk -F '' '$0=$0length($0length($0NF))' file
7aaaaaa8
8aaaaaaa9
9aaaaaaaa11
97aaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa99
98aaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa10aaaaaaaa101
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can change length($0) to just length for brevity. \$\endgroup\$
    – Ed Morton
    Commented Dec 23, 2016 at 16:40
  • \$\begingroup\$ @EdMorton Been experimenting with awk -F '' '$0=NF' \$\endgroup\$ Commented Dec 24, 2016 at 13:46
0
\$\begingroup\$

C# / CS Script 99 87 79 bytes

Saved a few bytes switching to a lambda. And a few more moving the try/catch out of the for loop.

F=a=>{int i=0,l;try{for(;;)l=(a+(a+a.Length).Length)[++i];}catch{}return a+i;};

Try it here

Expanded:

F => a
{
    // 'i' is for traversing the string
    // 'l' is just a placeholder
    int i = 0, l;

    // wrap the loop in a try/catch
    try
    {
        // loop forever
        for (;;)
            // assign to 'l' the char at position ++i
            // throws an IndexOutOfRangeException when it falls off the end
            l = (a + (a + a.Length).Length)[++i];
    }
    // empty catch block
    catch {}

    // returns a string concat of the input a and index i
    return a + i;
}
\$\endgroup\$
0
\$\begingroup\$

Java 7, 67 bytes

String y(String y){int i=0;for(;(y+i).length()!=i;i++);return y+i;}

Try it online!

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.