90% fail this challenge?

I guess I'm not the only one who have seen this kind of image on Facebook (and other sites).

The picture above was posted 16 days ago, and has accumulated 51 k comments. Some answers: 0, 4, 8, 48, 88, 120, 124 and so on.

Challenge:

The mathematics in the question doesn't make sense1, so we can't find the correct answer by looking at the equation (or whatever you'd call that mess of numbers and operators). However, there's a very large number of people who have answered, and 10% of those people are right!

Take an integer, percent, decimal value in 0-1, or fraction N representing how many percent of the test group who failed the question (or optionally how many answered correctly), and a list of numbers representing the answers people post.

Find the number that 100-N percent of the test group answered and output it. If there are more than one answer that matches this criterion, then you must output all of them. If there are no answers that are represented 100-N percent of the time then you must output the number that's closest (measured in number of answers from 100-N).

To make the input rules for N clear: If 90 % fails, then you may input 90, 10, 0.9 or 0.1. You must specify which one you choose. You may assume that the percentage numbers are integers.

Test cases:

In the test cases below, N is the percentage that failed the test. You may choose to input using any of the allowed input methods.

N:  90   (meaning 90 % will fail and 10 % answer correctly)
List: 3 1 5 6 2 1 3 3 2 6
Output: 5   (because 90 % of the answers weren't 5)
---
N:  50   (50 % will answer correctly)
List: 3 6 1 6
Output: 6   (because 50 % of the answers weren't 6)
---
N:  69   (31 % will answer correctly)
List: 1 9 4 2 1 9 4 3 5 1 2 5 2 4 4 5 2 1 6 4 4 3
Output: 4    (because 31% of 22 is 6.82. There are 6 fours, which is the
closest to 6.82)
---
N = 10   (90 % will answer correctly)
List: 1 2 3 4 5 6 7 8 9 10
Output: 1 2 3 4 5 6 7 8 9 10 (because 9/10 will answer correctly. All numbers
have been answered the same number of times, thus
all are equally likely to be correct.
---
N:  90
List: 1 1 1
Output: 1


1 Please don't argue with me here. If you "know" the answer, join the other 10% and post it on Facebook!

• – Stewie Griffin Oct 2 '17 at 11:03
• What will be the maximum number of items in the list, if any? – Kevin Cruijssen Oct 2 '17 at 12:25
• @KevinCruijssen You may not assume a maximum value. The maximum is determined by the memory / datatype. The challenge is based on a post with 51k comments, so it should preferably cover at least that many items. – Stewie Griffin Oct 2 '17 at 12:53
• What should we do if more than one answer is equally close such in the example [1,3,3,3], 0.5? Do we need to output both in that case? – Emigna Oct 2 '17 at 13:14
• @Emigna yes, output both. See the 4th test case. – Stewie Griffin Oct 2 '17 at 13:46

MATL, 16 14 bytes

-1 byte thanks to @Giuseppe

-1 byte thanks to @LuisMendo

SY'ts/i-|tX<=)


Explanation:

        % implicit input
S       % sort
Y'      % run-length encoding
ts      % duplicate elements and sum (get number of elements)
/       % array right division (get array of probability for each answer)
i-|     % get absolute difference with second input
tX<     % duplicate and get minimum value
=)      % get each answer that match with the minimum value
% (implicit) convert to string and display


R, 65 bytes

function(N,A,x=table(A))names(x)[!(y=(abs(1-x/sum(x)-N)))-min(y)]


Try it online!

Takes N as a number between 0 and 1, and A as a vector (sometimes taken from STDIN in the TIO link so I don't have to turn them to R vectors). Returns a list of strings, as allowed by the OP.

function(N,A){
x <- table(A)               # count occurrences of each value in A
pct <- 1 - x/sum(x)         # compute percentages different from each value
y <- abs(pct - N)           # find distances from N
idx <- y!=min(y)            # find the indices of the minimum/minima
names(x)[idx]               # return the names of the table (strings)
}


Jelly, 19 bytes

ĠL€÷⁸L¤e€ạÐṂ¥Tị⁸QṢ¤


Try it online!

JavaScript (ES7), 103 99 bytes

Takes input as (a, r) where a is the list of answers and r is the expected success ratio in [0...1]. Returns a Set.

(a,r,m)=>a.map(n=>(d=a.reduce((p,c)=>p-=c==n,r*a.length)**2)>m||(d==m?s:(m=d,s=new Set)).add(n))&&s


Test cases

let f =

format = s => JSON.stringify(Array.from(s))

console.log(format(f([3, 1, 5, 6, 2, 1, 3, 3, 2, 6], 0.1))) // 5
console.log(format(f([3, 6, 1, 6], 0.5))) // 6
console.log(format(f([1, 9, 4, 2, 1, 9, 4, 3, 5, 1, 2, 5, 2, 4, 4, 5, 2, 1, 6, 4, 4, 3], 0.31))) // 4
console.log(format(f([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 0.90))) // 1 2 3 4 5 6 7 8 9 10
console.log(format(f([1, 1, 1], 0.10))) // 1

Python 2, 91 bytes

def f(l,p):c=[(abs(len(l)*p-l.count(a)),a)for a in l];print{v for x,v in c if x==min(c)[0]}


Try it online!

Takes P as success (0.1 = 10% correct)

05AB1E, 1916 15 bytes

Takes rate of success in the form 0.31 (meaning 31% succeeds).

{γD€gDO/IαWQÏ˜Ù


Try it online!

• I'm not sure if the behavior for this is correct. – Erik the Outgolfer Oct 2 '17 at 12:49
• @EriktheOutgolfer: Fixed :P – Emigna Oct 3 '17 at 11:19