9
\$\begingroup\$

Challenge:

Your program will take two integers n and k as input, and output the smallest integer greater than (but not equal to) n that contains at least k occurrences of the digit 5.

You can assume 1 ≤ k ≤ 15 and 1 ≤ n < 10**15.

This is a challenge. Your program must run on TIO for all of the test cases and complete within 10 seconds in total.

General rules:

  • This is , so the shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for any programming language.

  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call. The function parameters may be taken in either order, but please specify in your answer.

  • Default Loopholes are forbidden.
  • You must add a link with a test for your code (i.e. TIO).
  • The answer header should list the score in bytes but also the total time taken for all test cases on TIO
  • If your language is not on TIO, the code should finish far under 10 seconds on your machine so that you're confident it's fast enough on any reasonable computer.
  • Adding an explanation for your answer is highly recommended.

Test Cases:

(n, k) ->  output
(53, 2) -> 55
(55, 1) -> 56
(65, 1) -> 75
(99, 1) -> 105
(555, 3) -> 1555
(557, 1) -> 558
(5559, 3) -> 5565
(6339757858743, 5) -> 6339757859555
(99999999999999, 15) -> 555555555555555

Program Example:

This program is correct.

\$\endgroup\$
2

10 Answers 10

6
\$\begingroup\$

R, 85 84 76 74 bytes, 0.250s on TIO

f=function(n,k,m=nchar(gsub("[^5]","",n+1))-k)`if`(m<0,f(n+.1^m/50,k),n+1)

Try it online!

-1 byte thanks to Robert S.
-8 bytes thanks to Giuseppe.

The nchar(gsub(...)) part counts the number of 5s.

A simple recursive solution would be to increment by 1 until the answer is found, but this would not meet the time restriction. To meet the time restriction, this function makes use of the fact that if there are p missing 5s, we can increment by 2*10^(p-2) (represented as the golfier .1^m/50, with m=-p).

Note that when p=1, the increment becomes 0.2. This is OK, since after 5 steps we come back to an integer, and none of the decimal numbers encountered in the mean time have an extra 5. If instead we were to increment by 5*10^(p-2) or by 1*10^(p-2), then we would find f(24, 1)=24.5 instead of 25 for example.

\$\endgroup\$
6
  • 2
    \$\begingroup\$ Save 1 byte by using an if function variant. \$\endgroup\$
    – Robert S.
    Mar 29, 2019 at 17:32
  • \$\begingroup\$ @RobertS. Thanks. I didn't know about that variant; is there somewhere I can read more about it? \$\endgroup\$ Mar 29, 2019 at 18:19
  • 2
    \$\begingroup\$ Definitely. Check out the tips for golfing in R post! \$\endgroup\$
    – Robert S.
    Mar 29, 2019 at 18:25
  • 1
    \$\begingroup\$ Also you can ask questions in the R golfer chat which isn't very active but it's better than nothing :-) \$\endgroup\$
    – Giuseppe
    Mar 29, 2019 at 18:44
  • 2
    \$\begingroup\$ 76 bytes -- I'm not really sure what the a was doing, so I removed it and it seems to be OK. \$\endgroup\$
    – Giuseppe
    Mar 29, 2019 at 18:56
3
\$\begingroup\$

Jelly, 37 bytes 0.113 s on TIO

»DL‘Ɗ}©5xḌ_DḌÐƤ;®ŻṬ€UḌ¤+⁹D=5S>ʋƇ⁸’¤ḟṂ

Try it online!

This works by

  1. working out the maximum of the number of digits in the input plus one and k, and making a number with that many fives
  2. Subtracting the input from that number
  3. Generating all of the suffixes of that number
  4. Also generating all the powers of ten from 1 up to the next one greater than the input
  5. Adds each of the numbers in 3 and 4 to the input
  6. Removes answers with too few 5’s
  7. Filters out the input from the answers
  8. And returns the minimum
\$\endgroup\$
4
  • \$\begingroup\$ @KevinCruijssen sorry I meant that many fives \$\endgroup\$ Mar 28, 2019 at 14:12
  • 1
    \$\begingroup\$ Hmm.. Seems to fail for [557,1] (results in 558 instead of 560); test case in the description seems incorrect, since [557,2] should result in 558 instead. \$\endgroup\$ Mar 28, 2019 at 14:59
  • 3
    \$\begingroup\$ @KevinCruijssen I asked about this: it’s at least k 5s not exactly k. \$\endgroup\$ Mar 28, 2019 at 15:00
  • \$\begingroup\$ Ah ok, then it's correct. :) \$\endgroup\$ Mar 28, 2019 at 15:00
2
\$\begingroup\$

Stax, 17 bytes (6.861 total seconds on TIO)

≈ª╞¥é£ôñτ←╝α┴╢JLd

Run and debug it

This program takes k and n on standard input separated by space. Stax doesn't have a convenient way to run multiple test cases on TIO, so I ran each input separately and added up the time. 99% of the time is in the interpreter process startup. Using the javascript interpreter on staxlang.xyz, all test cases run in 50 milliseconds.

Last test case on Try it online!

