collatz_record.wat en WebAssembly
Corre cada cadena de Collatz bajo 100 y devuelve el récord: 97.
;; Collatz: which start below 100 takes the most steps to reach 1?
(module
;; Halve if even; 3n+1 if odd; count until the chain hits 1.
(func $steps (export "chain_length") (param $n i32) (result i32)
(local $count i32)
(block $done
(loop $next
(br_if $done (i32.eq (local.get $n) (i32.const 1)))
(if (i32.and (local.get $n) (i32.const 1))
(then
(local.set $n
(i32.add (i32.mul (local.get $n) (i32.const 3))
(i32.const 1))))
(else
(local.set $n
(i32.div_s (local.get $n) (i32.const 2)))))
(local.set $count (i32.add (local.get $count) (i32.const 1)))
(br $next)))
(local.get $count))
;; Race every start below the limit and remember the record holder.
(func $longest (export "longest_start") (param $limit i32)
(result i32)
(local $n i32)
(local $best_n i32)
(local $best i32)
(local $s i32)
(local.set $n (i32.const 1))
(block $done
(loop $scan
(br_if $done (i32.ge_s (local.get $n) (local.get $limit)))
(local.set $s (call $steps (local.get $n)))
(if (i32.gt_s (local.get $s) (local.get $best))
(then
(local.set $best (local.get $s))
(local.set $best_n (local.get $n))))
(local.set $n (i32.add (local.get $n) (i32.const 1)))
(br $scan)))
(local.get $best_n))
;; 97 holds the under-100 record at 118 steps.
(func (export "main") (result i32)
(call $longest (i32.const 100))))
Cómo funciona
$stepsdivide a la mitad o hace 3n+1 hasta llegar a 1, contando.i32.andcon 1 es la prueba de paridad que elige la rama.$longestprueba cada inicio y recuerda el mejor; 97 toma 118 pasos.
Palabras clave y builtins usados aquí
blockbrbr_ifcallelseexportfunci32iflocalloopmoduleparamresultthen
El intento, en números
- Líneas
- 43
- Caracteres a escribir
- 1278
- Tokens
- 293
- Ritmo de tres estrellas
- 60 tpm
Al ritmo de tres estrellas de 60 tokens por minuto, este intento toma unos 293 segundos.
Paso 2 de 3 en Bis; paso 27 de 28 en Fundamentos del lenguaje.