Chơi gôn


20

Các thiết lập:

Một mạng xã hội báo cáo số phiếu bầu mà một bài đăng có theo hai cách: số lượng upvote ròng (tổng số upvote - tổng số downvote) và % số phiếu được upvote , làm tròn đến số nguyên gần nhất (0,5 lần làm tròn lên). Số lượng upvote ròng là một số nguyên (không nhất thiết là số dương) và số thứ hai được đảm bảo là một số nguyên nằm trong khoảng từ 0 đến +100. Số lượng upvote và số lượng downvote đều là số nguyên 32 bit 0 hoặc dương (bạn có thể chỉ định ký hoặc không dấu). Giả sử rằng nếu không có tổng số phiếu, tỷ lệ phần trăm tăng được báo cáo là không.

Các thách thức:

Với hai số nguyên này (upvote net và% upvote), chương trình ngắn nhất bạn có thể viết là gì để xác định số lượng tổng số upvote thấp nhất mà bài đăng nhận được, với tất cả các ràng buộc ở trên thỏa mãn?

Các ràng buộc đầu vào được đảm bảo. Nếu đầu vào không thỏa mãn các ràng buộc ở trên, hành vi chương trình là tùy thuộc vào bạn. Thưởng kudos nếu nó không đi vào một vòng lặp vô hạn hoặc nếu không sự cố. Xem xét trả lại một số âm nếu bạn muốn có thêm hướng dẫn.

Quy tắc chung:

  • Đây là , vì vậy giải pháp hợp lệ ngắn nhất (tính bằng byte) sẽ thắng.
  • Đừng để ngôn ngữ mã-golf ngăn cản bạn đăng câu trả lời với các ngôn ngữ không mã hóa. Cố gắng đưa ra một câu trả lời càng ngắn càng tốt cho ngôn ngữ lập trình 'bất kỳ'. Phần thưởng dành cho ngôn ngữ Web phía máy khách như Javascript.
  • Nếu bạn có giải pháp thú vị bằng nhiều ngôn ngữ, hãy đăng chúng riêng biệt .
  • Các quy tắc chuẩn áp dụng cho câu trả lời của bạn, vì vậy bạn được phép sử dụng STDIN / STDOUT, các hàm / phương thức với các tham số thích hợp và kiểu trả về hoặc các chương trình đầy đủ. Cuộc gọi của bạn.
  • Lỗ hổng mặc định bị cấm.
  • Nếu có thể, vui lòng thêm một liên kết với một bài kiểm tra cho mã của bạn.
  • Ngoài ra, vui lòng thêm một lời giải thích về cách hoạt động của mã.
  • Hãy nhớ rằng nếu bạn đang thực hiện một thao tác chia số nguyên cắt ngắn (ví dụ 20/3 = 6) chứ không phải các vòng , điều đó có thể không hoàn toàn chính xác.
  • Các trường hợp thử nghiệm bổ sung khám phá các trường hợp cạnh trong các ràng buộc trên được hoan nghênh.
  • Trong khi loại trả về dự kiến ​​là số, boolean "false" có thể được sử dụng thay cho 0 .

Các trường hợp thử nghiệm ví dụ:

Cột đầu tiên chỉ là một số tham chiếu bao gồm để tạo điều kiện thảo luận.

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.)

Đó là tổng số không bình chọn trường hợp đặc biệt là khá khó khăn. Nếu có số lượng upvote và downvote bằng nhau, thì tỷ lệ upvote là 50%, ngoại trừ 0% khi không có phiếu bầu, phá vỡ tính đối xứng upvote-downvote.
xnor

2
@xnor 0/0 thường không được xác định, do đó phải đưa ra giả định. Với lựa chọn này, bạn nhận được "câu trả lời = đầu vào thứ hai" tự động nếu đầu vào thứ hai là 0 và tự động "trả lời = đầu vào đầu tiên" nếu đầu vào thứ hai là 100.
WBT

1
Trường hợp thử nghiệm được đề xuất mượn từ @nwellnhof : 1000, 100. Bạn có thể xác nhận rằng câu trả lời dự kiến ​​là 1000?
Arnauld


@Arnauld và nwellnhof: như đã lưu ý trong nhận xét ngay trước bạn, nếu đầu vào thứ hai = 100, câu trả lời = đầu vào đầu tiên. Nếu 100 thực sự là một tỷ lệ phần trăm được làm tròn thấp hơn một chút, nhiều hơn số đầu vào đầu tiên của số lượt upvote sẽ được yêu cầu để nhận phiếu bầu ròng = đầu vào đầu tiên và thử thách này tìm kiếm số lượng tổng số upvote thấp nhất.
WBT

