Skip to content

Instantly share code, notes, and snippets.

@Rudxain
Last active July 31, 2025 19:30
Show Gist options
  • Save Rudxain/9628cf541f1ae72ada250e99e882347a to your computer and use it in GitHub Desktop.
Save Rudxain/9628cf541f1ae72ada250e99e882347a to your computer and use it in GitHub Desktop.
Print shortened Hailstone-sequence of CLI arg
#!/usr/bin/env node
//@ts-check
import { argv } from 'node:process'
/**
Remove all base2 trailing zeroes.
More precisely,
it removes all least-significant unset bits
(digits of radix=2 numeral).
Equivalent to trial-division by 2.
@param n {bigint}
*/
const trim_tz = n => {
if (n == 0n)
return 0n
while ((n & 1n) == 0n)
n >>= 1n
return n
}
/**
https://en.wikipedia.org/wiki/Collatz_conjecture#Iterating_on_all_integers
*/
const CYCLES = Object.freeze(new Set(/**@type {const}*/([
0n, 1n, -1n, -5n, -17n
])))
let n = BigInt(argv[2])
n = trim_tz(n)
console.log(n)
// `as any` because TS is dumb
while (!CYCLES.has(/**@type {any}*/(n))) {
n = 3n * n + 1n
console.log(n)
n = trim_tz(n)
console.log(n)
}
#!/usr/bin/env lua
--- `HashSet` constructor
--- https://www.lua.org/pil/11.5.html
--- @generic T
--- @param list T[]
--- @return table<T, true> "Set"
function Set(list)
local set = {}
for _, l in ipairs(list) do
set[l] = true
end
return set
end
--- Remove all base2 trailing zeroes.
--- More precisely,
--- it removes all least-significant unset bits
--- (digits of radix=2 numeral).
--- Equivalent to trial-division by 2.
--- @param n integer
function trim_tz(n)
if n == 0 then return 0 end
while (n & 1) == 0 do
n = n >> 1
end
return n
end
--- https://en.wikipedia.org/wiki/Collatz_conjecture#Iterating_on_all_integers
CYCLE_SET = Set({
0, 1, -1, -5, -17
}) --[[@as table<0|1|-1|-5|-17, true>]]
local x = tonumber(arg[1])
--[[
`0` is truthy! no need to check!
This was unintuitive at 1st,
but considering the best-practices when handling `fail`
it makes sense
--]]
if not x then
error('Invalid decimal number')
end
if x % 1 ~= 0 then
error('Not an integer')
end
local n = trim_tz(x)
x = nil
print(n)
while not CYCLE_SET[n] do
-- WARN: this doesn't check overflows!
n = 3 * n + 1
print(n)
n = trim_tz(n)
print(n)
end
#!/usr/bin/env python3
from typing import Final
from sys import argv
def trim_tz(n: int):
'''
Remove all base2 trailing zeroes.
More precisely,
it removes all least-significant unset bits
(digits of radix=2 numeral).
Equivalent to trial-division by 2.
'''
if n == 0:
return 0
while (n & 1) == 0:
n >>= 1
return n
CYCLES: Final = {0, 1, -1, -5, -17}
'''
https://en.wikipedia.org/wiki/Collatz_conjecture#Iterating_on_all_integers
'''
def main(arg: list[str]):
n = int(arg[0])
n = trim_tz(n)
print(n)
while n not in CYCLES:
n = 3 * n + 1
print(n)
n = trim_tz(n)
print(n)
if __name__ == '__main__':
main(argv[1:])
use std::env::args;
/// Remove all base2 trailing zeroes.
/// More precisely,
/// it removes all least-significant unset bits
/// (digits of radix=2 numeral).
/// Equivalent to trial-division by 2.
#[must_use]
const fn trim_tz(mut n: i128) -> i128 {
if n == 0 {
return 0;
}
while (n & 1) == 0 {
n >>= 1;
}
n
}
fn main() {
let mut n: i128 = args().nth(1).unwrap().parse().unwrap();
n = trim_tz(n);
println!("{n}");
// https://en.wikipedia.org/wiki/Collatz_conjecture#Iterating_on_all_integers
// Here we let the compiler generate a jump-table,
// because `HashSet` is overkill for `const` stuff
while !matches!(n, 0 | 1 | -1 | -5 | -17) {
// WARN: this doesn't check overflows!
n = 3 * n + 1;
println!("{n}");
n = trim_tz(n);
println!("{n}");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment