Last active
July 31, 2025 19:30
-
-
Save Rudxain/9628cf541f1ae72ada250e99e882347a to your computer and use it in GitHub Desktop.
Print shortened Hailstone-sequence of CLI arg
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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:]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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