github.com/NeowayLabs/nash@v0.2.2-0.20200127205349-a227041ffd50/testfiles/sieve.sh (about)

     1  #!/usr/bin/env nash
     2  
     3  # Sieve of Erathostenes
     4  
     5  fn lt(a, b) {
     6  	var _, st <= test $a -lt $b
     7  
     8  	return $st
     9  }
    10  
    11  fn gt(a, b) {
    12  	var _, st <= test $a -gt $b
    13  
    14  	return $st
    15  }
    16  
    17  fn le(a, b) {
    18  	var _, st <= test $a -le $b
    19  
    20  	return $st
    21  }
    22  
    23  fn sqrt(n) {
    24  	var v, _ <= expr $n * $n
    25  
    26  	return $v
    27  }
    28  
    29  fn range(start, end) {
    30  	var values, _ <= seq $start $end
    31  	var list <= split($values, "\n")
    32  
    33  	return $list
    34  }
    35  
    36  fn xrange(start, condfn) {
    37  	var out = ()
    38  
    39  	if $condfn($start) == "0" {
    40  		out = ($start)
    41  	} else {
    42  		return ()
    43  	}
    44  
    45  	var next = $start
    46  
    47  	for {
    48  		next, _ <= expr $next "+" 1
    49  
    50  		if $condfn($next) == "0" {
    51  			out <= append($out, $next)
    52  		} else {
    53  			return $out
    54  		}
    55  	}
    56  
    57  	unreachable
    58  }
    59  
    60  fn sieve(n) {
    61  	if lt($n, "2") == "0" {
    62  		return ()
    63  	}
    64  	if $n == "2" {
    65  		return ("2")
    66  	}
    67  
    68  	var tries = ("0" "0")
    69  
    70  	for i in range("2", $n) {
    71  		tries <= append($tries, "1")
    72  	}
    73  
    74  	fn untilSqrtRoot(v) {
    75  		return le(sqrt($v), $n)
    76  	}
    77  
    78  	for i in xrange("2", $untilSqrtRoot) {
    79  		if $tries[$i] == "1" {
    80  			for j in range("0", $n) {
    81  				# arithmetic seems cryptic without integers =(
    82  				var k, _ <= expr $i * $i "+" "(" $j * $i ")"
    83  
    84  				if gt($k, $n) != "0" {
    85  					tries[$k] = "0"
    86  				}
    87  			}
    88  		}
    89  	}
    90  
    91  	var primes = ()
    92  
    93  	for i in range("2", $n) {
    94  		if $tries[$i] == "1" {
    95  			primes <= append($primes, $i)
    96  		}
    97  	}
    98  
    99  	return $primes
   100  }
   101  
   102  for prime in sieve($ARGS[1]) {
   103  	print("%s ", $prime)
   104  }
   105  
   106  print("\n")