6
\$\begingroup\$

This is not an invitation for you to downvote everything I've posted. Just sayin' ;)

Challenge

Figure out how I can get myself back down to 1 reputation.

Details will follow input format, then followed by output.

Input

Input will consist of the my current reputation, the number of questions I have posted with an accepted answer (that is not my own), the number of questions I have posted without an accepted answer that have a valid answer that is not my own, and the number of answer downvotes that I have cast.

Details

Accepting an answer that is not my own gives me 2 rep. Unaccepting an answer takes away 2 rep from me. Undownvoting an answer gives me 1 rep (we assume that all of my answer votes are not locked in at the moment), and downvoting an answer makes me lose 1 rep (we assume there are enough answers on PPCG for me to not care about the number of answers that I can downvote). We also ignore potential serial vote reversal. Most of my reputation is going to have to be given away by bounties because I don't want to go around downvoting 5000 answers.

The challenge is to find the shortest way to get me back down to 1 rep using the shortest code. Please keep in mind that I need at least 125 rep to downvote and at least 75 rep to start a bounty. By "shortest way", I mean the way requiring the least actions, where each accept and downvote and their reverse actions and each bounty is a separate action. Note that it is impossible to award a bounty of more than +500 rep at once. Also note that you can only give out bounties in 50 rep increments.

If there is no way to get back down to 1 rep, then output some consistent error message. The error message may be output through crashing.

Output

Output the number of undownvotes, downvotes, accept-votes, unaccept-votes, and bounty actions I need to perform in any consistent order in any reasonable list format.

Test Cases

reputation, accepted_answers, no_accept_questions, answer_downvotes -> accepts, unaccepts, downvotes, undownvotes, bounties

101, 3, 2, 10 -> 0, 0, 0, 0, 1 // This one's easy, just give out a 100 rep bounty.
102, 3, 2, 10 -> 0, 1, 0, 1, 1 // Unaccept to get to 100, then undownvote to get to 101, then give a +100 bounty
103, 3, 2, 10 -> 0, 1, 0, 0, 1 // First unaccept one of those answers and then give out a 100 rep bounty or vice versa
3, 1, 0, 0 -> 0, 1, 0, 0, 0 // Unaccept that answer and lose the 2 rep
1000, 0, 1, 0 -> 1, 0, 1, 0, 2 // Accept an answer to get to 1002, then downvote an answer to get to 1001, then give out two +500 bounties

Rules

  • Standard Loopholes Apply
  • "Post a bunch of spam and get suspended" is not an answer, nor is anything similar
  • In the case of a tie between shortest methods, output one possible shortest method

  • This is , so the shortest code in bytes wins!

\$\endgroup\$
  • \$\begingroup\$ Can we assume you have arbitrarily many questions answered by other people? If so, all reputation counts can lead to 1: bounty down to below 152 rep if you're above that, accept answers until you're on 151 or 152 rep, downvote one answer to reach 151 if necessary, then do a 150 point bounty. Of course, there may well be shorter paths. \$\endgroup\$ – user62131 Jun 11 '17 at 6:08
  • \$\begingroup\$ @ais523 part of the input contains the number of questions with accepted answers and without accepted answers, so no. \$\endgroup\$ – HyperNeutrino Jun 11 '17 at 6:12
  • \$\begingroup\$ @user202729 Ah yes, good catch, my bad. Thanks! \$\endgroup\$ – HyperNeutrino Jun 11 '17 at 6:16
  • 1
    \$\begingroup\$ 1.Avocad 1.52.??? 2.Profit! \$\endgroup\$ – Matthew Roh Jun 11 '17 at 6:40
  • \$\begingroup\$ Aw, you already covered the 0 byte solution of getting yourself suspended! \$\endgroup\$ – Shaggy Jun 11 '17 at 9:19
3
\$\begingroup\$

Mathematica, 302 bytes

Golfed version:

Unprotect@Null;Null=0;f[1,_,_,_]={,,,,};f[r_,a_,n_,d_]:=(f[r,a,n,d]=l={∞,,,,};f[r,a,n,d]=#&@@MinimalBy[{If[r>74,{,,,,1}+f[r-50Min[⌈r/50⌉-1,10],a,n,d],l],If[r>124,{,,1,,}+f[r-1,a,n,d+1],l],If[d>0,{,,,1,}+f[r+1,a,n,d-1],l],If[a>0,{,1,,,}+f[r-2,a-1,n+1,d],l],If[n>0,{1,,,,}+f[r+2,a+1,n-1,d],l]},Tr])

Normal version:

Unprotect@Null; Null = 0;
f[1, _, _, _] = {, , , ,};
l = {\[Infinity], , , ,};
f[r_, a_, n_, d_] := (
  f[r, a, n, d] = l;
  f[r, a, n, d] = # & @@ MinimalBy[{
      If[r > 74, {, , , , 1} + 
        f[r - 50 Min[\[LeftCeiling]r/50\[RightCeiling] - 1, 10], a, n,
          d], l],
      If[r > 124, {, , 1, ,} + f[r - 1, a, n, d + 1], l],(* 
      downvote one more *)
      If[d > 0, {, , , 1,} + f[r + 1, a, n, d - 1], l],
      (* un-downvote *)
      If[a > 0, {, 1, , ,} + f[r - 2, a - 1, n + 1, d], l],
      (* un-accept. -2 rep *)
      If[n > 0, {1, , , ,} + f[r + 2, a + 1, n - 1, d], l]
      (* accept. +2 rep *)
      }, Tr]
  )

Note:

  1. Test this on https://sandbox.open.wolframcloud.com/ - paste the code, press Shift+Enter, then enter f[101,3,2,10] for example for first test case, then press Shift+Enter.
  2. Use Block[{Null=0}, ...] can save some bytes, but I haven't test that.
  3. Sometimes $IterationLimit=$RecursionLimit=∞ is necessary to get correct result.
  4. The function will return {∞,0,0,0,0} or similar (that is, the sum of elements in list is infinite) when it is impossible, and a list with format similar to that in the sample output when it is possible.
\$\endgroup\$
  • \$\begingroup\$ Can you add a way to test this? \$\endgroup\$ – HyperNeutrino Jun 11 '17 at 18:21
  • \$\begingroup\$ @HyperNeutrino Added. \$\endgroup\$ – user202729 Jun 12 '17 at 5:54

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.