#!/usr/bin/perl use strict; use warnings; use List::Util qw( max min ); my $max = 19; #from OP my @aoa = map { [ ( 'o' ) x ($max + 1) ] } 0..$max; #from OP my %illu = illuminate( 0,0,12 ); display(@aoa); %illu = illuminate( 0,10,4 ); display(@aoa); %illu = illuminate( 10,10,6 ); display(@aoa); %illu = illuminate( 10,0,5.5 ); display(@aoa); sub illuminate{ my $center_r = shift; my $center_c = shift; my $radius = shift; my %ret; foreach my $row ( $center_r - $radius .. $center_r + $radius ){ my $delta_x = $radius ** 2 - ($center_r - $row) ** 2; if( $delta_x >= 0 ){ $delta_x = int sqrt $delta_x; my $low = max 0, $center_c - $delta_x; my $high = min $#{ $aoa[$row] }, $center_c + $delta_x; map { $ret{ $row.'_'.$_ }++ } $low .. $high; } } return %ret; } sub display{ print "\n"; foreach my $row ( 0..$#aoa ){ foreach my $col ( 0..$#{$aoa[$row]} ){ print $illu{$row.'_'.$col} ? ' ' : $aoa[$row][$col] ; } print "\n" } }