# Find the C-factor of a vote

In this challenge you will be determining how controversial a vote is, given an array of other votes, by figuring out a number called the C-factor. What is the C-factor, you ask?

Well, imagine you've got multiple votes on an election. We'll use 1 and 0 for the sake of the challenge to represent two different candidates in an election. Here's the ten votes in our sample election:

0110111011


Now, say we want to find the C-factor of any vote for candidate 0. We can do that with the following function:

$$f(o,v) = abs(o-mean(v))$$

In $$\f\$$, o is the vote we want to determine the C-factor for, and v is an array of votes. So, using our function, to get the C-factor of any vote for candidate 0:

$$f(0, [0,1,1,0,1,1,1,0,1,1]) = 0.7$$

A lower C-factor shows that the vote was less controversial in comparison to the other votes. So, a vote for candidate 0 is more different from the other votes than a vote for candidate 1. In comparison, the C-factor for a candidate 1 vote is $$\0.3\$$, so it is less controversial because it is more like the other votes.

## The Challenge

Write a function $$\f(o,v)\$$ to determine the C-factor of a vote o given results of a vote v.

• o must be an integer, either 0 or 1.

• v must be an array (or similar container type depending on language specifications) of arbitrary length containing zeroes and ones.

• The function should return or print to the console the resulting C-factor given the function parameters, using the formula above or a modified method.

Good luck! The least bytes wins (winner chosen in five days).

• Isn't mean(v) equal to 0.7 in your example? Jun 19, 2019 at 13:22
• @HyperNeutrino Yes. What's the issue? Jun 19, 2019 at 13:23
• How is abs(0 - 0.7) equal to 0.3? Jun 19, 2019 at 13:23
• Ah. Fixed the example. I reversed the two numbers Jun 19, 2019 at 13:24
• Oh okay. Thanks for clarifying! Jun 19, 2019 at 13:24

# R, 23 bytes

function(o,v)mean(o!=v)


Try it online!

The challenge boils down to computing the proportion of values in v different from o (i.e. mean(xor(o,v))). We can therefore avoid using abs.

• Also works for arbitrary voting representations, neat. Jun 20, 2019 at 7:54

# Jelly, 3 bytes

ạÆm


Try it online!

Literally just "absolute difference to mean".

ạÆm  Main link
ạ    Absolute difference
Æm  Arithmetic Mean


If you invert the arguments you can invert the atoms.

# APL (Dyalog Unicode), 9 8 5 bytes

≠⌹⊢=⊢


Try it online!

Anonymous train. Thanks to @Adám for a byte saved, and thanks to @ngn for 3 bytes!

### How:

≠⌹⊢=⊢ ⍝ Anonymous Train
⊢ ⍝ The right argument (⍵)
⊢=  ⍝ Equals itself. Generates an array of 1s
≠     ⍝ XOR left (⍺) and right args; generates ⍵ or (not ⍵), depending on ⍺.
⌹    ⍝ Divide these matrices.

• you can do it in 5. hint: ⌹
– ngn
Jun 21, 2019 at 8:53

# Actually, 3 bytes

♀^æ


Try it online!

Explanation:

♀^æ
♀^   XOR each vote with candidate (0 if matches, 1 if not)
æ  mean of the list


# 05AB1E, 3 bytes

ÅAα


Try it online!

• I'm 30 seconds too late.. My order was different though, first α then ÅA ;p Jun 19, 2019 at 13:32
• @KevinCruijssen I watched your solution come in in real-time, I started to comment, and it was deleted, all within about 30 seconds. Hilarious! Jun 19, 2019 at 13:33
• @KevinCruijssen I don't really understand how the two orders work the same... :-) My 05AB1E knowledge is not very good Jun 19, 2019 at 13:34
• @KevinCruijssen Ah, I see. What was confusing me is that the two approaches give different results for arbitrary numbers; but for 0/1 inputs they seem to agree. Example Jun 19, 2019 at 14:23
• @LuisMendo Ah, yes, you're indeed right. I tested it with a few other integers, but those gave the same results as well regardless of the order (but your test case with 0.8 indeed differs). If the input could have contained something else besides 0/1, your approach of first getting the mean and then the absolute difference is correct when we compare it to the formula in the challenge description. With only 0s/1s some alternative 3-byters are possible as well, like ÊÅA. Jun 19, 2019 at 16:48

# Octave, 16 bytes

@(a,b)mean(a!=b)


Try it online!

# Elm 0.19, 48 bytes

f a v=abs(v-(List.sum a/toFloat(List.length a)))


Online demo here.

# Attache, 11 8 bytes

