23
\$\begingroup\$

Programming Puzzles and Code Golf has graduated from beta. Soon we will get a custom site design, and with that the reputation boundaries for privileges will go up. A lot of users will lose privileges on the site. So your task is to write a program that tells us how much extra reputation we'll need to keep our privileges.

Task

Your task is to write the shortest code to find the amount of extra reputation a user will need to keep their current privileges after the site design, given the number of reputation points.

Input / Output

You can accept input and give output in any way you like, so long as it follows these rules:

Input - An integer from 1 to 250000+ inclusive. Your program or function should be able to accept numbers bigger than this, but it must accept numbers in this range.

Output - An integer representing the number of reputation points the user will need to get to keep their current privileges after the graduation.

No standard loopholes, please.

Example algorithm

  1. Set variable i to the input
  2. Set variable r to variable i.
  3. While r is not in list beta:
    1. Subtract 1 from r.
  4. Set n to the position of r in beta.
  5. Set r to item n of graduated.
  6. Set variable o to the result of r - i.
  7. If o < 0:
    1. Set variable o to 0.
  8. Output variable o.

Tables

Table of privileges that will change

 | privilege name              | beta rep | graduation rep |
-+-----------------------------+----------+----------------+-
 | create tags                 |      150 |           1500 |
 | access review queues        |      350 |            500 |
 | cast close and reopen votes |      500 |           3000 |
 | established user            |      750 |           1000 |
 | edit questions and answers  |     1000 |           2000 |
 | create tag synonyms         |     1250 |           2500 |
 | approve tag wiki edits      |     1500 |           5000 |
 | access to moderator tools   |     2000 |          10000 |
 | protect questions           |     3500 |          15000 |
 | trusted user                |     4000 |          20000 |
 | access to site analytics    |     5000 |          25000 |
-+-----------------------------+----------+----------------+-
 | privilege name              | beta rep | graduation rep |

Table of privileges that won't change

 | privilege name               | reputation |
-+------------------------------+------------+-
 | create posts                 |          1 |
 | participate in meta          |          1 |
 | create wiki posts            |         10 |
 | remove new user restrictions |         10 |
 | vote up                      |         15 |
 | flag posts                   |         15 |
 | talk in chat                 |         20 |
 | comment everywhere           |         50 |
 | set bounties                 |         75 |
 | create chatrooms             |        100 |
 | edit community wiki          |        100 |
 | vote down                    |        125 |
-+------------------------------+------------+-
 | privilege name               | reputation |

Testcases

wizzwizz4                |   750 |  2250
cat                      |  2004 |  7996
Dennis ♦                 | 72950 |     0
Dr Green Eggs and Ham DJ |  4683 | 15317
New User                 |     1 |     0

Not all reputation counts are correct at time of writing
If you want your past or present reputation count here, just comment below and I'll maybe add it.

\$\endgroup\$
  • 2
    \$\begingroup\$ You should include a few test cases. \$\endgroup\$ – Dennis Apr 23 '16 at 15:43
  • 3
    \$\begingroup\$ Btw the participate on meta rep threshold in 5 for beta sites as well. PPCG had it customized so new users can use the sandbox. This shouldn't change when we graduate. \$\endgroup\$ – Dennis Apr 23 '16 at 15:44
  • 1
    \$\begingroup\$ @cat I actually used that; thanks! \$\endgroup\$ – wizzwizz4 Apr 23 '16 at 15:46
  • 2
    \$\begingroup\$ @wizzwizz4 Thanks for that; my head is starting to explode and I only wanted 250 more rep. \$\endgroup\$ – cat Apr 23 '16 at 16:48
  • 1
    \$\begingroup\$ @wizzwizz4 Nah, it would just look low next to Dennis :-) \$\endgroup\$ – xnor Apr 24 '16 at 6:48
4
\$\begingroup\$

Python, 101 bytes

lambda n:max(0,eval("+(n>=%d)*%d"*7%(5e3,5e3,4e3,5e3,35e2,5e3,2e3,5e3,15e2,2e3,5e2,15e2,150,15e2))-n)
\$\endgroup\$
  • \$\begingroup\$ I think you're giving the new rep you need, not the increase. So, f(750) should be 1250, not 2000. Should be an easy fix. \$\endgroup\$ – xnor Apr 23 '16 at 20:10
  • \$\begingroup\$ @xnor Well, f(750) should be 2250, not 1250 :) \$\endgroup\$ – orlp Apr 23 '16 at 20:20
  • \$\begingroup\$ Still need to have f(72950) give 0. \$\endgroup\$ – xnor Apr 23 '16 at 20:33
  • \$\begingroup\$ Your eval trick is really good. Combining it with my list compression gives 83: lambda n:max(eval("+(n>=%s*500)*%s*500"*7%(.3,3,1,3,3,4,4,10,7,10,8,10,10,10))-n,0). \$\endgroup\$ – xnor Apr 23 '16 at 21:12
  • \$\begingroup\$ Do you think you could add a code explanation and breakdown? \$\endgroup\$ – wizzwizz4 Apr 24 '16 at 6:58
