11
\$\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 '19 at 13:22
  • \$\begingroup\$ @HyperNeutrino Yes. What's the issue? \$\endgroup\$ – connectyourcharger Jun 19 '19 at 13:23
  • \$\begingroup\$ How is abs(0 - 0.7) equal to 0.3? \$\endgroup\$ – HyperNeutrino Jun 19 '19 at 13:23
  • \$\begingroup\$ Ah. Fixed the example. I reversed the two numbers \$\endgroup\$ – connectyourcharger Jun 19 '19 at 13:24
  • \$\begingroup\$ Oh okay. Thanks for clarifying! \$\endgroup\$ – HyperNeutrino Jun 19 '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.

| improve this answer | |
\$\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.

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ Also works for arbitrary voting representations, neat. \$\endgroup\$ – CriminallyVulgar Jun 20 '19 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.
| improve this answer | |
\$\endgroup\$
  • 4
    \$\begingroup\$ you can do it in 5. hint: ⌹ \$\endgroup\$ – ngn Jun 21 '19 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
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 3 bytes

ÅAα

Try it online!

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ I'm 30 seconds too late.. My order was different though, first α then ÅA ;p \$\endgroup\$ – Kevin Cruijssen Jun 19 '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 '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 '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 '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 '19 at 16:48
3
\$\begingroup\$

Octave, 16 bytes

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

Try it online!

| improve this answer | |
\$\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.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 38 bytes

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

Try it

| improve this answer | |
\$\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

| improve this answer | |
\$\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 '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.

| improve this answer | |
\$\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

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ You can use n instead of _...A to save 1 (Try it online!). \$\endgroup\$ – Mr. Xcoder Jun 19 '19 at 18:45
  • \$\begingroup\$ @Mr.Xcoder Ooh nice. Yeah I realized the != trick after making this lol. Thanks! \$\endgroup\$ – HyperNeutrino Jun 19 '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.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

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

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

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

K (Kona), 17 bytes

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

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Elm 0.19, 48 bytes

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

Online demo here.

| improve this answer | |
\$\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).

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Japt v2.0a0, 6 bytes

aVx÷Vl

Try it

| improve this answer | |
\$\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!

| improve this answer | |
\$\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`
| improve this answer | |
\$\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))
| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

Ruby, 31 bytes

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

Try it online!

| improve this answer | |
\$\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!

| improve this answer | |
\$\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.