#!/usr/bin/env perl -l use strict; use warnings; use Data::Dump; my @parent = ( { Europe => [ qw{ London Moscow } ] }, { Asia => [ qw{ Tokyo Seoul } ] }, { Africa => [ qw{ Cairo Algiers } ] }, ); my @current; reset_current(\@parent, \@current); print '*** Starting State ***'; print_current_state(\@current); print '*** Asia Down ***'; failover(Asia => \@current); print_current_state(\@current); print '*** Reset State ***'; reset_current(\@parent, \@current); print_current_state(\@current); print '*** Europe Down ***'; failover(Europe => \@current); print_current_state(\@current); print '*** Asia Down ***'; failover(Asia => \@current); print_current_state(\@current); sub failover { my ($down, $current) = @_; my @cities_to_failover = map { (keys %$_)[0] eq $down ? @{$_->{$down}} : () } @$current; for (@$current) { my ($continent) = keys %$_; next unless @{$_->{$continent}}; if ($continent eq $down) { @{$_->{$continent}} = (); } else { push @{$_->{$continent}}, shift @cities_to_failover; } } } sub print_current_state { my ($current) = @_; dd $current; } sub reset_current { my ($parent, $current) = @_; @$current = (); for (@$parent) { my ($continent) = keys %$_; push @$current, { $continent => [ @{$_->{$continent}} ] }; } } #### *** Starting State *** [ { Europe => ["London", "Moscow"] }, { Asia => ["Tokyo", "Seoul"] }, { Africa => ["Cairo", "Algiers"] }, ] *** Asia Down *** [ { Europe => ["London", "Moscow", "Tokyo"] }, { Asia => [] }, { Africa => ["Cairo", "Algiers", "Seoul"] }, ] *** Reset State *** [ { Europe => ["London", "Moscow"] }, { Asia => ["Tokyo", "Seoul"] }, { Africa => ["Cairo", "Algiers"] }, ] *** Europe Down *** [ { Europe => [] }, { Asia => ["Tokyo", "Seoul", "London"] }, { Africa => ["Cairo", "Algiers", "Moscow"] }, ] *** Asia Down *** [ { Europe => [] }, { Asia => [] }, { Africa => ["Cairo", "Algiers", "Moscow", "Tokyo"] }, ]