31
\$\begingroup\$

In honor of how much rep I had several hours ago, when I first thought of this challenge:

enter image description here

Numbers like this that are made up of a single digit repeating are called repdigits. Repdigits are fun! Every body would be more happy if the amount of rep they had was a repdigit¹, but I am impatient, so you need to help me find out the fastest way to get to a repdigit.

Here is your challenge:

Given a positive integers representing reputation, output the minimum amount of rep they need to gain to get to a repdigit. For example, at the time of writing this challenge, user Martin Ender had 102,856 rep. The nearest rep-digit is 111,111, so he would need to gain: 8255 rep to be at a repdigit.

Since people dislike losing rep, we will only consider non-negative changes. This means that, for example, if someone is at 12 rep, rather than losing 1 rep, the solution is to gain 10 rep. This allows '0' to be a valid output, since anyone who has 111 rep is already at a repdigit.

Input and output can be in any reasonable format, and since it is impossible to have less than 1 rep on any Stack Exchange site, you can assume no inputs will be less than 1.

One cornercase to note:

If a user has less than 10 rep, they are already at a repdigit, and so they also need '0'.

Test IO:

#Input      #Ouput
8           0
100         11
113         109
87654321    1234567
42          2
20000       2222
11132       11090

Standard loopholes apply, and the shortest solution in bytes wins!

\$\endgroup\$
12
  • 1
    \$\begingroup\$ @Dennis I don't see why not. \$\endgroup\$ – DJMcMayhem Aug 24 '16 at 6:53
  • 1
    \$\begingroup\$ @Dennis Why would I say no? I always try to avoid restrictive IO in my challenges, and a lot of languages (like my own) don't distinguish between string and integer input, so I don't see any reason I would restrict it. \$\endgroup\$ – DJMcMayhem Aug 24 '16 at 7:10
  • 2
    \$\begingroup\$ Related: codegolf.stackexchange.com/q/73916/17602 \$\endgroup\$ – Neil Aug 24 '16 at 7:51
  • 6
    \$\begingroup\$ @ColdGolf I highly doubt Wikipedia will die any time soon, but I added some more info. \$\endgroup\$ – DJMcMayhem Aug 24 '16 at 17:18
  • 1
    \$\begingroup\$ @brianh No, the smallest rep gain that turns odds to evens is 5 (question upvote). However, for the sake of this challenge, we're ignoring the fact that there are only certain amounts to gain rep. So 110 should give 1, even though there isn't a way to gain one rep. \$\endgroup\$ – DJMcMayhem Sep 13 '17 at 12:09

33 Answers 33

1
2
0
\$\begingroup\$

J, 39 bytes

f=.$:&>:`[@.(1=#@~.@(10&#.inv)@])
g=.0&f

Take the digits (10&#.inv)@], remove dups ~., check if the length is 1 (same basic idea as Dennis's solution). Recurse with incremented left and right args if it's not.

Note because $: recurses on the entire verb, we need to define a second verb to give the left arg an initial value of 0. I'd be curious to know how to avoid that, if possible.

Also, I'd be curious to know if there is a way to do this with ^: (do... while version).

Try it online!

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

TI-BASIC, 51 bytes

Ans→A:Ans→B:Repeat dim(Ans)=sum(Ans(1)=Ans:B+1→B:int(10fPart(B₁₀^(seq(⁻X-1,X,0,log(B:End:B-A

Slowly iterates through all integers greater than the input until the next repdigit has been reached.
Checks \$\approx20\$ numbers per second.

Input is the current reputation in Ans.
Output is the amount of rep required to reach the next repdigit.

Examples:

100
             100
prgmCDGF1D
              11
11132
           11132
prgmCDGF1D
           11090

Test case 11132 took \$\approx9.5\$ minutes to run.

Explanation:

Ans→A                                ;store the input into A and B
Ans→B
Repeat dim(Ans)=sum(Ans(1)=Ans       ;"do-while" the digits of B are not equal
B+1→B                                ;increment B
int(10fPart(B₁₀^(seq(⁻X-1,X,0,log(B  ;generate a list of B's digits reversed.  leave it in Ans
End
B-A                                  ;calculate the rep needed.  leave the result in Ans
                                     ;implicit print of Ans

Note: TI-BASIC is a tokenized language. Character count does not equal byte count.

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

Forth (gforth), 54 bytes

: f 0 over s>f flog f>s 1+ 0 do 10 * 1- loop mod abs ;

Try it online!

Explanation

  • Gets the smallest repdigit of the same length as the input.
  • Negates the result and gets the remainder of dividing the input by that number.
  • Returns the absolute value of the result (since positive modulo negative is negative)

Code Explanation

: f                \ start a new word definition
  0 over           \ place 0 on stack and copy input back to top
  s>f flog f>s     \ move number to floating point stack, get log10, move back to stack (truncate)
  1+               \ add 1 to get number of digits
  0 do             \ start a loop from 0 to number of digits - 1
    10 * 1-        \ repeatedly multiply by 10 and subtract 1 to get smallest repdigit of that size
  loop             \ end loop
  mod abs          \ get that absolute value of input modulo result
;                  \ end the word definition
   
 
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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