10
\$\begingroup\$

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

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

22 Answers 22

6
\$\begingroup\$

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.

\$\endgroup\$
10
\$\begingroup\$

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.

\$\endgroup\$
  • 2
    \$\begingroup\$ Also works for arbitrary voting representations, neat. \$\endgroup\$ – CriminallyVulgar Jun 20 at 7:54
6
\$\begingroup\$

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.
\$\endgroup\$
  • 4
    \$\begingroup\$ you can do it in 5. hint: ⌹ \$\endgroup\$ – ngn Jun 21 at 8:53
4
\$\begingroup\$

Actually, 3 bytes

♀^æ

Try it online!

Explanation:

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

05AB1E, 3 bytes

ÅAα

Try it online!

\$\endgroup\$
  • 2
    \$\begingroup\$ I'm 30 seconds too late.. My order was different though, first α then ÅA ;p \$\endgroup\$ – Kevin Cruijssen Jun 19 at 13:32
  • 2
    \$\begingroup\$ @KevinCruijssen I watched your solution come in in real-time, I started to comment, and it was deleted, all within about 30 seconds. Hilarious! \$\endgroup\$ – connectyourcharger Jun 19 at 13:33
  • \$\begingroup\$ @KevinCruijssen I don't really understand how the two orders work the same... :-) My 05AB1E knowledge is not very good \$\endgroup\$ – Luis Mendo Jun 19 at 13:34
  • 1
    \$\begingroup\$ @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 \$\endgroup\$ – Luis Mendo Jun 19 at 14:23
  • 2
    \$\begingroup\$ @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. \$\endgroup\$ – Kevin Cruijssen Jun 19 at 16:48
3
\$\begingroup\$

Octave, 16 bytes

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

Try it online!

\$\endgroup\$
2
\$\begingroup\$

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.

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

JavaScript, 38 bytes

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

Try it

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

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

\$\endgroup\$
  • \$\begingroup\$ @Rod I was trying to figure out how to optimize for the 1/0 input restriction but failed. Thanks! \$\endgroup\$ – HyperNeutrino Jun 19 at 14:38
1
\$\begingroup\$

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.

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

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

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

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.

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

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

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

Try it online!

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

K (Kona), 17 bytes

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

Try it online!

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

Elm 0.19, 48 bytes

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

Online demo here.

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

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

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

Japt v2.0a0, 6 bytes

aVx÷Vl

Try it

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

JavaScript (Node.js), 47 42 bytes

-5 bytes from @arnauld

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

Try it online!

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

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`
\$\endgroup\$
0
\$\begingroup\$

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))
\$\endgroup\$
0
\$\begingroup\$

Ruby, 31 bytes

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

Try it online!

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

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!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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