Mean@/=


Try it online! Takes arguments as f[o, v].

Nothing terribly original.

## Alternative approaches

11 bytes: Average@/=

11 bytes: ${1-x~y/#y} Counts the occurrences of x in y divided by the length of y, then subtracts that from 1. 11 bytes: {1-_2~_/#_} (Arguments are reversed for this one) 15 bytes: ${Sum[x/=y]/#y} A more explicit version of the above, without Average.

# JavaScript, 38 bytes

n=>a=>a.map(x=>n-=x/a.length)|n<0?-n:n


Try it

# Proton, 26 bytes

(o,v)=>1-v.count(o)/len(v)


Try it online!

The output is a fraction because Proton uses sympy instead of regular Python numbers for better precision.

(-7 bytes; abs-diff to mean is shorter than mean of abs-diff; I'm actually dumb)

-1 byte thanks to Rod

• @Rod I was trying to figure out how to optimize for the 1/0 input restriction but failed. Thanks! Jun 19, 2019 at 14:38

# Perl 6, 20 bytes

{@_.sum/@_}o(*X!= *)


Try it online!

* X!= * is an anonymous function which takes the not-equals cross product of its two arguments. It produces a sequence of Booleans; for example, 1 X!= (1, 0, 1) evaluates to (False, True, False).

{ @_.sum / @_ } is another anonymous function that returns the average of its arguments. Boolean True evaluates to 1 numerically, and False to 0.

The o operator composes those two functions into one.

# Enlist, 3 bytes

nÆm


Try it online!

nÆm  Main Link
n    Not Equals (returns a list of whether or not each element is unequal to to the value)
Æm  Arithmetic Mean


The language is very heavily inspired by Jelly to the point that it's probably more like me experimenting to try to recreate the structure of how Jelly is parsed with my own code.

-1 byte thanks to Mr. Xcoder

• You can use n instead of _...A to save 1 (Try it online!). Jun 19, 2019 at 18:45
• @Mr.Xcoder Ooh nice. Yeah I realized the != trick after making this lol. Thanks! Jun 19, 2019 at 19:15

# Retina 0.8.2, 27 bytes

(.),((?(\1)|()).)*#3/$#2  Try it online! Outputs a fraction. Explanation: The first group captures o and the second group captures each entry of v, while the conditional ensures that the third group only makes a capture when the vote is dissimilar. The $# construction then returns the count of the relevant captures as desired.

# Perl 5-MList::Util=sum, 30 bytes

sub f{abs((shift)-sum(@_)/@_)}


Try it online!

# K (Kona), 17 bytes

{_abs+/y-x%.0+#x}


Try it online!

# C (gcc), 62 bytes

float f(o,v,l,k)int*v;{float r=0;for(k=l;k;)r+=v[--k]^o;r/=l;}


Try it online!

Call as f(int o, int *v, int length_of_v).

# Japt v2.0a0, 6 bytes

aVx÷Vl


Try it

# JavaScript (Node.js), 47 42 bytes

-5 bytes from @arnauld

a=>b=>Math.abs(a-eval(b.join+)/b.length)


Try it online!

# Java 8, 47 bytes

v->o->(o-=v.get().sum()/v.get().count())<0?-o:o


Try it online.

or alternatively:

v->o->Math.abs(o-v.get().sum()/v.get().count())


Try it online.

For both the inputs are a Supplier<DoubleStream> for the list of votes v and double for the vote o.

Explanation:

v->o->                 // Method with DoubleStream-Supplier & double parameters and double return
(o-=v.get().sum()    //  Get the sum of the DoubleStream-Supplier
/v.get().count() //  Divide it by the amount of items in the DoubleStream-Supplier
)                //  Subtract this from o
<0?-o:o         //  And get the absolute value of this updated value o


# Common Lisp 49 bytes

Solution:

(defun c(o v)(abs(- o(/(reduce'+ v)(length v)))))


Try it online

Explanation:

(defun c(o v)
(abs (- o (/ (reduce '+ v) (length v)))))

• reduce applies an function over all list elements (+ in this case)
• rest is just the base function, abs(o - mean(v))

# Ruby, 31 bytes

->o,v{v.count(1-o)/v.size.to_f}


Try it online!

# Pyth, 4 bytes

aE.O


Explanation:

       ( implicitly set Q = eval(input()) )
a      Absolute difference between
E     eval(input()) (this is the second line of input taken)
.O   and the average of
Q  (implicit) Q (the first line of input)


Input is in the format of:

[0,1,1,0,1,1,1,0,1,1]
0


with the array of votes first, and the candidate second.

Try it online!