14
\$\begingroup\$

Someone I know has no coding experience, but has proposed an algorithm* to determine the character limit of text fields they find online. They copy a string containing the numbers from 1 to 1,000 inclusive, not separated in any way, and they read the last few digits it displays.

For example, after pasting, they might see

...5645745845

From here, they can figure out the character limit.

They've got two problems with this approach. One, it's a little hard to determine where the discrete numbers are in the string. (The last whole number displayed here is 458, and the final two digits would have been followed by 9 if the text field allowed one more character.)

Two, the math is a little tricky even when that character has been identified. It's easy with single digits. For instance, if the last whole number were 5, the limit would be 5 characters. With double digits it's a little harder. If the last whole number were 13 followed by the 1 of 14, the full field would display 123456789101112131 for a limit of 18 characters.

They've managed to get a script that copies the last 10 digits the text field displays, or as many as the field holds if the field can hold less than 10. They'd like to feed that into another script that returns the field's length limit.

Additional test cases:

'' -> 0
'1' -> 1
'12' -> 2
'7891011121' -> 16
'1191201211' -> 256
'5645745845' -> 1268

Here are some examples of invalid inputs, incidentally:

'0'
'121'
'1211'

* Possibly in jest :)

asked Dec 8, 2023 at 5:46
\$\endgroup\$
16
  • \$\begingroup\$ Since this can by computed by a "generate everything and find the input" strategy, a harder variation might allow inputs to be arbitrarily large, and guarantee only that you are given enough digits to uniquely find it, assuming the input is the first instance of that sequence in the nats. \$\endgroup\$ Commented Dec 8, 2023 at 7:01
  • \$\begingroup\$ @Jonah Good call. After all, the "find input in string" strategy is probably how I'd do it. Do you think it's too late to change with an update given the 7 answers, or is it worth improving now? Not sure of Code Golf conventions. \$\endgroup\$ Commented Dec 8, 2023 at 12:18
  • 1
    \$\begingroup\$ @LukeSawczak I think it would need to be a part 2 post \$\endgroup\$ Commented Dec 8, 2023 at 15:36
  • 1
    \$\begingroup\$ @P.b I don't follow. If we're dealing with consecutive natural numbers from 1 to 1,000, the only valid sequence I see is ...(4)56,457,458,4(59)... Here's how I reason: we can't be in the single digits, because 4,6 isn't valid. We can't be in the double digits, because neither 56,45 nor 64,57 is valid. So we must be in the triple digits. It can't be 564,574 or 645,745, so it must be 457,458. However, that does give me an interesting idea for a variation of the problem: rather than knowing the numbers are consecutive, the step could be any power of 10 up to the column value... \$\endgroup\$ Commented Dec 8, 2023 at 22:14
  • 1
    \$\begingroup\$ I missed on the 1 to 1000 part and got mislead by the example being larger than 1000 in the first place. \$\endgroup\$ Commented Dec 9, 2023 at 11:53

17 Answers 17

6
\$\begingroup\$

Excel (ms365)

1) Recursion with LAMBDA(), 74 bytes:

enter image description here

Formula in B1:

=LET(x,LAMBDA(y,n,s,IFERROR(FIND(A1,s),y(y,n+1,s&n))),x(x,1,""))+LEN(A1)-1

Note: Due to the limitations within Excel this may return an error above a certain amount of recursive lambda calls.


2) Concatenating with ROW(), 39 bytes:

I did explicitly want to stay away from using a concatenated string from any arbitrary range of numbers for this challenge. If one is okay with this concept then try:

 =FIND(A1,CONCAT(ROW(1:8468)))+LEN(A1)-1

Here I found that concatenating ROW(1:8468) seems to be Excel's (or rather CONCAT()'s) limit.


3) Overcome Excel's limits using PY(), 87 bytes:

To overcome these limits of function within Excel, we could use the new PY() function:

=PY(
 ''.join(map(str,range(1,int(xl("A1")+1)))).find(str(xl("A1")))++len(str(xl("A1")))
)

Note: Python is not my forté, so I'm sure this can be golfed down. However, more importantly. Since PY() is executed on an external server there is a high chance of this code error out due to a "time-limit".

answered Dec 8, 2023 at 10:19
\$\endgroup\$
5
\$\begingroup\$

05AB1E, 7 bytes

LJIkIg+

Times out for larger inputs. Add a leading 4 (push 1000) to speed it up.

Try it online or verify all test cases.

Explanation:

L # Push a list in the range [1, (implicit) input-integer]
 J # Join it together to a single string
 Ik # Pop and push the (0-based) index of the input
 Ig+ # Add the length of the input
 # (after which the result is output implicitly)
answered Dec 8, 2023 at 8:34
\$\endgroup\$
5
\$\begingroup\$

Vyxal, 50 bitsv2 , 6.25 bytes

⌊ɾṅḟ?L+

