击退仇敌


20

设置:

社交网络以两种方式报告帖子的投票数:净投票数(总投票数-总投票数)和被投票数的百分比,四舍五入到最接近的整数(四舍五入。)。净投票数是一个整数(不一定是正数),第二个保证是0到+100之间的一个整数。upvotes数和downvotes数均为零或正32位整数(可以指定有符号或无符号)。假设如果总票数为零,则投票的百分比将报告为零。

挑战:

给定这两个整数(净投票数和%投票数),您可以编写出最短的程序,该程序确定在满足上述所有约束的情况下收到的帖子的总投票最少的情况?

输入约束得到保证。如果输入不满足上述约束,则程序行为由您决定。如果不进入无限循环或崩溃,则可赢得荣誉。如果您需要更多指导,请考虑返回负数。

一般规则:

  • 这是,因此最短的有效解决方案(以字节为单位)获胜。
  • 不要让代码高尔夫球语言阻止您发布使用非代码高尔夫球语言的答案。尝试针对“任何”编程语言提出尽可能简短的答案。诸如Javascript之类的客户端Web语言的荣誉。
  • 如果您在多语言有趣的解决方案,张贴他们分开
  • 标准规则适用于您的答案,因此允许您使用STDIN / STDOUT,具有正确参数和返回类型的函数/方法或完整程序。你的来电。
  • 禁止默认漏洞
  • 如果可能的话,请添加一个带有测试代码的链接。
  • 另外,请添加代码说明。
  • 请记住,如果您要执行的整数除法运算会被截断(例如20/3 = 6)而不是舍入,则可能并不完全正确。
  • 欢迎在上述约束条件下探索边缘情况的其他测试用例。
  • 虽然期望的返回类型为数字,但可以使用布尔值“ false”代替0

测试用例示例:

第一列只是为了方便讨论而包括的参考数字。

ref net  %up    answer
1   0    0   => 0    
2   -5   0   => 0    
3   -4   17  => 1    
4   -3   29  => 2    
5   -2   38  => 3    
6   -1   44  => 4    
7   0    50  => 1    
8   5    100 => 5    
9   4    83  => 5    
10  3    71  => 5    
11  2    63  => 5    
12  1    56  => 5    
13  1234 100 => 1234
14  800  90  => 894  (tip: don't refer to this as the "last test case;" others may be added.)

总票数为零的情况非常挑剔。如果赞成票和反对票的数目相等,则赞成票的百分比为50%,但无票时为0%,这将破坏赞成票和反对票的对称性。
xnor

2
@xnor 0/0通常是未定义的,因此必须进行假设。使用此选择,如果第二个输入为0,则得到一个自动的“ answer =第二个输入”,如果第二个输入是100,则得到一个自动的“ answer =第一个输入”
。– WBT

1
从@nwellnhof借来的建议测试用例:1000, 100。您可以确认期望的答案是1000吗?
Arnauld

1
不赞成投票,因为仇恨者必须讨厌:)
Hosch250 '18

@Arnauld和nwellnhof:正如您前面的评论中所述,如果第二个输入= 100,则答案=第一个输入。如果100实际上是一个略低的四舍五入百分比,则要获得净票数=第一个输入,就需要比第一个输入要多的投票数,而这一挑战将寻求最少的总投票数。
WBT

Answers:


10

JavaScript(ES6),47个字节

以currying语法接受输入(n)(p),其中n是净投票数,p是投票数的百分比。可能返回false0

n=>p=>(g=u=>u/(u-n/2)*50+.5^p?g(u+1):u)(n>0&&n)

在线尝试!

已评论

n => p => (          // given n and p
  g = u =>           // g = recursive function taking u = number of upvotes
    u / (u - n / 2)  //   compute u / (total_votes / 2)
    * 50 + .5        //   turn it into a percentage, add 1/2
    ^ p ?            //   XOR it with p, which gives 0 if the integer parts are matching
                     //   if the result is not equal to 0:
      g(u + 1)       //     try again with u + 1
    :                //   else:
      u              //     stop recursion and return u
)(n > 0 && n)        // initial call to g() with u = max(0, n)

边缘情况

