Neustadtl score

7

1

Write the shortest function that takes a two-dimensional square array representing the scores of a chess round, and outputs an array of the Neustadtl scores of the players.

The two-dimensional array is structured so that array[i][j] is the score earned by the player i against player j.

The Neustadtl score is used to tie-break in chess tournaments when their conventional scores tie. The Neustadtl score is calculated by adding the scores of the player defeated and half of the scores the player drew with.

Here is an example data for a 5 on 5 match.

               cs  ns
1. X 1 ½ 1 0 | 2½  4.25
2. 0 X 1 ½ 0 | 1½  2.5
3. ½ 0 X ½ ½ | 1½  3.5  
4. 0 ½ ½ X 1 | 2   4
5. 1 1 ½ 0 X | 2½  4.75

where cs stands for conventional score and ns stands for Neustadtl score.

For example, the Neustadtl score of the 4th player is:

  0(player 1's cs) + ½(player 2's cs) + ½(player 3's cs) + 1(player 5's cs)
= 0(2½) + ½(1½) + ½(1½) + 1(2½)
= 4

For more details and another example data, see its Wikipedia article.

Some notes:

  1. Assume the diagonal is always zero (array[j, j] = 0)
  2. No need to check if the array is square
  3. No need to check if the data makes sense (a valid scoretable has the property array[i, j] + array[j, i] = 1, i != j)

Ming-Tang

Posted 2013-03-22T02:44:22.313

Reputation: 5 383

Answers

7

Mathematica 11 10 8

#.Tr/@#&

(Thanks @chyanog!) Usage

m = {{0,  1, .5, 1, 0}, {0, 0, 1, .5, 0}, {.5, 0, 0, .5, .5}, 
     {0, .5, .5, 0, 1}, {1, 1, .5, 0, 0}}

#.Tr/@#&[m]

Result {4.25, 2.5, 3.5, 4., 4.75}

Edit

Some explanations:

Tr is "Trace". When applied to a one-dimensional list returns the elements sum
/@ is "Map". Feeds the preceding operator with one element at a time and returns a list
. is "dot product". Multiplies vectors (or matrices and vectors)
the set # ... & is a functional construct. The &feeds the #with its arguments

Dr. belisarius

Posted 2013-03-22T02:44:22.313

Reputation: 5 345

How about Tr? – chyanog – 2013-03-24T07:45:12.317

@chyanog Hey! Yesss – Dr. belisarius – 2013-03-24T07:52:10.020

7

APL 31 29 24 or 10 or 7

If you will accept decimal input and output then the following takes your score array as screen input via ←⊃⎕ with each row of the array enclosed in parentheses.

((m,'|'),+/m),m+.×+/m←⊃⎕

Your example would look as follows:

Input: 

(0 1 0.5 1 0)(0 0 1 0.5 0)(0.5 0 0 0.5 0.5)(0 0.5 0.5 0 1)(1 1 0.5 0 0)

Output:

0.0 1.0 0.5 1.0 0.0 | 2.5 4.25
0.0 0.0 1.0 0.5 0.0 | 1.5 2.50
0.5 0.0 0.0 0.5 0.5 | 1.5 3.50
0.0 0.5 0.5 0.0 1.0 | 2.0 4.00
1.0 1.0 0.5 0.0 0.0 | 2.5 4.75

with the input displayed along with the separator and the two scores as the output. Or if you just want the Neustadtl score then:

m+.×+/m←⊃⎕

If the input scores array exists as a global m then:

m←⊃(0 1 0.5 1 0)(0 0 1 0.5 0)(0.5 0 0 0.5 0.5)(0 0.5 0.5 0 1)(1 1 0.5 0 0)

m+.×+/m

4.25 2.5 3.5 4 4.75

Latest mods prompted by marinus. Thanks.

Graham

Posted 2013-03-22T02:44:22.313

Reputation: 3 184

1What APL are you using? Doesn't only read one line? How can ⍎⍞ get you a matrix? Also, isn't ⍎⍞ the same as ? – marinus – 2013-03-24T04:03:21.257

@marinus APL+WIN v5. Yes or a variable. By entering your matrix as, for example, 2 2⍴⍳4. Yes you are right. Another senior moment!!! – Graham – 2013-03-24T09:41:05.177

@marinus Another useful alternative for matrix entry is to use ⊃⎕ and enter each row enclosed in parentheses. In this case: (0 1 0.5 1 0)(0 0 1 0.5 0)(0.5 0 0 0.5 0.5)(0 0.5 0.5 0 1)(1 1 0.5 0 0) – Graham – 2013-03-24T09:47:41.310

4

K,13

{+/'x*\:+/'x}

.

k)input:(0 1 0.5 1 0;0 0 1 0.5 0;0.5 0 0 0.5 0.5;0 0.5 0.5 0 1;1 1 0.5 0 0)
k)input
0   1   0.5 1   0  
0   0   1   0.5 0  
0.5 0   0   0.5 0.5
0   0.5 0.5 0   1  
1   1   0.5 0   0  
k){+/'x*\:+/'x}[input]
4.25 2.5 3.5 4 4.75

It's unclear whether you just want a 1-d array of Neustadtl scores or if you want the output that's in your example. If it's the latter then:

K, 23

{x!,:'b,'+/'x*\:b:+/'x}

.

k){x!,:'b,'+/'x*\:b:+/'x}[input]
0   1   0.5 1   0  | 2.5 4.25
0   0   1   0.5 0  | 1.5 2.5 
0.5 0   0   0.5 0.5| 1.5 3.5 
0   0.5 0.5 0   1  | 2 4     
1   1   0.5 0   0  | 2.5 4.75

tmartin

Posted 2013-03-22T02:44:22.313

Reputation: 3 917

3

R - 25

function(x)x%*%rowSums(x)

R> input <- matrix(c(0,  1, .5,  1,  0,
                     0,  0,  1, .5,  0,
                    .5,  0,  0, .5, .5,
                     0, .5, .5,  0,  1,
                     1,  1, .5,  0,  0), nrow=5, byrow=TRUE)

R> (function(x)x%*%rowSums(x))(input)
     [,1]
[1,] 4.25
[2,] 2.50
[3,] 3.50
[4,] 4.00
[5,] 4.75

flodel

Posted 2013-03-22T02:44:22.313

Reputation: 2 345

2

C# 106 (88 function body + 18 required using stetement)

float[]N(float[][]s){return s.Select(l=>l.Select((v,i)=>v*s[i].Sum()).Sum()).ToArray();}

This function requires the using System.Linq; directive to be present in the file, so I added that to the character count as well.

IdeOne link: http://ideone.com/cPcfwg

OK, I know it's not very short, but I love C# and LINQ so much that I just had to do it. :)

Here's a more readable version of the code:

public float[] Neustadl(float[][] scoreTable)
{
    return scoreTable.Select(scoreLine => 
                        scoreLine.Select((lineValue, otherPlayerIndex) => 
                            lineValue * scoreTable[otherPlayerIndex].Sum())
                        .Sum()
                    ).ToArray();
}

Cristian Lupascu

Posted 2013-03-22T02:44:22.313

Reputation: 8 369

0

Ruby, 62

N=->a{a.map{|l|z=0
l.zip(a.map{|l|eval l*?+}){|k,s|z+=k*s}
z}}

Lowjacker

Posted 2013-03-22T02:44:22.313

Reputation: 4 466