Try it Online!

Bitstring:

11001011010011010000000111000101111000110100000010

Times out for very large inputs because it needs to generate a range between 1 and whatever number represented by the input.

Explained

⌊ɾṅḟ?L+­⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁣‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁤‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌­
⌊ɾ # ‎⁡The range [1, input]
 ṅ # ‎⁢Joined into a single string.
 ḟ # ‎⁣Find the index of the input in that string
 ?L+ # ‎⁤And add the length of the input to that 
💎

Created with the help of Luminespire.

answered Dec 8, 2023 at 5:51
\$\endgroup\$
3
  • \$\begingroup\$ It’s a little misleading for the link in the header to go to the default branch, since this is Vyxal 2 \$\endgroup\$ Commented Dec 8, 2023 at 17:02
  • \$\begingroup\$ @noodleman never attribute to malice what can adequately be explained by stupidity (ie forgetting to update the template generator) \$\endgroup\$ Commented Dec 8, 2023 at 21:35
  • 1
    \$\begingroup\$ never attribute to malice what can adequately be explained by stupidity (ie using the word "misleading" instead of "confusing") :p \$\endgroup\$ Commented Dec 9, 2023 at 2:29
5
\$\begingroup\$

JavaScript (Node.js), 43 bytes

x=>~(g=s=>~s.indexOf(x,1)||g(s+i++))(x,i=1)

Try it online!

Using range, fail 11 (expect 13, get 1)

JavaScript (Node.js), 49 bytes

x=>~(g=s=>~s.search(x)||g(s+ ++i))(i='')+x.length

Try it online!

-4 from Arnauld

Not using the 10

answered Dec 8, 2023 at 5:54
\$\endgroup\$
4
  • \$\begingroup\$ 53 bytes? \$\endgroup\$ Commented Dec 8, 2023 at 7:46
  • \$\begingroup\$ @Arnauld Is this correct? \$\endgroup\$ Commented Dec 8, 2023 at 7:59
  • \$\begingroup\$ Yes, that looks safe. \$\endgroup\$ Commented Dec 8, 2023 at 8:22
  • \$\begingroup\$ How does this work? Does it also use brute force, like most other answers? \$\endgroup\$ Commented Dec 20, 2023 at 15:22
5
\$\begingroup\$

Ruby, (削除) 34 (削除ここまで) 30 bytes

->i{[*1..1e3]*''=~/(?<=#{i})/}

Try it online!

Thanks to @Neil for saving 1 Byte by removing useless + in regexp

Regexp /(?<=#{i})+/ finds index next to input in the constructed string [*1..1e3]*'' by using a look behind.

answered Dec 8, 2023 at 9:11
\$\endgroup\$
2
  • 1
    \$\begingroup\$ I don't think you need the + do you? \$\endgroup\$ Commented Dec 9, 2023 at 14:42
  • \$\begingroup\$ @Neil well.. thank you! \$\endgroup\$ Commented Dec 9, 2023 at 16:28
4
\$\begingroup\$

Perl 5 (-p), 27 bytes

(join"",1..1e3)=~$_;$_="@+"

Try it online!

answered Dec 8, 2023 at 10:52
\$\endgroup\$
4
\$\begingroup\$

Haskell, (削除) 65 (削除ここまで) 63 bytes

-2 bytes thanks to @AZTECCO

n%h|l<-length n,n==take l h=l
n%(_:h)=1+n%h
f=(%([1..]>>=show))

Try it online!

answered Dec 8, 2023 at 13:46
\$\endgroup\$
1
  • \$\begingroup\$ 63 \$\endgroup\$ Commented Dec 8, 2023 at 13:54
3
\$\begingroup\$

Retina 0.8.2, 38 bytes

^
1001$*1¶
\G1
$.`
r`\B1円.*¶(.*)
1ドル
\B

Try it online! Link includes test cases. Explanation:

^
1001$*1¶
\G1
$.`

Create a string of all the numbers from 0 to 1000 concatenated.

r`\B1円.*¶(.*)
1ドル

Remove everything after the first copy of the input, but don't delete the leading 0. The r reverses the direction of processing, so the (.*) is matched first and the \B last.

\B

Count the pairs of adjacent digits, which is the same as the length excluding the leading 0.

Alternative 38-byte version that works for arbitrary numbers given enough memory and processing power but is slower for inputs of four or more digits.

^
$'$*111¶
\G1
$.`
r`\B1円.*¶(.*)
1ドル
\B

Try it online! Link includes test cases. Explanation:

^
$'$*111¶
\G1
$.`

Create a string of all the numbers from 0 to the input plus 1 concatenated. (This is needed for the edge case of an empty input.)

r`\B1円.*¶(.*)
1ドル

Remove everything after the first copy of the input, but don't delete the leading 0.

\B

Take the length excluding the leading 0.

answered Dec 8, 2023 at 10:10
\$\endgroup\$
3
\$\begingroup\$

Pip, 10 bytes

Semi-port of lyxal's Vyxal answer

J1,a~:Xa$)

Attempt This Online!

J1,a~:Xa$)­⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏⁠‎⁡⁠⁣‏⁠‎⁡⁠⁤‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌­
J1,a # ‎⁡Range from 1 to input as string
 ~:Xa # ‎⁢Match input as regex in range
 $) # ‎⁣Return last index of first match