F n(u)= u /(u-n / 2)* 50 + 0.5

  • 如果u = 0n = 0,则F n(u)= NaNF n(u)XOR p = p。因此,如果n = p = 0(第一个测试用例的第一次迭代),则返回u = 0;如果p!= 0(第7个测试用例的第一次迭代),则继续递归。

  • 如果u> 0u = n / 2,则F n(u)= +无穷大 -再一次-F n(u)XOR p = p。除非p = 0,否则我们将继续进行下一个迭代。(这发生在第9和第11个测试用例中。)


真好!您将获得额外的荣誉,包括语言选择以及包括解释和实时演示的链接!
WBT

6

Stax,17 个字节

ëI╩½• ╠☺Vì∞«S↑♠αS

运行并调试

这是蛮力。对于候选投票,它以0开头,并递增直到满足公式。

拆开包装,松开包装并进行评论,看起来像这样。

0       push zero
{       start filter block...
        candidate upvotes is on the stack
  cHx-  calculate candidate downvotes for denominator (upvotes * 2 - net)
  c1?   if denominator is zero, replace it with 1
  :_    floating point division
  AJ*   multiply by 100
  j     round to integer
  ;=    is equal to second input?
        increment until a match is found
}gs

运行这个


2

干净114个 107 104字节

import StdEnv
? =toReal o toInt
$a d#e= ?d
= ?a+until(\c#b= ~c*e/(e-100.0)
= ?(?100*b/(?b+c))==e)inc 0.0

在线尝试!

定义函数$ :: Int Int -> Real,其中参数是有符号整数,返回值是可以由32位有符号整数精确表示的双精度浮点数。

它检查的每个值c方程中b=-cd/(d+1)找到一个b满足a+c=bb/(b+c)=d,因为最小c的最小的结果b,采取集中的所有解决方案中的第一要素。


2

05AB1E,13个字节[轻微损坏]

*²·т-/ò²т;Qi1

在线尝试!

说明:

为了解决这个问题,我假设输入a,b和预期结果x。给定设置中的信息,这给了我方程式:

 2x         100x
———— - a = ——————
 a           b

重新排列x给

        ab
x = ——————————
     2b - 100

唯一不适用的测试用例是0、50-我只是硬编码检查了一下。

*²·т-/ò²т;Qi1     Implicit Inputs: a, b              STACK (bottom to top)
*                 Multiply the inputs together       [ab]
 ²·               Take the second input * 2          [ab, 2b]
   т-             Subtract 100                       [ab, 2b - 100]
     /ò           Divide and round                   [round(ab/(2b-100))]
       ²т;Qi1     If 2nd input = 50, push 1 to stack
                  { Implicitly output top item of stack [either 1, or round(...)] }

对于某些输入,这不能正常工作。90票获得800票,可以894票获得。
递归

@recursive我知道这是什么。它准确地假设为90%,而不是89.5%。
Geno Racklin Asher

好吧,在这种情况下接近90.5%,但是可以。
递归

1
现在我意识到这比我想的要难。我会考虑的,但现在我将其标记为已损坏。
Geno Racklin Asher

@GenoRacklinAsher 现在,我意识到这比我想象的要棘手。我会考虑的...这些是我喜欢阅读的评论,将其视为一个好谜题的标志:-)。
WBT

0

转1.10,154字节

func h(n,u float64)float64{if u==50{return 1};r:=Round(n*u/(2*u-100));s:=Round(n*(u+.5)/(2*u-99));v:=s/(2*s-n);if v>1||Round(v*100)!=u{return r};return s}

在Go Playground上尝试一下!(TIO运行Go 1.9,它没有数学运算。)

非高尔夫版本

func haters(n, u float64) float64 {
    if u == 50 {
        return 1
    }
    r := Round(n * u / (2*u - 100))
    //Test the case where we were given a percentage that was rounded down (e.g. 90.4% given as 90%)
    //We test this by adding 0.5% to u. The denominator is just a simplified form of 2*(u+0.5) - 100
    s := Round(n * (u + .5) / (2*u - 99))
    //Check if s is a valid result
    v := s / (2*s - n)
    if v > 1 || Round(v*100) != u {
        return r
    }
    //s is strictly less than r, so we don't need to check the minimum.
    return s
}

为了增加说明,可以通过同时求解n=v-d和求解u = 100 * v/(v + d)v 来得出r的上式,其中v和d分别是上投票数和下投票数。对于v = 50,派生公式是不确定的,因此我们必须处理这种情况(我们使用第一个if语句进行处理)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.