use strict;
use warnings;
use List::Util qw/sum/;
use Data::Dumper;

my @data = (
    { A => 4, B => 5, C => 2, D => 4, F => 5 },
    { A => 2, C => 3, D => 4, E => 3 },
    { A => 1, B => 4, D => 5, E => 3, F => 4 },
    { B => 5, E => 2, F => 4 },
    { B => 3, C => 1, D => 3, F => 3 }
);

my @items = (qw/A B C D E F/);

my $ave = {};

for (0..$#data) {
    $ave->{$_} = sum(values %{ $data[$_] }) / $#data;
}

my $dev = {};

for my $i (0..$#items) {
    for my $j ($i+1..$#items) {
        my $item1 = $items[$i];
        my $item2 = $items[$j];

        my $r = 0.0;
        my $n = 0;

        for my $k (0..$#data) {
            my $user = $data[$k];

            if(defined $user->{$item1} and defined $user->{$item2}) {
                $r += $user->{$item2} - $user->{$item1};
                $n++;
            }
        }

        $r /= $n if $n > 0;

        $dev->{$item1}->{$item2} = [$r, $n];
        $dev->{$item2}->{$item1} = [-$r, $n];
    }
}

my $a;

for (0..$#data) {
    my $u = $data[$_];
    my @user;

    for my $item (@items) {
        push @user, $item unless defined $u->{$item};
    }

    for my $user (@user) {
        my $p;

        my $r1 = 0.0;
        my $r2 = 0.0;

        for my $key (keys %{ $u }) {
            my ($d, $n) = @{ $dev->{$key}->{$user} };
            $r1 += ($d + $u->{$key}) * $n;
            $r2 += $n;
        }

        $a->{$_}->{$user} = $r1 / $r2;
    }
}

print Dumper $a;