use strict; my $hash = { AA => { AA => {}, AB => {}, AC => { AA => { AA => {}, }, }, }, }; add($hash); add($hash->{AB}); add($hash->{AB}->{AA}); print_me($hash); add($hash); add($hash->{AC}) for (0..5); add($hash->{AC}->{AC}); print_me($hash); remove($hash->{AC},'AC'); print_me($hash); remove($hash,'AB'); print_me($hash); sub add { my $ref = shift; my $new = (sort keys %$ref)[-1]; if ($new) { $ref->{++$new} = {}; } else { $ref->{'AA'} = {}; } } sub remove { my $ref = shift; my $sec = shift; delete $ref->{$sec}; for (sort keys %$ref) { # skip higher section next if ord(substr($_,1,1)) < ord(substr($sec,1,1)); my $new = substr($_,0,1) . chr(ord(substr($_,1,1))-1); my %new = %{$ref->{$_}}; $ref->{$new} = \%new; delete $ref->{$_}; } } sub print_me { my $ref = shift; my $ind = shift || ''; for (sort keys %$ref) { print "$ind$_\n"; print_me($ref->{$_},$ind."\t") if ref $ref->{$_}; } }