7
\$\begingroup\$

Programs often list outcome statistics, such as this:

  • 54% of participants received an award
  • 69% of participants got a promotion
  • 85% of participants increased their salary

These percentages are the result of dividing a/x, where both a and x are whole numbers, and the result is rounded to the nearest hundredth.

Your task is to, given a set of percentages of arbitrary length and an arbitrary precision to which these percentages are rounded, find the three smallest whole numbers x of participants which could result in the given statistics.

To standardize answers, let's presume your input percentages are given as floating or fixed point decimals (your choice) like 0.54 and 0.69, and a precision given as an integer such as 2 meaning two digits past the decimal point.

For the above statistics, the first smallest number of participants is 13, and the 7, 9, and 11 participants had each of the given outcomes. Thus, 13 would be the first number in a set of three output numbers.

The winner will be the shortest piece of code counted in bytes. Any rounding method is acceptable in solutions, but solutions that offer solutions for multiple rounding schemes (floor, ceiling, or nearest) are encouraged.

Another example in Ruby

percentages = [ 0.5, 0.67, 0.83, 1.0 ]
precision = 2
smallest_group_size(percentages, precision) # Should produce [6, 12, 18]
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Could you provide more test cases? \$\endgroup\$
    – DJMcMayhem
    Dec 5, 2017 at 16:38
  • 1
    \$\begingroup\$ Are occasional floating point rounding errors acceptable? For instance, in JS: (1.35).toFixed(1) is 1.4 but (0.35).toFixed(1) is 0.3. \$\endgroup\$
    – Arnauld
    Dec 5, 2017 at 17:17
  • \$\begingroup\$ Very similar: Reverse Engineer Polling Statistics \$\endgroup\$ Apr 13, 2020 at 16:47

4 Answers 4

1
\$\begingroup\$

Python 3, 80 bytes

lambda l,p:[i for i in range(1,10**p)if[round(round(e*i)/i,p)for e in l]==l][:3]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 84 bytes

Takes input in currying syntax (a)(p), where a is an array of percentages and p is the precision.

a=>p=>(b=[],g=n=>b[2]?b:g(n+1,a.some(x=>((n*x+.5|0)/n).toFixed(p)-x)||b.push(n)))(1)

Test case

let f =

a=>p=>(b=[],g=n=>b[2]?b:g(n+1,a.some(x=>((n*x+.5|0)/n).toFixed(p)-x)||b.push(n)))(1)

console.log(f([ 0.5, 0.67, 0.83, 1.0 ])(2))

\$\endgroup\$
0
\$\begingroup\$

05AB1E, 17 bytes

3µNLN/².ò¹åPi¼N])

Try it online!

\$\endgroup\$
0
\$\begingroup\$

APL (Dyalog), 37 bytes

{3↑x/⍨((⍺⍕⍵)≡⍺⍕⊢÷⍨(⌊.5+⍵×⊢))¨x←⍳10*⍺}

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.