12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Lehmer.mli *)typet=intletm=2147483647(* 2^31 - 1, a prime *)leta=16807(* 7^5 *)letq=m/a(* 127773 *)letr=mmoda(* 2836 *)letof_int(n:int):t=lets=abs(nmodm)inifs=0then1elses(* MurmurHash3's fmix32, on Int32 (wrapping at 2^32 natively and in a
* browser alike) *)letfmix32(h:int32):int32=letxorshiftkh=Int32.logxorh(Int32.shift_right_logicalhk)inh|>xorshift16|>Int32.mul0x85ebca6bl|>xorshift13|>Int32.mul0xc2b2ae35l|>xorshift16letscramble(n:int):t=(* the low 31 bits of the hash, a non-negative int on both platforms *)of_int(Int32.to_int(Int32.logand(fmix32(Int32.of_intn))0x7fffffffl))letnext(s:t):t=lett=(a*(smodq))-(r*(s/q))inift>0thentelset+mletto_unit(s:t):float=float_of_int(s-1)/.float_of_int(m-1)typestate=trefletmake(seed:int):state=ref(scrambleseed)letdraw(st:state):float=st:=next!st;to_unit!stletint(st:state)(n:int):int=min(n-1)(int_of_float(drawst*.float_of_intn))letfloat(st:state)(x:float):float=drawst*.x