Gra w hejterów

20

Ustawić:

Sieć społecznościowa podaje liczbę głosów, które ma post na dwa sposoby: liczbę głosów pozytywnych netto (liczba głosów pozytywnych - liczba głosów pozytywnych) oraz % głosów, które były głosami pozytywnymi , w zaokrągleniu do najbliższej liczby całkowitej (0,5 zaokrągla w górę). Liczba upvotów netto jest liczbą całkowitą (niekoniecznie dodatnią), a drugą gwarancją jest liczba całkowita od 0 do +100 włącznie. Liczba głosów pozytywnych i liczba głosów negatywnych są zarówno zerowymi, jak i dodatnimi 32-bitowymi liczbami całkowitymi (możesz określić podpisany lub niepodpisany). Załóżmy, że jeśli głosów jest zero, procentowy udział w głosowaniu jest zgłaszany jako zero.

Wyzwanie:

Biorąc pod uwagę te dwie liczby całkowite (wzrost liczby głosów netto i procent wzrostu liczby głosów), jaki jest najkrótszy program, jaki można napisać, który określa najniższą liczbę całkowitych głosów pozytywnych otrzymanego postu, przy spełnieniu wszystkich powyższych ograniczeń?

Ograniczenia wejściowe są gwarantowane. Jeśli dane wejściowe nie spełniają powyższych ograniczeń, zachowanie programu zależy od Ciebie. Dodatkowe nagrody, jeśli nie wejdzie w nieskończoną pętlę lub w inny sposób ulegnie awarii. Jeśli chcesz uzyskać więcej wskazówek, rozważ zwrócenie liczby ujemnej.

Główne zasady:

  • To jest , więc wygrywa najkrótsze prawidłowe rozwiązanie (mierzone w bajtach).
  • Nie pozwól, aby języki gry w golfa zniechęcały Cię do publikowania odpowiedzi w językach niekodujących golfa. Spróbuj znaleźć możliwie najkrótszą odpowiedź na „dowolny” język programowania. Dodatkowe wyróżnienia za język WWW po stronie klienta, taki jak Javascript.
  • Jeśli masz ciekawe rozwiązania w wielu językach, opublikuj je osobno .
  • Do odpowiedzi odnoszą się standardowe reguły , więc możesz używać STDIN / STDOUT, funkcji / metody z odpowiednimi parametrami i typem zwrotu lub pełnymi programami. Twoja decyzja.
  • Domyślne luki są zabronione.
  • Jeśli to możliwe, dodaj link z testem swojego kodu.
  • Dodaj także wyjaśnienie dotyczące działania kodu.
  • Pamiętaj, że jeśli wykonujesz operację dzielenia liczb całkowitych, która skraca (np. 20/3 = 6) zamiast zaokrąglać , może to nie być w pełni poprawne.
  • Dodatkowe przypadki testowe, które eksplorują przypadki brzegowe w powyższych ograniczeniach, są mile widziane.
  • Podczas gdy oczekiwany typ zwrotu jest liczbowy, zamiast wartości 0 można użyć wartości logicznej „fałsz” .

Przykładowe przypadki testowe:

Pierwsza kolumna to tylko numer referencyjny dołączony w celu ułatwienia dyskusji.

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.)
WBT
źródło
Ten szczególny przypadek braku całkowitej liczby głosów jest dość wybredny. Jeśli istnieje tyle samo głosów pozytywnych i negatywnych, procentowe głosy uprzywilejowane wynoszą 50%, z wyjątkiem 0%, gdy nie ma głosów, co łamie symetrię głosów pozytywnych i negatywnych.
xnor
2
@xnor 0/0 jest zasadniczo niezdefiniowany, więc należy przyjąć założenie. Dzięki temu wyborowi otrzymujesz automatyczną odpowiedź „odpowiedź = drugie wejście”, jeśli drugie wejście ma wartość 0, i automatyczne „odpowiedź = pierwsze wejście”, jeśli drugie wejście ma wartość 100.
WBT
1
Sugerowana sprawdzian zapożyczone z @nwellnhof: 1000, 100. Czy możesz potwierdzić, że oczekiwana odpowiedź to 1000?
Arnauld
1
Zagłosowano, bo hejterzy muszą nienawidzić :)
Hosch250
@Arnauld i nwellnhof: jak zauważono w komentarzu tuż przed twoim, jeśli drugie wejście = 100, odpowiedź = pierwsze wejście. Jeśli 100 byłby naprawdę zaokrąglonym nieco niższym procentem, więcej niż pierwsza liczba głosów przychodzących byłaby wymagana, aby uzyskać głosy netto = pierwsze wejście, a to wyzwanie ma na celu jak najmniejszą liczbę głosów pozytywnych.
WBT,

