use strict; use warnings; use Data::Dump::Streamer; use constant ORDER => 3; my %chains; while () { my @words = split; my @chain; for (@words) { push @chain, $_; next if @chain < ORDER; shift @chain if @chain > ORDER; my $root; for my $index (0 .. ORDER - 1) { if (defined $root) { ++$root->[1]{$chain[$index]}[0]; $root = $root->[1]{$chain[$index]}; } else { ++$chains{$chain[$index]}[0]; $root = $chains{$chain[$index]}; } } } } Dump (\%chains); __DATA__ I will not eat them in a bar. I will not eat them in a car. I will not eat them Sam I am. I will not eat green eggs and ham!