#!/usr/bin/perl use warnings; use strict; use Text::Table; # Where the ranges start for C and H: my @c_start = qw/1 3 6 11/; my @h_start = qw/1 11 21 31/; my @file = ; my @multiply = split " ", $file[1]; shift @multiply; # Discard "amount:" my $i = 0; my %result; for my $ch (grep @$_, # Ignore "num:" and whitespace map [/C([0-9]+)H([0-9]+)/], split ' ', $file[0]) { my ($c, $h) = @$ch; $result{find_range($c, @c_start)} {find_range($h, @h_start)} += $multiply[$i]; $i++; } # Table header. my $table = Text::Table->new( '*', map join('-', ranges($_, @c_start)), 0 .. $#c_start - 1); # Table rows. for my $i (0 .. $#h_start-1) { $table->add(join ('-', ranges($i, @h_start)), map { $result{$_}{$i} // 0 } 0 .. @c_start); } print $table; sub ranges { my ($idx, @arr) = @_; return ($arr[$idx], $arr[$idx + 1] - 1); } sub find_range { my ($value, @ranges) = @_; my $range_start = 0; $range_start++ while $ranges[$range_start + 1] <= $value; return $range_start; } __DATA__ num: C1H10 C5H30 C3H5 C2H8 amount: 1 5 6 9