13
\$\begingroup\$

The task is simple. You're given an arbitrary string message. Return that message prefixed with a number, such that the length of that number plus the message equals the number. In other words, the length in your output must be the total length of your output.

If multiple candidates exist, you can output any of them.

For example, take the following message: pull the other one, with a length of 18. Your final output should be 20 + pull the other one, because the total length of 20 + the total length of pull the other one is 20 ASCII characters.

Restrictions/clarifications:

  • Your input and output can be given by any convenient method.
  • The outputted length can be encoded in any way you like, as long as the encoding can represent any arbitrary positive number, and the encoding is consistent. You can, for example, output 10111 + pull the other one (10111 is 23 in binary, and the total length is 23). This also extends to types: e.g. a tuple of (int, string) is accepted as output, as long as you specify the encoding the integer must have.
  • The input string can also have any encoding you like (well, except for the encoding in this question).
  • Your program should be able to handle at least all messages of length <= 1,048,575 (2^20-1).
  • The program can be a full program or just a function; either is fine.
  • Standard loopholes are forbidden.
  • Shortest code wins.

Some more test cases:

# base 10
"hello world" -> "13" + "hello world"
"the axes"    -> "9"  + "the axes"
"the axes"    -> "10" + "the axes"    # both of these are valid outputs
""            -> "1"  + ""            # the empty message should result in simply the output "1"

# base 2
"hello world" -> "1111" + "hello world"
"test"        -> "111"  + "test"
"test"        -> "1000" + "test"        # both of these are valid outputs
""            -> "1"    + ""            # the empty message can result in simply the output "1"
""            -> "10"   + ""            # in binary, this is also a valid result for the empty message
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Presumably 10 is also a valid output for the empty message using base 2...? \$\endgroup\$ Dec 4, 2022 at 15:39
  • 3
    \$\begingroup\$ I'm pretty sure we had a similar challenge some years ago, but I can't find it. (Nor do I remember it well enough to tell if that's a dupe.) \$\endgroup\$
    – Arnauld
    Dec 4, 2022 at 17:45
  • 5
    \$\begingroup\$ cc @Arnauld - this is Appending String Lengths, but with the only difference being 10theaxes is also acceptable output in this challenge, and not the other one. It is likely a dup, but I'm not sure if the difference between prepending and appending is suitably large enough. \$\endgroup\$ Dec 4, 2022 at 20:56
  • \$\begingroup\$ @ConorO'Brien Ah, that's the one! And my answer was (almost) identical... \$\endgroup\$
    – Arnauld
    Dec 4, 2022 at 22:09
  • 1
    \$\begingroup\$ I suggest having test cases of length 9 (and maybe 98) in base 10 to help catch code that would output 10something or 100reallylongmessageof98length instead of 11something or 101.... \$\endgroup\$
    – Chris
    Dec 5, 2022 at 20:57

25 Answers 25

4
\$\begingroup\$

C (gcc), 43 bytes

f(b,s,n){for(;sprintf(b,"%d%s",++n,s)>n;);}

Try it online!

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

Pyth, 4 bytes

+Chl

Try it online!

Length encoded using Python chr.

\$\endgroup\$
3
  • \$\begingroup\$ Can you explain how this approach will work with string lengths that cannot be encoded as a single character? The challenge stipulates that it should work for strings up to 1,048,575 characters long, which (I suppose) is larger than the number of characters available to encode the length... \$\endgroup\$ Dec 7, 2022 at 20:37
  • \$\begingroup\$ @DominicvanEssen Pyth's C uses Python's chr directly, and the docs for chr say "The valid range for the argument is from 0 through 1,114,111." \$\endgroup\$
    – hakr14
    Dec 8, 2022 at 0:31
  • \$\begingroup\$ Ok - that sounds fair. Thanks for clarifying. \$\endgroup\$ Dec 8, 2022 at 8:55
3
\$\begingroup\$

Pyth, 7 6 bytes

-1 byte thanks to @isaacg

+fql+Q

Attempt This Online!

Explanation

+fql+QTT<None>Q
+                #  add
 f               #    first input (T) where
   l             #      length of
    +QT          #        testcase + T
  q    T         #      equals T
              Q  #  to the testcase
\$\endgroup\$
1
  • 1
    \$\begingroup\$ This still works if you remove the T, for -1 byte. \$\endgroup\$
    – isaacg
    Dec 4, 2022 at 22:35
3
\$\begingroup\$

Vyxal, 4 bytes

3(Lp

Try it Online! -1 thanks to lyxal, -2 thanks to Kevin Cruijjsen.

3(   # Three times
   p # Prepend to input
  L  # Length of current value
\$\endgroup\$
4
  • \$\begingroup\$ Try it Online! for 6, no? \$\endgroup\$
    – lyxal
    Dec 4, 2022 at 22:39
  • \$\begingroup\$ 4 bytes by porting my 05AB1E answer. \$\endgroup\$ Dec 5, 2022 at 7:20
  • \$\begingroup\$ @KevinCruijssen Nice, thanks! \$\endgroup\$
    – emanresu A
    Dec 5, 2022 at 9:23
  • \$\begingroup\$ Strictly speaking, @lyxal had that approach first with his comment on the related challenge. \$\endgroup\$
    – Neil
    Dec 5, 2022 at 10:20
3
\$\begingroup\$

Charcoal, 10 bytes

⁺L⁺L⁺Lθθθθ

Try it online! Link is to verbose version of code. Explanation: Charcoal doesn't really do recursion, but the recursive approach of repeatedly taking the length of the string with the previous length prefixed to it never needs to iterate more than twice.

      θ     Input string
     L      Take the length
    ⁺       Concatenated with
       θ    Input string
   L        Take the length
  ⁺         Concatenated with
        θ   Input string
 L          Take the length
⁺           Concatenated with
         θ  Input string
            Implicitly print
\$\endgroup\$
1
  • \$\begingroup\$ Plus it looks great. :) \$\endgroup\$
    – cnamejj
    Dec 6, 2022 at 2:57
3
\$\begingroup\$

Japt, 7 bytes

ÈsY}f+U

Try it here

ÈsY}f+U     :Implicit input of string U
È           :Function taking a string and a 0-based iteration index Y as arguments
 sY         :  Slice the string from the Yth character
   }        :End function
    f       :Get the first string that returns falsey (empty string)
     +U     :  Where each string is U appended to the current iteration index