4
\$\begingroup\$

Jelly, 40 37 bytes

19112203.3b11×ȷḞ>Ḥ¬×9999322D‘¤S×.ȷ_»0

Try it online! or verify all test cases.

How it works

19112203.3b11×ȷḞ>Ḥ¬×9999322D‘¤S×.ȷ_»0  Main link. Argument: n

19112203.3b11                          Convert the float to base 11. Yields
                                       [10, 8, 7, 4, 3, 1, 0.30000000074505806].
             ×ȷ                        Multiply each by 1000.
               Ḟ                       Floor. Yields
                                       [10000, 8000, 7000, 4000, 3000, 1000, 300].
                 Ḥ                     Unhalve; yield 2n.
                >                      Compare each integer in the list with 2n.
                  ¬                    Negate the resulting Booleans.
                             ¤         Chain the three links to the left:
                    9999322D           Convert the integer to base 10.
                            ‘          Increment each digit. Yields 
                                       [10, 10, 10, 10, 4, 3, 3].
                   ×                   Multiply the Booleans with the corr. digits.
                              S        Compute the sum of the products.
                               ×.ȷ     Multiply the sum by 500.
                                  _    Subtract n.
                                   »0  Return the maximum of the difference and 0.
\$\endgroup\$
3
\$\begingroup\$

CJam, 38 bytes

0000000: 72 69 5f 35 30 2f 22 64 50 46 28 1e 0a 03 22 66  ri_50/"dPF(..."f
0000010: 3c 3a 2b 22 fa c8 96 64 32 1e 0f 00 22 3d 69 65  <:+"...d2..."=ie
0000020: 32 5c 2d 55 65 3e                                2\-Ue>

Try it online! or verify all test cases.1

How it works

ri                        Read an integer n from STDIN.
  _50/                    Push a copy and divide it by 50.
     "…"                  Push the string with code points [100 80 70 40 30 10 3].
        f<                Compare each code point with n / 50.
          :+              Add the resulting Booleans.
            "…"           Push the string with code points
                          [250 200 150 100 50 30 15 0].
               =          Select the one at the index of the sum.
                i         Convert from character to integer.
                 e2       Multiply by 100.
                   \-     Subtract n from the product.
                     Ue>  Take the maximum of the difference and 0.

1 Note that the code contains a null byte, which causes problems in some browsers.

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

JavaScript (ES6), 137 135 102 81 bytes

n=>(n-=[5,0,.3,.6,1,2,3,4][[.3,1,3,4,7,8,10].findIndex(m=>m*500>n)+1]*5e3)<0?-n:0

If the user has 5000 or more reputation then findIndex fails, returning -1, so the result is incremented to that I can index into the array of new reputations needed. Edit: Saved 21 bytes by scaling the input and output array.

   [.3,1,3,4,7,8,10]        Old reputations of note, divided by 500
    .findIndex(m=>m*500>n)  Skip ones that have been achieved
     +1                     Normalise the return value
  [5,0,.3,.6,1,2,3,4][]     Index into new reputation needed
   *5e3                     Scaling factor
 n-=                        Compare to the current reputation
()<0?-n:0                   Negate to return the requirement
\$\endgroup\$
  • \$\begingroup\$ Some answers don't work with the New User testcase. If yours doesn't work, please fix it. \$\endgroup\$ – wizzwizz4 Apr 23 '16 at 17:19
  • \$\begingroup\$ @wizzwizz4 Ah, the meta privilege change? Sure, that's a simple fix. \$\endgroup\$ – Neil Apr 23 '16 at 19:04
  • \$\begingroup\$ Do you think you could add a code explanation and breakdown? \$\endgroup\$ – wizzwizz4 Apr 24 '16 at 6:58
2
\$\begingroup\$

Python, 88 bytes

lambda n:max(sum(500*b*(n>=a*500)for a,b in zip([.3,1,3,4,7,8,10],[3,3,4]+[10]*4))-n,0)

For each new beta privilege exceeded, adds the rep amount needed to get to the next graduated privilege. Then, the additional rep needed is the new rep minus the current rep, but no less than 0.

Both rep boundary lists are shortened by rep in multiples of 500.

\$\endgroup\$
  • \$\begingroup\$ You might as well replace [3]*2+[4] with [3,3,4], 9 vs 8 bytes. \$\endgroup\$ – CalculatorFeline Apr 23 '16 at 23:33
  • \$\begingroup\$ @CatsAreFluffy Thanks, I forgot I changed them from decimals where it's worth it. \$\endgroup\$ – xnor Apr 23 '16 at 23:35
2
\$\begingroup\$

Python 156 152 bytes

s=str.split;n=input()
for k,v in map(s,s('5e3 5r4e3 5r3500 30./7r2e3 5r1500 10./3r500 6r1 1','r')):
 w=u(k);r=eval(v)*w
 if w<=n:print max(0,r-n);break

