嫌いな人を追い払う


20

セットアップ:

ソーシャルネットワークは、投稿の投票数を2つの方法で報告します:純投票数(総投票数-総投票数)と、投票数割合(最も近い整数に切り上げ)(0.5切り上げ)。正味の投票数は整数(必ずしも正とは限らない)であり、2番目は0から+100までの整数であることが保証されています。アップ投票の数とダウン投票の数は、どちらもゼロまたは正の32ビット整数です(符号付きまたは符号なしを指定できます)。総投票数がゼロの場合、投票率はゼロとして報告されると仮定します。

チャレンジ:

これらの2つの整数(ネットのアップ投票と%のアップ投票)が与えられた場合、上記のすべての制約が満たされた状態で、投稿が受け取った総アップ投票の最小数を決定する最短のプログラムはどれですか?

入力制約が保証されています。入力が上記の制約を満たさない場合、プログラムの動作はユーザー次第です。無限ループに入ったりクラッシュしたりしなければ、賞賛に値します。さらにガイダンスが必要な場合は、負の数を返すことを検討してください。

一般的なルール:

  • これはであるため、最短の有効なソリューション(バイト単位で測定)が勝ちます。
  • コードゴルフ言語では、コードゴルフ以外の言語で回答を投稿しないようにしてください。「任意の」プログラミング言語の可能な限り短い答えを考えてみてください。Javascriptのようなクライアント側のWeb言語の賞賛。
  • 複数の言語で興味深いソリューションがある場合は、それらを個別に投稿してください
  • 回答には標準的な規則が適用されるため、STDIN / STDOUT、適切なパラメーターと戻り値型を使用した関数/メソッド、または完全なプログラムを使用できます。あなたの電話。
  • デフォルトの抜け穴は禁止されています。
  • 可能であれば、コードのテストへのリンクを追加してください。
  • また、コードの動作方法の説明を追加してください。
  • roundsではなく切り捨てる整数除算演算(たとえば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は一般に未定義であるため、仮定が必要です。この選択により、2番目の入力が0の場合、自動「answer = 2番目の入力」、2番目の入力が100の場合、自動「answer =最初の入力」が得られます
WBT

1
@nwellnhofから借用した推奨テストケース:1000, 100。予想される答えが正しいことを確認できます1000か?
アーナルド

1
憎しみは嫌いだから:)
Hosch250

@Arnauldおよびnwellnhof:コメントの直前に記載されているように、2番目の入力が100の場合、答えは1番目の入力です。100が実際に丸められたわずかに低いパーセントである場合、正味の投票=最初の入力を得るには、最初の入力より多くの賛成票が必要になり、このチャレンジは総投票数の最小数を求めます。
WBT

回答:


10

JavaScript(ES6)、47バイト

カリー化構文の入力を受け取ります(n)(p)。ここで、nは正味の投票数、pは投票数の割合です。に戻るfalse場合があり0ます。

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)

エッジケース

LET F N(U)= U /(U - N / 2)* 50 + 0.5

  • 場合はuが0 =及びN = 0、次いで、F N(U)= NaNに及びF 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 = Pp = 0でない限り、次の反復に進みます。(これは、9番目と11番目のテストケースで発生します。)


いいね!言語の選択、および説明とライブデモへのリンクを含めると、ボーナス賞賛がもらえます!
WBT

6

スタックス、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=bし、b/(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(...)] }

一部の入力では、これは正しく機能しません。800の正味投票で90%は、894の賛成票で行うことができます。
再帰的

@recursive私はそれが何であるかを知っています。89.5%ではなく、正確に90%を想定しています。
ジェノラックリンアッシャー

まあ、この場合は90.5%に近いが、はい。
再帰的

1
今では、思ったよりトリッキーであることに気付きました。私はそれについて考えますが、今のところ私はそれを壊れたものとしてマークします。
ジェノラックリンアッシャー

@GenoRacklinAsher これで、思ったよりトリッキーだとわかりました私はそれについて考えます...これらは私が読むのが好きな種類のコメントで、良いパズルの特徴であると考えています :-)。
WBT

0

Go 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はmath.Roundを持たない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
}

説明を追加の利益のために、Rについて上記式を同時に解くことによって導出することができるn=v-du = 100 * v/(v + d)、V及びdはそれぞれupvotesとdownvotesの数であり、V、のために。派生式はv = 50で未定義なので、そのケースを処理する必要があります(最初のifステートメントで行います)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.