\$\endgroup\$
2
\$\begingroup\$

Husk, 10 bytes

,ḟS=ȯL+¹sN

Try it online!

,ḟS=ȯL+¹sN
 ḟ          # get the first 
         N  # integer from 1..infinity
  =         # that equals       
   ȯ        # (compose 3 functions)
    L       #   the length of
     +¹     #   the input added to
       s    #   itself as a string
,           # finally, construct a pair of 
            # this number and the input
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6), 31 bytes

-1 thanks to @Shaggy

Uses a decimal prefix.

s=>(g=n=>(S=++n+s)[n]?g(n):S)``

Try it online!

\$\endgroup\$
1
  • 3
    \$\begingroup\$ 31 bytes \$\endgroup\$
    – Shaggy
    Dec 4, 2022 at 18:26
2
\$\begingroup\$

Ly, 15 bytes

iys>l`Sys<l+u&o

Try it online!

iys              - Read STDIN onto the stack, push stack size, save it
   >l`           - Switch to new stack, load saved size, increment by 1
      Sys        - Convert number to digits, get size of stack, save it
         <       - Switch back to the original stack (w/ STDIN and strlen)
          l+     - Load number of digits in the "strlen + 1", add to strlen
            u    - Write length as a number
             &o  - Write STDIN codepoints as characters
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 4 bytes

3Fgì

Similar as my answer for the related challenge, but with a prepend instead of append. Will therefore also use base-10, and always use the smallest (9 instead of 10) if more than one option is available.

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)
   ì  #  Prepend this length to the (implicit) input-string
      # (after which the result is output implicitly)
\$\endgroup\$
2
\$\begingroup\$

Python, 24 bytes

lambda a:chr(len(a)+1)+a

Attempt This Online!


Python, 50 bytes

f=lambda a,b=1:(len(s:=str(b)+a)==b)*s or f(a,b+1)

Attempt This Online!


Python 2, 49 bytes

f=lambda a,b=1:(len(`b`+a)==b)*(`b`+a)or f(a,b+1)

Attempt This Online!

Python 2 solution suggested by Dominic van Essen

\$\endgroup\$
4
  • 1
    \$\begingroup\$ 1 byte shorter in Python 2: try it \$\endgroup\$ Dec 4, 2022 at 16:28
  • \$\begingroup\$ I suspect that the "24 byte" version is not valid, unless there are ≥1,048,575 characters encodable by Python's chr function: is this the case? \$\endgroup\$ Dec 7, 2022 at 20:41
  • \$\begingroup\$ @DominicvanEssen python's chr function should be able to encode up to 1_114_112 (0x110000) which is greater than 1_048_575 \$\endgroup\$ Dec 8, 2022 at 3:31
  • \$\begingroup\$ Ok - that sounds fair. Thanks for clarifying. \$\endgroup\$ Dec 8, 2022 at 8:56
2
\$\begingroup\$

AWK, 41 38 bytes

{a=length;$0=length(length(a)+a)+a$0}1

# E.g.
awk '{a=length;$0=length(length(a)+a)+a$0}1' <<< "input"

