Giocare a golf con gli odiatori


20

Il set up:

Un social network riporta il numero di voti che un post ha in due modi: il numero di voti netti ( voti totali - voti totali ridotti) e la percentuale di voti che sono stati votati , arrotondata al numero intero più vicino (0,5 arrotondamenti per eccesso). Il numero di voti netti è un numero intero (non necessariamente positivo) e il secondo è garantito per essere compreso tra 0 e +100 inclusi. Il numero di voti positivi e il numero di voti negativi sono numeri interi a 32 bit zero o positivi (è possibile specificare con segno o senza segno). Supponiamo che se ci sono zero voti totali, la percentuale votata viene indicata come zero.

La sfida:

Dati questi due numeri interi (voti netti e% votati), qual è il programma più breve che puoi scrivere che determina il numero più basso di voti totali post ricevuti, con tutti i vincoli sopra indicati soddisfatti?

I vincoli di input sono garantiti. Se l'input non soddisfa i vincoli di cui sopra, il comportamento del programma dipende da te. Complimenti bonus se non entra in un ciclo infinito o altrimenti si blocca. Considera di restituire un numero negativo se desideri ulteriori indicazioni.

Regole generali:

  • Questo è , quindi vince la soluzione valida più breve (misurata in byte).
  • Non lasciare che le lingue di code-golf ti scoraggino dal pubblicare risposte con lingue non codegolfing. Prova a trovare una risposta il più breve possibile per "qualsiasi" linguaggio di programmazione. Complimenti bonus per un linguaggio Web lato client come Javascript.
  • Se hai soluzioni interessanti in più lingue, pubblicale separatamente .
  • Per la tua risposta valgono regole standard , quindi puoi usare STDIN / STDOUT, funzioni / metodo con i parametri e il tipo di ritorno corretti o programmi completi. La tua chiamata.
  • Sono vietate le scappatoie predefinite .
  • Se possibile, aggiungi un link con un test per il tuo codice.
  • Inoltre, aggiungi una spiegazione del funzionamento del codice.
  • Tieni presente che se stai eseguendo un'operazione di divisione di numeri interi che si tronca (ad es. 20/3 = 6) anziché arrotondamenti , ciò potrebbe non essere del tutto corretto.
  • Sono benvenuti ulteriori casi di test che esplorano i casi limite nei vincoli precedenti.
  • Mentre il tipo di ritorno previsto è numerico, è possibile utilizzare "false" booleano al posto di 0 .

Esempi di test:

La prima colonna è solo un numero di riferimento incluso per facilitare la discussione.

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

Quel caso speciale con zero voti totali è piuttosto schizzinoso. Se esiste un numero uguale di voti positivi e negativi, i voti percentuali sono del 50%, eccetto lo 0% quando non ci sono voti, interrompendo la simmetria voto positivo-negativo.
xnor

2
@xnor 0/0 non è generalmente definito, quindi è necessario fare un presupposto. Con questa scelta, si ottiene una "risposta = secondo input" automatica se il secondo input è 0 e una "risposta = first input" automatica se il secondo input è 100.
WBT,

1
Banco di prova suggerita preso in prestito da @nwellnhof: 1000, 100. Puoi confermare che la risposta prevista è 1000?
Arnauld,

1
Sottovalutato, perché gli odiatori devono odiare :)
Hosch250,

@Arnauld e nwellnhof: come notato nel commento appena prima del tuo, se il secondo input = 100, la risposta = primo input. Se il 100 fosse in realtà una percentuale leggermente inferiore arrotondata, per ottenere voti netti = primo input sarebbe richiesto più del primo input # di voti positivi, e questa sfida cerca il numero più basso di voti totali.
WBT,

Risposte:


10

JavaScript (ES6), 47 byte

Accetta input nella sintassi del curry (n)(p), dove n è il numero di voti netti e p è la percentuale di voti. Può tornare falseper0 .

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

Provalo online!

Commentate

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)

Custodie per bordi

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

  • Se u = 0 e n = 0 , allora F n (u) = NaN e F n (u) XOR p = p . Quindi, restituiamo u = 0 se n = p = 0 (prima iterazione del primo caso di test) o continuiamo con la ricorsione se p! = 0 (prima iterazione del 7o caso di test).

  • Se u> 0 e u = n / 2 , allora F n (u) = + Infinito e - di nuovo - F n (u) XOR p = p . A meno che p = 0 , proseguiamo con la prossima iterazione. (Ciò accade nei casi di test 9 e 11).


Bello! Ottieni bonus bonus per la scelta della lingua e per l'inclusione di una spiegazione + collegamento a una demo dal vivo!
WBT,

6

Stax , 17 byte

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

Esegui ed esegui il debug

Questa è forza bruta. Inizia con 0 per i voti dei candidati e aumenta fino a quando non soddisfa la formula.

Disimballato, non golfato e commentato, sembra così.

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

Esegui questo


2

Pulito , 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

Provalo online!

Definisce la funzione $ :: Int Int -> Real, in cui gli argomenti sono numeri interi con segno e il valore restituito è un float a doppia precisione esattamente rappresentabile da un numero intero con segno a 32 bit.

Controlla ogni valore cdell'equazione b=-cd/(d+1)per trovare un risultato bsoddisfacente a+c=be b/(b+c)=d, dal momento che il più piccolo crisulta nel più piccolo b, prende il primo elemento dell'insieme di tutte le soluzioni.


2

05AB1E , 13 byte [lievemente rotto]

*²·т-/ò²т;Qi1

Provalo online!

Spiegazione:

Per risolvere questo, ho assunto gli input a, b e il risultato atteso x. Date le informazioni nel setup, che mi ha dato l'equazione:

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

La riorganizzazione per x dà

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

L'unico caso di test per cui non funziona è 0, 50 - Ho semplicemente codificato per verificarlo.

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

Questo non funziona correttamente per alcuni input. Il 90% con 800 voti netti può essere fatto con 894 voti in più.
ricorsivo

@recursive So di cosa si tratta. Presuppone esattamente il 90%, non l'89,5%.
Geno Racklin Asher,

Bene, più vicino al 90,5% in questo caso, ma sì.
ricorsivo

1
Ora mi rendo conto che è più complicato di quanto pensassi. Ci penserò, ma per ora lo segnerò come rotto.
Geno Racklin Asher,

@GenoRacklinAsher Ora mi rendo conto che è più complicato di quanto pensassi. Ci penserò ... Questi sono i tipi di commenti che mi piace leggere, vedendoli come il segno distintivo di un buon puzzle :-).
WBT

0

Vai 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}

Provalo su Go Playground! (TIO esegue Go 1.9, che non ha matematica.Round)

Versione Ungolfed

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
}

Nell'interesse di aggiungere una spiegazione, la formula precedente per r può essere derivata risolvendo simultaneamente n=v-de u = 100 * v/(v + d)per v, dove v e d sono rispettivamente il numero di voti positivi e negativi. La formula derivata non è definita per v = 50, quindi dobbiamo gestire quel caso (cosa che facciamo con la prima istruzione if).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.