#!/usr/bin/env perl

# Eratosthenes' screen, returns prime numbers smaller than given positive
# integer.

use strict;
use warnings;
use Set::IntSpan;

print "Enter a natural number greater than 1: ";
chomp(my $n = <STDIN>);

my $set = screen($n);

print "Prime numbers smaller or equal than $n are: $set\n";

sub screen {
  my $n = shift;
  my $underflow = "There are no primes smaller or equal to $n";

  return $underflow if($n < 2);

  my $s = [ 2..$n ];
  $s = new Set::IntSpan $s;
  my $a = new Set::IntSpan;
  my $b;
  
  my $r = 1;
  do {
    $b = $s->min();
    $a = $a->union([ $b ]);
    my $m = $b;
    
    do {
      $s->remove($m);
      $m = $m + $b;
      $r++;
    } until ($m > $n);
  } until ($b > sqrt($n));
  
  $a = $a->union($s);
      
  return $a;
}