Find the C-factor of a vote

10

1

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

connectyourcharger

Posted 2019-06-19T13:17:33.527

Reputation: 2 056

Isn't mean(v) equal to 0.7 in your example? – HyperNeutrino – 2019-06-19T13:22:31.817

@HyperNeutrino Yes. What's the issue? – connectyourcharger – 2019-06-19T13:23:25.240

How is abs(0 - 0.7) equal to 0.3? – HyperNeutrino – 2019-06-19T13:23:40.863

Ah. Fixed the example. I reversed the two numbers – connectyourcharger – 2019-06-19T13:24:39.340

Oh okay. Thanks for clarifying! – HyperNeutrino – 2019-06-19T13:24:51.880

Can one's program output a fraction? – LegionMammal978 – 2019-06-24T20:47:31.710

Answers

6

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.

HyperNeutrino

Posted 2019-06-19T13:17:33.527

Reputation: 26 575

10

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.

Robin Ryder

Posted 2019-06-19T13:17:33.527

Reputation: 6 625

2Also works for arbitrary voting representations, neat. – CriminallyVulgar – 2019-06-20T07:54:11.547

6

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.

J. Sallé

Posted 2019-06-19T13:17:33.527

Reputation: 3 233

4you can do it in 5. hint: ⌹ – ngn – 2019-06-21T08:53:02.017

4

Actually, 3 bytes

♀^æ

Try it online!

Explanation:

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

Mego

Posted 2019-06-19T13:17:33.527

Reputation: 32 998

3

05AB1E, 3 bytes

ÅAα

Try it online!

Luis Mendo

Posted 2019-06-19T13:17:33.527

Reputation: 87 464

2I'm 30 seconds too late.. My order was different though, first α then ÅA ;p – Kevin Cruijssen – 2019-06-19T13:32:54.323

2@KevinCruijssen I watched your solution come in in real-time, I started to comment, and it was deleted, all within about 30 seconds. Hilarious! – connectyourcharger – 2019-06-19T13:33:28.710

@KevinCruijssen I don't really understand how the two orders work the same... :-) My 05AB1E knowledge is not very good – Luis Mendo – 2019-06-19T13:34:38.557

@LuisMendo Well, whether we first calculate the mean of the list and then the absolute difference of this list with the second input, or first the absolute difference between each value in the list with the second input, and then calculate the mean of that updated list, it'll results in the same output. As long as the list is the first input, either order of the builtins is fine. I think the same applies to Jelly if the list is the first argument tbh. – Kevin Cruijssen – 2019-06-19T13:42:46.690

1

@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

– Luis Mendo – 2019-06-19T14:23:34.390

2@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. – Kevin Cruijssen – 2019-06-19T16:48:57.913

3

Octave, 16 bytes

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

Try it online!

Expired Data

Posted 2019-06-19T13:17:33.527

Reputation: 3 129

2

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.

Conor O'Brien

Posted 2019-06-19T13:17:33.527

Reputation: 36 228

1

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

HyperNeutrino

Posted 2019-06-19T13:17:33.527

Reputation: 26 575

@Rod I was trying to figure out how to optimize for the 1/0 input restriction but failed. Thanks! – HyperNeutrino – 2019-06-19T14:38:33.047

1

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

HyperNeutrino

Posted 2019-06-19T13:17:33.527

Reputation: 26 575

You can use n instead of _...A to save 1 (Try it online!).

– Mr. Xcoder – 2019-06-19T18:45:19.987

@Mr.Xcoder Ooh nice. Yeah I realized the != trick after making this lol. Thanks! – HyperNeutrino – 2019-06-19T19:15:13.210

1

JavaScript, 38 bytes

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

Try it

Shaggy

Posted 2019-06-19T13:17:33.527

Reputation: 24 623

1

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.

Sean

Posted 2019-06-19T13:17:33.527

Reputation: 4 136

1

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.

Neil

Posted 2019-06-19T13:17:33.527

Reputation: 95 035

1

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

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

Try it online!

Xcali

Posted 2019-06-19T13:17:33.527

Reputation: 7 671

1

K (Kona), 17 bytes

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

Try it online!

Galen Ivanov

Posted 2019-06-19T13:17:33.527

Reputation: 13 815

1

Elm 0.19, 48 bytes

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

Online demo here.

O.O.Balance

Posted 2019-06-19T13:17:33.527

Reputation: 1 499

1

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

pizzapants184

Posted 2019-06-19T13:17:33.527

Reputation: 3 174

0

JavaScript (Node.js), 47 42 bytes

-5 bytes from @arnauld

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

Try it online!

Luis felipe De jesus Munoz

Posted 2019-06-19T13:17:33.527

Reputation: 9 639

0

Japt v2.0a0, 6 bytes

aVx÷Vl

Try it

Shaggy

Posted 2019-06-19T13:17:33.527

Reputation: 24 623

0

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`

Kevin Cruijssen

Posted 2019-06-19T13:17:33.527

Reputation: 67 575

0

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

David Horák

Posted 2019-06-19T13:17:33.527

Reputation: 121

0

Ruby, 31 bytes

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

Try it online!

GorbitGames

Posted 2019-06-19T13:17:33.527

Reputation: 1

0

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!

RK.

Posted 2019-06-19T13:17:33.527

Reputation: 497