The data string (5e3 5r4e3 5r3500 30./7r2e3 5r1500 10./3r500 6r1 1) is a list with the format (old_rep1) (new_rep1/old_rep1)r(old_repr) (new_rep2/old_rep2) only including privleges which set the new max rep (users with >750 rep still need at least 3k rep post-graduation, even though they will be an established user at 1k. The list is sorted from highest rep first to lowest rep last.

\$\endgroup\$
  • \$\begingroup\$ Do you think you could add a code explanation and breakdown? \$\endgroup\$ – wizzwizz4 Apr 24 '16 at 7:00
  • \$\begingroup\$ @wizzwizz4 Done. \$\endgroup\$ – pppery Apr 24 '16 at 18:16
  • \$\begingroup\$ Hmm... now that is a clever technique. \$\endgroup\$ – wizzwizz4 Apr 24 '16 at 18:38
1
\$\begingroup\$

Pyth - 71 70 69 77 75 77 bytes

eS,Z-@CM"\x00ǴϨלߐৄஸᎈ✐㪘丠憨"xKCM"\x00ŞˮϨӢǴלߐඬྠᎈ"e<#QK

Test Suite.

\$\endgroup\$
  • \$\begingroup\$ This doesn't work for the wizzwizz4 testcase. \$\endgroup\$ – wizzwizz4 Apr 23 '16 at 16:36
  • 1
    \$\begingroup\$ Some answers don't work with the New User testcase. I've noticed that yours doesn't; please fix it! \$\endgroup\$ – wizzwizz4 Apr 23 '16 at 17:19
  • \$\begingroup\$ Do you think you could add a code explanation and breakdown? \$\endgroup\$ – wizzwizz4 Apr 24 '16 at 6:59
1
\$\begingroup\$

LiveCode 8, 318 bytes

function g c
    local b,g,r
    put c into r
    put "0.15,0.35,0.5,0.75,1,1.25,1.5,2,3.5,4,5" into b
    split b by ","
    put "0.3,0.1,0.6,0.2,0.4,0.5,1,2,3,4,5" into g
    split g by ","
    repeat with i=1 to 11
       if c>b[i]*1000 and not c>g[i]*5000 then put max(r,g[i]*5000) into r
    end repeat
    return r-c
 end g

As wizzwizz4 suggested, here is an explanation:

function g c 

Create a function named g taking a single parameter c. c is the user's current reputation. Equivalent to def g(c) in Python.

local b,g,r

Create three local variables: b,g, and r. b will be the reputation cutoffs for privileges in beta, g will contain the new reputation cutoffs after graduation, and r will represent the total reputation the user will have to have after graduation to retain their privileges.

put c into r

This copies the value of c(the user's current reputation) into r. Equivalent to r=c in Python)

put "0.15,0.35,0.5,0.75,1,1.25,1.5,2,3.5,4,5" into b

Similar to above, this sets b to a string containing a comma-deliminated list of the reputation cutoffs in beta, divided by 1000. Equivalent to b="0.15,0.35,0.5,0.75,1,1.25,1.5,2,3.5,4,5" in Python.

split b by ","

This splits the local variable b into an array, using , as the delimiter. This array now contains the reputation cutoffs in beta, divided by 1000. Equivalent to b.split(",") in Python.

put "0.3,0.1,0.6,0.2,0.4,0.5,1,2,3,4,5" into g
split g by ","

Same as above, except that g now contains a list of the reputation cutoffs after graduation, divided by 5000

repeat with i=1 to 11

Similar to a for loop in other languages, this repeates 11 times, with i assigned the next value in the sequence 1 to 11 each time. Arrays in LiveCode start at index 1. In Python, this would be for i in range(11).

if c>b[i]*1000 and not c>g[i]*5000 then put max(r,g[i]*5000) into r

This is the main logic of the function. It checks to see if the user has enough reputation for the privilege in position i of the beta list, if so, and if they don't have enough reputation for the privilege after graduation, it sets the variable r(representing the total reputation that the user will have to have to retain their privileges after graduation) to the reputation cutoff after graduation for that privilege (only if the new reputation is higher than the previous one). The equivalent Python code would be if c>b[i]*1000 and not c>g[i]*5000: r=max(g[i]*5000,r) end repeat Ends the repeat loop. Similar to C or Java's }. LiveCode uses the syntax end 'insert contruct name to end a repeat loop, an if, a switch etc...

return r-c

Fairly self-explanatory.

end g

Ends the function g.

\$\endgroup\$
  • \$\begingroup\$ A brand new user post an answer on my challenge? I'm honoured. +1 and welcome to the site. \$\endgroup\$ – wizzwizz4 Apr 24 '16 at 20:41
  • \$\begingroup\$ You could improve this post by adding a code explanation and breakdown. (Explain what the code does, line by line, below your code.) \$\endgroup\$ – wizzwizz4 Apr 24 '16 at 20:42
  • \$\begingroup\$ @wizzwizz4 Added explanation. \$\endgroup\$ – penalosa Apr 25 '16 at 21:48

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.