#!/usr/bin/perl use strict; my (@todo) = @ARGV; my ($each, @nums); my @tris = (0, 1); for $each (@todo) { maketriangles(\@tris, $each); @nums = findthree(\@tris, $each); print "$each = ", join(' + ', @tris[@nums]), "\n"; #print join(', ', @nums), "\n"; } #----------------------------------------------------------- sub maketriangles { my ($tris, $num) = @_; while ($tris->[-1] < $num) { push (@{$tris}, $tris->[-1] + ($tris->[-1] - $tris->[-2] + 1)); } } #----------------------------------------------------------- sub findthree { my ($tris, $num) = @_; my ($i, $j, $k, $start); $start = $i = $j = $k = largeless($tris, $num); while ($k > 0) { if ($num == $tris->[$i] + $tris->[$j] + $tris->[$k]) { return ($i, $j, $k); } $i--; if ($i < 0) { $i = $start; $j--; if ($j < 0) { $j = $start; $k--; } } } return (0, 0, 0); } #----------------------------------------------------------- sub largeless { my ($tris, $num) = @_; my $beg = 0; my $end = @{$tris}; my $mid = int(($beg + $end) / 2); while ($mid != $beg && $mid != $end) { if ($tris->[$mid] < $num) { $beg = $mid; } elsif ($tris->[$mid] > $num) { $end = $mid; } else { last; } $mid = int(($beg + $end) / 2); } return $mid; }