Try it online

Remove the space (" ") between the final length and the string as suggested by @Dominic van Essen (-3 bytes)

\$\endgroup\$
4
  • \$\begingroup\$ This outputs 10 abcdefghi for abcdefghi, which is incorrect as it has 11 characters and so should be 11 abcdefghi... \$\endgroup\$ Dec 6, 2022 at 9:18
  • \$\begingroup\$ Ahh - thanks - I'll try to come up with a working solution, otherwise I'll delete it. Thanks for pointing that out :) \$\endgroup\$ Dec 6, 2022 at 9:24
  • \$\begingroup\$ Looks good now. You could even delete the " " to save 3 bytes and output the length smashed together with the input... \$\endgroup\$ Dec 6, 2022 at 10:05
  • \$\begingroup\$ You're absolutely right; thanks again for your help @DominicvanEssen \$\endgroup\$ Dec 6, 2022 at 10:15
1
\$\begingroup\$

Python, 65 bytes

I'm not 100% sure I understood the question right

lambda a,b=0:(z:=len(a)+len(str(b)))and((z,a)if z==b else f(a,z))

Attempt This Online!

\$\endgroup\$
2
  • \$\begingroup\$ 58 bytes by only having one call to len, and using and/or instead of if/else. \$\endgroup\$
    – The Thonnu
    Dec 4, 2022 at 16:11
  • \$\begingroup\$ You can save an extra byte on @TheThonnu's suggestion by reversing the last conditional. Also, as this is a recursive lambda, you need to include the assignment to variable f in your byte count. \$\endgroup\$
    – Shaggy
    Dec 5, 2022 at 12:25
1
\$\begingroup\$

Python, 47 bytes

f=lambda a,b=1:(b*f"{b}{a}")[-b:b*b]or f(a,b+1)

Attempt This Online!

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

Ruby, 39 34 bytes

->c,a=0{a+=1while(b=[a]*c+c)[a];b}

-5 bytes thanks to observations from jdt's C and Arnauld's JS.

Attempt This Online!

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

MathGolf, 6 bytes

£▌£▌£▌

Try it online.

Explanation:

£       # Pop and push the length of the (implicit) input-string
 ▌      # Prepend it to the (implicit) input-string
  £     # Pop and push the length of that
   ▌    # Prepend it to the (implicit) input-string
    £▌  # Rinse and repeat
        # (after which the entire stack is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

><>, 43 41 bytes