Odpowiedzi:

10

JavaScript (ES6), 47 bajtów

Pobiera dane wejściowe w składni curry (n)(p), gdzie n to liczba głosów pozytywnych netto, a p to procent głosów pozytywnych. Może wrócić falseza0 .

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

Wypróbuj online!

Skomentował

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)

Skrzynie na brzeg

Niech F n (u) = u / (u - n / 2) * 50 + 0,5

  • Jeśli u = 0 i n = 0 , to F n (u) = NaN i F n (u) XOR p = p . Tak więc zwracamy u = 0, jeśli n = p = 0 (pierwsza iteracja pierwszego przypadku testowego) lub kontynuujemy rekurencję, jeśli p! = 0 (pierwsza iteracja siódmego przypadku testowego).

  • Jeśli u> 0 i w = n / 2 , wówczas M n (U) = + nieskończoność oraz - ponownie - M N (U) XOR P = P . O ile p = 0 , kontynuujemy następną iterację. (Dzieje się tak w 9 i 11 przypadku testowym.)

Arnauld
źródło
Ładny! Otrzymujesz dodatkowe wyróżnienia za wybór języka oraz za dołączenie objaśnienia + link do pokazu na żywo!
WBT
6

Stax , 17 bajtów

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

Uruchom i debuguj

To brutalna siła. Zaczyna się od 0 dla pozytywnych głosów kandydatów i rośnie, aż spełni formułę.

Rozpakowane, niepolowane i skomentowane, wygląda to tak.

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

Uruchom ten

rekurencyjny
źródło
2

Czysty , 114 107 104 bajtów

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

Wypróbuj online!

Definiuje funkcję $ :: Int Int -> Real, w której argumentami są liczby całkowite ze znakiem, a zwracana wartość to liczba zmiennoprzecinkowa podwójnej precyzji, dokładnie reprezentowana przez 32-bitową liczbę całkowitą ze znakiem.

Sprawdza każdą wartość cw równaniu, b=-cd/(d+1)aby znaleźć bsatysfakcjonujące, a+c=ba b/(b+c)=dponieważ najmniejsze cwyniki dają najmniejsze b, bierze pierwszy element zestawu wszystkich rozwiązań.

Obrzydliwe
źródło
2

05AB1E , 13 bajtów [delikatnie złamany]

*²·т-/ò²т;Qi1

Wypróbuj online!

Wyjaśnienie:

Aby rozwiązać ten problem, założyłem dane wejściowe a, b i oczekiwany wynik x. Biorąc pod uwagę informacje w konfiguracji, dało mi to równanie:

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

Zmiana układu x daje

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

Jedyny przypadek testowy, w którym to nie działa, to 0, 50 - po prostu na stałe to sprawdziłem.

*²·т-/ò²т;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(...)] }
Geno Racklin Asher
źródło
To nie działa poprawnie dla niektórych danych wejściowych. 90% z 800 głosami netto można zrobić przy 894 głosach do góry.
rekurencyjny
@recursive Wiem co to jest. Zakłada dokładnie 90%, a nie 89,5%.
Geno Racklin Asher
Cóż, w tym przypadku bliżej 90,5%, ale tak.
rekurencyjny
1
Teraz zdaję sobie sprawę, że to trudniejsze niż myślałem. Zastanowię się, ale na razie oznaczę to jako zepsute.
Geno Racklin Asher
@GenoRacklinAsher Teraz zdaję sobie sprawę, że to trudniejsze niż myślałem. Pomyślę o tym ... Takie komentarze lubię czytać, widząc je jako znak rozpoznawczy dobrej układanki :-).
WBT
0

Idź 1.10, 154 bajtów

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}

Wypróbuj na Go Playground! (TIO uruchamia Go 1.9, który nie ma matematyki.)

Wersja bez golfa

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
}

W celu dodania wyjaśnienia powyższy wzór dla r można uzyskać przez jednoczesne rozwiązanie n=v-di u = 100 * v/(v + d)dla v, gdzie v i d są odpowiednio liczbą głosów pozytywnych i negatywnych. Formuła pochodna jest niezdefiniowana dla v = 50, więc musimy obsłużyć tę sprawę (co robimy z pierwszą instrukcją if).

ollien
źródło