Câu trả lời:


10

JavaScript (ES6), 47 byte

Đưa đầu vào theo cú pháp currying (n)(p), trong đó n là số lượng upvote ròng và p là tỷ lệ phần trăm của upvote. Có thể trở lại falsecho0 .

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

Hãy thử trực tuyến!

Đã bình luậ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)

Trường hợp cạnh

Đặt F n (u) = u / (u - n / 2) * 50 + 0,5

  • Nếu u = 0n = 0 , thì F n (u) = NaNF n (u) XOR p = p . Vì vậy, chúng tôi trả về u = 0 nếu n = p = 0 (lần lặp đầu tiên của trường hợp thử nghiệm đầu tiên) hoặc tiếp tục với đệ quy nếu p! = 0 (lần lặp đầu tiên của trường hợp thử nghiệm thứ 7).

  • Nếu u> 0u = n / 2 , thì F n (u) = + Infinity và - một lần nữa - F n (u) XOR p = p . Trừ khi p = 0 , chúng ta chỉ tiếp tục với lần lặp tiếp theo. (Điều này xảy ra trong các trường hợp thử nghiệm thứ 9 và 11.)


Tốt đẹp! Bạn nhận được tiền thưởng cho sự lựa chọn ngôn ngữ và bao gồm một lời giải thích + liên kết đến bản demo trực tiếp!
WBT

6

Stax , 17 byte

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

Chạy và gỡ lỗi nó

Đây là lực lượng vũ phu. Nó bắt đầu bằng 0 cho các ứng cử viên nâng cấp và tăng cho đến khi nó thỏa mãn công thức.

Giải nén, không được chỉnh sửa, và nhận xét, nó trông như thế này.

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

Chạy cái này


2

Sạch , 114 107 104 byte

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

Hãy thử trực tuyến!

Xác định hàm $ :: Int Int -> Real, trong đó các đối số là số nguyên được ký và giá trị trả về là số float có độ chính xác kép được biểu diễn chính xác bằng số nguyên có chữ ký 32 bit.

Nó kiểm tra mọi giá trị của cphương trình b=-cd/(d+1)để tìm một bthỏa mãn a+c=bb/(b+c)=d, vì ckết quả nhỏ nhất trong giá trị nhỏ nhất b, lấy phần tử đầu tiên của tập hợp tất cả các giải pháp.


2

05AB1E , 13 byte [bị hỏng nhẹ]

*²·т-/ò²т;Qi1

Hãy thử trực tuyến!

Giải trình:

Để giải quyết điều này, tôi giả sử đầu vào a, b và kết quả dự kiến ​​x. Đưa ra thông tin trong thiết lập, điều đó đã cho tôi phương trình:

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

Sắp xếp lại cho x cho

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

Trường hợp thử nghiệm duy nhất không hoạt động là 0, 50 - Tôi chỉ đơn giản là mã hóa cứng để kiểm tra điều này.

*²·т-/ò²т;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(...)] }

Điều này không hoạt động chính xác cho một số đầu vào. 90% với 800 phiếu bầu ròng có thể được thực hiện với 894 phiếu bầu tăng.
đệ quy

@recursive Tôi biết nó là gì. Nó giả định chính xác 90%, không phải 89,5%.
Geno Racklin Asher

Vâng, gần hơn với 90,5% trong trường hợp này nhưng có.
đệ quy

1
Bây giờ tôi nhận ra nó phức tạp hơn tôi nghĩ. Tôi sẽ nghĩ về nó, nhưng bây giờ tôi sẽ đánh dấu nó là hỏng.
Geno Racklin Asher

@GenoRacklinAsher Bây giờ tôi nhận ra nó phức tạp hơn tôi nghĩ. Tôi sẽ nghĩ về nó ... Đó là những loại bình luận tôi muốn đọc, xem chúng là dấu hiệu của một câu đố hay :-).
WBT

0

Đi 1,10, 154 byte

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}

Hãy thử nó trên Go Playground! (TIO chạy Go 1.9, không có math.Round)

Phiên bản ung dung

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
}

Theo lợi ích của việc thêm một lời giải thích, công thức trên cho r có thể được suy ra bằng cách giải đồng thời n=v-du = 100 * v/(v + d)cho v, trong đó v và d là số lượng upvote và downvote tương ứng. Công thức dẫn xuất không được xác định cho v = 50, vì vậy chúng ta phải xử lý trường hợp đó (mà chúng ta làm với câu lệnh if đầu tiên).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.