more procs for working on faststacks
This commit is contained in:
parent
cd81150e6c
commit
8d889170df
@ -1,4 +1,4 @@
|
||||
import bitops, strutils
|
||||
import bitops, strutils, random
|
||||
|
||||
|
||||
proc show(i: SomeInteger, bitlength = 16) =
|
||||
@ -67,8 +67,7 @@ proc `[]=`(s: var ColorStack, i: uint8 | BackwardsIndex, c: Color) =
|
||||
|
||||
|
||||
iterator items(s: ColorStack): Color =
|
||||
# s.len is unsigned so it will wrap around if it's 0
|
||||
# so we will no-op in that case
|
||||
# s.len is unsigned so it will wrap around if we do s.len - 1 in that case
|
||||
if s.len != 0:
|
||||
for i in countdown(s.len - 1, 0'u8):
|
||||
yield cast[Color]((s.data shr (i * 3)) and masks[1])
|
||||
@ -81,6 +80,12 @@ iterator pairs(s: ColorStack): (int, Color) =
|
||||
inc count
|
||||
|
||||
|
||||
proc find(s: ColorStack, needle: Color): uint8 =
|
||||
for i in 0'u8 .. s.high:
|
||||
if s[i] == needle:
|
||||
return i
|
||||
|
||||
|
||||
proc moveSubstack(src, dst: var ColorStack, nToMove: uint8) =
|
||||
# Moves a sub-stack from the top of src to the top of dst
|
||||
# shift the dst stack by the length of the substack to make room
|
||||
@ -109,22 +114,44 @@ proc moveSubstackPre(src, dst: var ColorStack, nToMove: uint8) =
|
||||
|
||||
proc swap(s: var ColorStack, i1, i2: uint8) =
|
||||
# Swap the values at two indices in the stack
|
||||
# further explanation to follow
|
||||
if i1 == i2: return
|
||||
|
||||
# i1 and i2 are unsigned, so we have to watch out for underflows
|
||||
let diff = if i1 > i2:
|
||||
(i1 - i2) * 3
|
||||
else:
|
||||
(i2 - i1) * 3
|
||||
|
||||
# take masks[1] from above (rightmost position) and shift to position of i1.
|
||||
# then do the same for i2, and OR them together.
|
||||
let mask = (masks[1] shl s.offset(i1)) or (masks[1] shl s.offset(i2))
|
||||
mask.show
|
||||
# get rid of everything but the two values we're swapping
|
||||
let masked = s.data and mask
|
||||
masked.show
|
||||
let swapped = ((masked shl diff) and mask) or ((masked shr diff) and mask)
|
||||
swapped.show
|
||||
s.data = (s.data and bitnot(mask)) or swapped
|
||||
s.data.show
|
||||
# shift by the distance between values in both directions, combine, then mask
|
||||
let swapped = ((masked shl diff) or (masked shr diff)) and mask
|
||||
# finally, AND with the inverse of mask so that only the values being
|
||||
# swapped are erased, and combine that with the swapped values
|
||||
s.data = (s.data and mask.bitnot) or swapped
|
||||
|
||||
|
||||
proc shuffle(r: var Rand, s: var ColorStack) =
|
||||
# Fisher-Yates shuffle
|
||||
for i in countdown(s.high, 1'u8):
|
||||
let j = cast[uint8](r.rand(i))
|
||||
if j != i:
|
||||
s.swap(i, j)
|
||||
|
||||
|
||||
proc reverse(s: var ColorStack, first, last: uint8) =
|
||||
var x = first
|
||||
var y = last
|
||||
while x < y:
|
||||
s.swap(x, y)
|
||||
inc x
|
||||
dec y
|
||||
|
||||
|
||||
proc asInt(s: ColorStack): uint16 = s.data
|
||||
|
||||
|
||||
proc `$`(s: ColorStack): string =
|
||||
@ -137,11 +164,11 @@ proc `$`(s: ColorStack): string =
|
||||
|
||||
|
||||
var one: ColorStack
|
||||
one.add(cRed)
|
||||
one.add(cGreen)
|
||||
one.add(cBlue)
|
||||
one.add(cYellow)
|
||||
one.add(cPurple)
|
||||
one.add(cRed)
|
||||
|
||||
var two: ColorStack
|
||||
# two.add(cPurple)
|
||||
@ -149,9 +176,9 @@ two.add(cRed)
|
||||
# two.add(cYellow)
|
||||
|
||||
echo "one: ", one
|
||||
echo "two: ", two
|
||||
# echo "two: ", two
|
||||
|
||||
one.swap(0, 4)
|
||||
one.reverse(0, 4)
|
||||
echo "one: ", one
|
||||
# one[^2] = cPurple
|
||||
# echo "one: ", one
|
||||
|
Loading…
x
Reference in New Issue
Block a user