r1>:0v >o<
1(?v$>1+$a,:
2l~<.03+1v?=@:$+-

Try it online! or Try without input

Explanation

r1                  # initialize with length as 1 (L)
  >:0v              # initialize length of (L) as 0 (N)
1(?v$>1+$a,:        # calculate (N)
2l~<     v?=@:$+-   # if the length of string (S) + (N) = (L)
       >o<          # print L followed by the string
    .03+1           # else, increment (L) and go back to calculation of (N)

The length is output as a charcode.

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

Nibbles, 4.5 bytes (9 nibbles)

/\`.$:,$@

Inspired by Pacmanboss's comment.

  `.            # iterate while unique
    $           # starting from the input:
     :          #   prepend
      ,$        #   its length 
        @       #   to the original input
 \              # then, reverse the list
/               # and fold over it 
                # getting the left-hand argument each time
                # (so getting the first element)

enter image description here


Previous approach:

Nibbles, 5.5 bytes (11 nibbles)

:/|,~~-,:`p

Nibbles adds implicit variables to the end of each program if they are needed for the arity of the functions used.
In this case, this works particularly well.

  |             # filter
   ,~           # 1..infinity
     ~          # for elements that are falsy for
       ,        #   the length of 
         `p     #    the string represention 
                #    (implicitly: of each element)
        :       #    concatenated with
                #    (implicitly: the input)
      -         #   minus
                #   (implicitly: itself)
 /              # now, fold over this list
                #   returning for each pair
                #   (implicitly: the left-hand argument)
                #   (so the fold returns the first element)
:               # finally, prepend this to
                #   (implicitly: the input)
\$\endgroup\$
1
\$\begingroup\$

Go, 95 bytes

import."fmt"
func f(s string)string{S:=Sprint
return S(len(s)+len(S(len(s)+len(S(len(s))))),s)}

Attempt This Online!

Go, Old 125 bytes
import(."fmt";."strings")
func f(s string)string{S:=Repeat("-",len(s))+s
for range`---`{S=Sprintf("%d%s",len(S),s)}
return S}

Attempt This Online!

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

Excel, 21 27 bytes

=LEN(LEN(LEN(A1)&A1)&A1)&A1

Admittedly boring. I tried to do something fancy with LOG() but it's longer than this solution.

\$\endgroup\$
2
  • \$\begingroup\$ This doesn't work for messages of length 9 (or 98, 99, 997, etc). Example: something can only be encoded as 11something, but your code erroneously produces 10. \$\endgroup\$
    – Chris
    Dec 5, 2022 at 20:47
  • \$\begingroup\$ @Chris I think I misunderstood the the axes example. I believe it is corrected now although also longer. \$\endgroup\$ Dec 5, 2022 at 21:25
1
\$\begingroup\$

JavaScript, 29 bytes

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

Try it online!

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

SQL (24 bits)

print len(@)+len(len(@))

Assuming we have: declare @ as varchar(max) = 'any-string'

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

SAS, 47 58 bytes

Fix something error. I just find this anwser is same with the Excel one.

%macro e(m);
%put%length(%length(%length(&m)&m)&m)&m;
%mend;

Try some example:

%e(hello world);
13hello world

%e(something);
11something

%e(the axes);
9the axes
\$\endgroup\$
6
  • \$\begingroup\$ 10something is 11 characters long and so should be 11something. \$\endgroup\$ Dec 6, 2022 at 9:17
  • \$\begingroup\$ @DominicvanEssen Length of something is 9, length of 9 is 1, so the final length is 9+1=10, I think. \$\endgroup\$
    – whymath
    Dec 7, 2022 at 1:28
  • \$\begingroup\$ No: you should output "that message prefixed with a number, such that the length of that number plus the message equals the number." So, in the case of something, "that number" needs to be 11, because the length of 11 plus the length of something is 11. \$\endgroup\$ Dec 7, 2022 at 7:36
  • \$\begingroup\$ @DominicvanEssen You're right, I'll fix it. \$\endgroup\$
    – whymath
    Dec 7, 2022 at 8:20
  • 1
    \$\begingroup\$ @DominicvanEssen Thank you for your kindness. It is kind of troublesome to use SAS online because SAS is not free, like MATLAB. You can use SAS OnDemand(welcome.oda.sas.com/home), It may takes you several minutes to create account first. \$\endgroup\$
    – whymath
    Dec 7, 2022 at 8:36
0
\$\begingroup\$

PLIS, 81 bytes

&R($Z(strlen($0))$D(1+@(H@({$0^2}{$0-spT@$0-Z}a))@0)catat(48+digits(D),spT@D,$0))

Takes a string sequence as input, and returns a string sequence as output.

print(R("hello world"));        #=> 13hello world
print(R("the axes"));           #=> 9the axes
print(R("pull the other one")); #=> 20pull the other one
print(R(""));                   #=> 1

Explanation

Here is an equivalent, commented, ungolfed version of the above, with shortnames expanded.

&R(
  # set Z to strlen(input)
  $Z(strlen($0))
  # set D to 1 + the first index where
  $D(
    1 + @(
      # we find a 0 in
      A000007@(
        # the squared sequence of (i.e. absolute value of)
        {$0^2}
          # the difference between increasing positive integers ($0),
          # the length of that integer (A055642), and the input
          # string's length (Z)
          {$0 - A055642@$0 - Z} A000027
      )
    )@0
  )
  # D is now the appropriate number we need to prepend
  # 48 + digits(D) gives the ASCII version of this sequence
  # catat(A,n,B) will use the first  n  entries of  A  followed by
  # the entries in  B
  # this line has the effect we want
  catat(48 + digits(D), A055642@D, $0)
)
\$\endgroup\$
0
\$\begingroup\$

Terse, 4 bytes

地用找儿

Try it here

地     Length
 用    +1
  找   To character
   儿  Append input
\$\endgroup\$
4
  • \$\begingroup\$ Never seen this before! I ran your example with "This is a string that is 43 characters long" as input, the output is ,This is a string that is 43 characters long. \$\endgroup\$
    – whymath
    Dec 7, 2022 at 1:32
  • \$\begingroup\$ Can you explain how this approach will work with string lengths that cannot be encoded as a single character? The challenge stipulates that it should work for strings up to 1,048,575 characters long, which (I suppose) is larger than the number of characters available to encode the length... \$\endgroup\$ Dec 7, 2022 at 8:43
  • \$\begingroup\$ @DominicvanEssen Well it does the same thing as hakr14's pyth answer, as well as the other python answer. I'll work on adding a correct answer later \$\endgroup\$
    – Gymhgy
    Dec 7, 2022 at 20:12
  • \$\begingroup\$ @Gymhgy - Apparently my supposition was wrong (as clarified by hakr14 & Mukundan314), and there are more characters (or, at least, character-encodings) than I thought. So - if you use the Python chr-encoding (or something equivalent), your answer is already correct. Sorry for doubting...! \$\endgroup\$ Dec 8, 2022 at 8:58

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