use strict; use warnings; use List::Util qw/reduce/; map { print } join "\n", "Distribution of grades by letter:", map { sprintf( "\t%s: %s student%s", @$_, $_ -> [1] == 1 ? '' : 's' ) } map { my $c = $_ ; sort { $a -> [0] cmp $b -> [0] } map { [ $_, $c->{$_} ] } keys %$c } reduce { $a->{chr(ord($b->[1]))}++; $a } {}, map { printf( "List of students with failing grades:\n\t%s\n", join ', ' , map { $_->[0] } grep {ord $_->[1] >68} @$_); @$_} reduce {push(@$a, $b); $a} [], map { printf( "${^A}'s grade: %s\n" , $_ -> [1] ) if $_->[0] eq $^A; $_ } map { $^A="Zsófia"; [split(/\s+/)] } <STDIN>