Procedure:

  1. Increment input
  2. If there are enough 5s, terminate and print
  3. t= number of trailing 5s in the number
  4. Add 10 ** t
  5. Goto 2
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 33 32 31 bytes

sg>‚à©5s×α.s0š®Ý°0šâO+IKʒ5¢¹@}ß

Port of @NickKennedy's amazing approach in his Jelly answer, so make sure to upvote him!!

Takes \$k\$ as first input; \$n\$ as second.

Try it online or verify all test cases.

Explanation:

sg>                # Get the length+1 of the second (implicit) input-integer
   ‚à              # Pair it with the first input-integer, and leave the maximum
     ©             # Store this maximum in the register (without popping)
      5s×          # Create an integer (actually, create a string..) with that many 5s
         α         # Take the absolute difference with the second (implicit) input
          .s       # Get the prefixes of that number
            0ª     # Prepended with an additional 0
    ®              # Get the maximum from the register again
     Ý             # Create a list in the range [0, max]
      °            # Raise 10 to the power of each integer
       0ª          # And also prepend an additional 0 to this list
              â    # Then create each possible pair of these two lists
               O   # Sum each pair
                +  # Add the second input to each sum
IK                 # Then remove the second input from this list (if present)
  ʒ                # And filter this list by:
   5¢              #  Count the amount of 5s in the integer
     ¹@            #  And check if this count is larger than or equal to the first input
       }ß          # After the filter: only leave the lowest number
                   # (which is output implicitly as result)
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -pl, 44 bytes

$k=<>;$_++;s/.*?(?=5*$)/1+$&/e while$k>y/5//

Try it online!

Finds what the number is without its trailing 5s. Increments that portion by 1. Continues until sufficient 5s are in the number. Takes about .012s on TIO to run all test cases.

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

Python 3, 144 98 86 75 bytes

f=lambda N,k,d=1:k>str(-~N).count("5")and f(N+-(-~N//d+5)%10*d,k,d*10)or-~N

Try it online!

This is \$\mathcal{O}(k)\$, (system time .008 on TIO) and has golfed well with some advice from ASCII-only.

The algorithm is to round up each digit (starting from the least-significant one) to the nearest value of 5 until the new number's decimal representation has the desired count.

The original approach used an abortable (D=iter(range(k)) and list(D) at work here) list comprehension, but @ASCII-only has convinced me that will never win code-golf. I dislike recursion, but if the algorithm is written to minimize recursion-depth, then a future compiler/interpreter will be smart enough to re-implement it as a while loop.

\$\endgroup\$
8
  • \$\begingroup\$ 94? \$\endgroup\$
    – ASCII-only
    Mar 31, 2019 at 11:48
  • \$\begingroup\$ 93? \$\endgroup\$
    – ASCII-only
    Mar 31, 2019 at 11:49
  • \$\begingroup\$ 88? \$\endgroup\$
    – ASCII-only
    Mar 31, 2019 at 11:51
  • \$\begingroup\$ 86? \$\endgroup\$
    – ASCII-only
    Mar 31, 2019 at 11:52
  • 1
    \$\begingroup\$ it's (-(-~n//l+5))%10 is why \$\endgroup\$
    – ASCII-only
    Apr 4, 2019 at 23:21
0
\$\begingroup\$

PHP, 109 97 bytes, (< 0.03s on TIO)

function($n,$k){++$n;do if(count_chars($n)[53]>=$k)return$n;while($n+=10**strspn(strrev($n),5));}

Try it online!

Based on @recursive's algorithm.

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

Retina, 63 bytes

.+$
*
^.+
$.(*__
/((5)|.)+¶(?<-2>_)+$/^+`^.*?(?=5*¶)
$.(*__
1G`

Try it online! Takes n and k on separate lines, but link includes header that converts the test suite into the appropriate format. Explanation:

.+$
*

Convert k to unary.

^.+
$.(*__

Increment n. The * repeats its right argument (here the first _ character) the number of times given by its left argument (which, as here, defaults to the match). This results in a string of that length. The $( (the ) is implied) then concatenates that with the second _ and the . causes the resulting length to be taken. (Actually Retina 1 is cleverer than that and just performs the calculation on the underlying lengths in the first place.)

/((5)|.)+¶(?<-2>_)+$/

Test whether enough 5s can be found in n to match the _s of the unary representation of k. This test has been golfed and would be three times faster with ^ added after the initial / and faster still if [^5] was used instead of ..

^+`

Until the test passes...

^.*?(?=5*¶)
$.(*__

... increment n but exclude trailing 5s.

1G`

Delete k.

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

C (gcc), 159 158 152 150 149 bytes, ~0.04 s

Outputs the answer to STDOUT, with leading zeroes.

-3 byte thanks to ceilingcat

m,j;f(n,k)long n;{char*t,s[17];for(t=s+sprintf(s,"%016ld",++n),m=n=0;m<k&--t>s;m<k&&*t-53?n=*t>53,*t=53:0)for(*t+=n,m=j=17;j--;)m-=s[j]!=53;puts(s);}

Try it online!

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

Ruby, 41 bytes

->n,k{(n+1..).find{_1.to_s.count(?5)>=k}}

Attempt This Online!

\$\endgroup\$

Your Answer

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

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