💎

Created with the help of Luminespire.

answered Dec 8, 2023 at 16:51
\$\endgroup\$
2
  • \$\begingroup\$ If you switch the operands to ~, you can get rid of the :. (In the upcoming version 1.2, you'll be able to drop the X as well.) \$\endgroup\$ Commented Mar 6, 2024 at 7:12
  • \$\begingroup\$ @DLosc new version?? :D I’ll update my answers later this month, I can’t right now \$\endgroup\$ Commented Mar 6, 2024 at 7:53
3
\$\begingroup\$

Charcoal, 10 bytes

I+Lθ⌕⭆φ⊕ιθ

Try it online! Link is to verbose version of code. Explanation:

 φ Predefined variable `1000`
 ⭆ Map over implicit range and join
 ι Current value
 ⊕ Incremented
 ⌕ Find index of
 θ Input string
 + Plus
 θ Input string
 L Length
I Cast to string
 Implicitly print
answered Dec 8, 2023 at 16:55
\$\endgroup\$
3
\$\begingroup\$

APL+WIN, (削除) 35 (削除ここまで) 33 bytes

Two bytes saved thanks to Tbw

Prompts for string of digits:

↑( ̄1+⍴s)+((s←,⎕)⍷n)/⍳⍴n←⊃,/⍕ ̈⍳1E3

Try it online! Thanks to Dyalog Classic

answered Dec 8, 2023 at 15:54
\$\endgroup\$
2
  • \$\begingroup\$ You can save bytes with ⊃,/⍕¨⍳1E3 to make the string. \$\endgroup\$ Commented Dec 8, 2023 at 16:27
  • \$\begingroup\$ @Tbw Thanks. Edited code. \$\endgroup\$ Commented Dec 8, 2023 at 17:31
2
\$\begingroup\$

APL (Dyalog Classic), 22 bytes

≢-1-(⊃∘⍸⍷∘(⊃,/⍕ ̈⍳1E3))

Try it online!

≢-1-(⊃∘⍸⍷∘(⊃,/⍕ ̈⍳1E3)) # tacit function⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏⁠‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏⁠‎⁡⁠⁢⁤‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁤⁡‏⁠‎⁡⁠⁤⁢‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁤⁣‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁤⁤‏⁠‎⁡⁠⁢⁡⁡‏⁠‎⁡⁠⁢⁡⁢‏‏​⁡⁠⁡‌⁢⁢​‎‎⁡⁠⁢‏‏​⁡⁠⁡‌⁢⁣​‎‎⁡⁠⁡‏‏​⁡⁠⁡‌­
 ⊃∘⍸⍷∘ # ‎⁡index of first subsequence equal to input in 
 1E3 # ‎⁢⁡1000 
 ⍳ # ‎⁤range 
 ⍕ ̈ # ‎⁣toString each 
 ,/ # ‎⁢concat reduce 
 ⊃,/⍕ ̈⍳1E3 # '12345678910...'
 -1- # ‎⁢⁢minus 1 (because a-1-c = a-(1-c) = ̄1+a+c in APL)
≢ # ‎⁢⁣length of input (this is one character;
💎 # the code block does not display it correctly)

Created with the help of Luminespire.

answered Dec 8, 2023 at 16:53
\$\endgroup\$
2
\$\begingroup\$

Python 3, 55 bytes

lambda s:"".join(map(str,range(1,1001))).find(s)+len(s)

This is a rather simple solution, but it works.

answered Dec 9, 2023 at 22:33
\$\endgroup\$
1
\$\begingroup\$

Japt, 9 bytes

+A3õ ¬
aN

Try it

answered Dec 9, 2023 at 16:10
\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 57 bytes

x=>[...Array(1000).keys()].join('').indexOf(x)-1+x.length

Attempt This Online!

Constructs "0123456789...", then finds the input in it.

answered Jan 5, 2024 at 19:36
\$\endgroup\$
0
\$\begingroup\$

Scala 3, 41 bytes

s=>(1 to 1000).mkString.indexOf(s)+s.size

Attempt This Online!

answered Jan 6, 2024 at 0:10
\$\endgroup\$
0
\$\begingroup\$

Uiua, 30 bytes

(⊏0+⧻:⊚⌕:/$"__"+1⇡1e3.|0;)=0⧻.

Test suite

I felt like adding another answer

answered Jan 7, 2024 at 13:49
\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.