prime_sieve.wat en WebAssembly
La criba de Eratóstenes en memoria lineal: 25 primos hasta 100.
;; Sieve of Eratosthenes in one memory page: count the primes to 100.
(module
(memory 1)
;; Mark every composite: for each prime p, cross off p*p, p*p+p, ...
(func $sieve (param $limit i32)
(local $p i32)
(local $m i32)
(local.set $p (i32.const 2))
(block $done
(loop $next_p
(br_if $done
(i32.gt_s (i32.mul (local.get $p) (local.get $p))
(local.get $limit)))
(if (i32.eqz (i32.load8_u (local.get $p)))
(then
(local.set $m (i32.mul (local.get $p) (local.get $p)))
(block $marked
(loop $mark
(br_if $marked
(i32.gt_s (local.get $m) (local.get $limit)))
(i32.store8 (local.get $m) (i32.const 1))
(local.set $m (i32.add (local.get $m) (local.get $p)))
(br $mark)))))
(local.set $p (i32.add (local.get $p) (i32.const 1)))
(br $next_p))))
;; Anything still zero after the sieve is prime.
(func $count_primes (export "count_primes") (param $limit i32)
(result i32)
(local $n i32)
(local $count i32)
(call $sieve (local.get $limit))
(local.set $n (i32.const 2))
(block $done
(loop $scan
(br_if $done (i32.gt_s (local.get $n) (local.get $limit)))
(if (i32.eqz (i32.load8_u (local.get $n)))
(then
(local.set $count
(i32.add (local.get $count) (i32.const 1)))))
(local.set $n (i32.add (local.get $n) (i32.const 1)))
(br $scan)))
(local.get $count))
;; There are 25 primes at or below 100.
(func (export "main") (result i32)
(call $count_primes (i32.const 100))))
Cómo funciona
$sievetacha compuestos, cada primo avanzando desde p*p.- Pares block/loop anidados arman el for de dos niveles.
count_primesreescanea la memoria;mainresponde 25 para 100.
Palabras clave y builtins usados aquí
blockbrbr_ifcallexportfunci32iflocalloopmemorymoduleparamresultthen
El intento, en números
- Líneas
- 48
- Caracteres a escribir
- 1355
- Tokens
- 314
- Ritmo de tres estrellas
- 60 tpm
Al ritmo de tres estrellas de 60 tokens por minuto, este intento toma unos 314 segundos.
Paso 1 de 3 en Bis; paso 26 de 28 en Fundamentos del lenguaje.