Skip to content

Instantly share code, notes, and snippets.

@lfnoise
Last active January 17, 2022 05:42
Show Gist options
  • Save lfnoise/a34d96ed02dbb176f4a55cd973a9cf2a to your computer and use it in GitHub Desktop.
Save lfnoise/a34d96ed02dbb176f4a55cd973a9cf2a to your computer and use it in GitHub Desktop.
[fixed version] my second day of trying out Nim.
import system
import math
type
VArray[T] = ref object of RootObj
len : int
VSeries[T] = ref object of VArray[T]
start, step: T
VGeo[T] = ref object of VArray[T]
start, step: T
VConst[T] = ref object of VArray[T]
val : T
VCat[T] = ref object of VArray[T]
all: seq[(int, VArray[T])]
VRand[T] = ref object of VArray[T]
seed: uint64
m, b: T
const
kHashStart = 0x9E3779B97F4A7C15'u64
kTwoToTheMinus64:float64 = pow(2.0, -64.0)
proc hashToFloat64(hash: uint64):float64 =
result = float64(hash) * kTwoToTheMinus64
proc hash64(x: uint64):uint64 =
var z = x
z = (z xor (z shr 30)) * 0xBF58476D1CE4E5B9'u64
z = (z xor (z shr 27)) * 0x94D049BB133111EB'u64
result = z xor (z shr 31)
proc iwrap[T](x:T, a:T):T =
let c = x mod a
result = if c<0: c+a else: c
proc vseries[T](len: int, start, step: T):VSeries[T] =
result = VSeries[float](len:len, start:start, step:step)
proc vgeo[T](len: int, start, step: T):VSeries[T] =
result = VGeo[float](len:len, start:start, step:step)
proc arc4random(): cint {.importc: "arc4random", header: "<stdlib.h>", nodecl.}
proc vrand[T](len: int, lo, hi: T, seed:uint64 = 0):VRand[T] =
var s:uint64
if seed == 0 :
s = hash64(uint64(arc4random())) +
hash64(uint64(arc4random()))
else:
s = hash64(seed + kHashStart)
result = VRand[T](len:len, seed:s, m:hi-lo, b:lo)
proc vcat[T](args: varargs[VArray[T]]):VCat[T] =
var sumLen = 0
var all = newSeq[(int,VArray[T])]()
for arg in args :
sumLen += arg.len
all.add((sumLen,arg))
result = VCat[T](len:sumLen, all:all)
proc vconst[T](len:int, val:T):VConst[T] =
result = VConst[T](len:len, val:val)
method `[]` [T](a: VArray[T], i: int):T {. base .} =
quit "override me!"
method `[]` [T](a: VSeries[T], i: int):T =
result = a.start + a.step * T(iwrap(i, a.len))
method `[]` [T](a: VGeo[T], i: int):T =
result = a.start * pow(a.step, T(iwrap(i, a.len)))
method `[]` [T](a: VConst[T], i: int):T =
result = a.val
method `[]` [T](a: VRand[T], i: int):T =
let x = hashToFloat64(hash64(uint64(iwrap(i, a.len)) + a.seed))
result = a.m * x + a.b
method `[]` [T](a: VCat[T], i: int):T =
let i = iwrap(i, a.len);
var base = 0;
for j in 0..a.all.len :
let sizeToHere = a.all[j][0]
if i < sizeToHere :
return a.all[j][1][i-base]
base = sizeToHere
quit "VCat: went past end. Your children have mutated?"
var c = vcat( vseries(5, 0.0, 1.5),
vrand(8, 7.0, 10.0),
vconst(3,11.0))
for i in -20..20 :
echo i, " ", c[i]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment