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) =
|
proc show(i: SomeInteger, bitlength = 16) =
|
||||||
@ -67,8 +67,7 @@ proc `[]=`(s: var ColorStack, i: uint8 | BackwardsIndex, c: Color) =
|
|||||||
|
|
||||||
|
|
||||||
iterator items(s: ColorStack): Color =
|
iterator items(s: ColorStack): Color =
|
||||||
# s.len is unsigned so it will wrap around if it's 0
|
# s.len is unsigned so it will wrap around if we do s.len - 1 in that case
|
||||||
# so we will no-op in that case
|
|
||||||
if s.len != 0:
|
if s.len != 0:
|
||||||
for i in countdown(s.len - 1, 0'u8):
|
for i in countdown(s.len - 1, 0'u8):
|
||||||
yield cast[Color]((s.data shr (i * 3)) and masks[1])
|
yield cast[Color]((s.data shr (i * 3)) and masks[1])
|
||||||
@ -81,6 +80,12 @@ iterator pairs(s: ColorStack): (int, Color) =
|
|||||||
inc count
|
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) =
|
proc moveSubstack(src, dst: var ColorStack, nToMove: uint8) =
|
||||||
# Moves a sub-stack from the top of src to the top of dst
|
# 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
|
# 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) =
|
proc swap(s: var ColorStack, i1, i2: uint8) =
|
||||||
# Swap the values at two indices in the stack
|
# Swap the values at two indices in the stack
|
||||||
# further explanation to follow
|
|
||||||
if i1 == i2: return
|
if i1 == i2: return
|
||||||
|
|
||||||
|
# i1 and i2 are unsigned, so we have to watch out for underflows
|
||||||
let diff = if i1 > i2:
|
let diff = if i1 > i2:
|
||||||
(i1 - i2) * 3
|
(i1 - i2) * 3
|
||||||
else:
|
else:
|
||||||
(i2 - i1) * 3
|
(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))
|
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
|
let masked = s.data and mask
|
||||||
masked.show
|
# shift by the distance between values in both directions, combine, then mask
|
||||||
let swapped = ((masked shl diff) and mask) or ((masked shr diff) and mask)
|
let swapped = ((masked shl diff) or (masked shr diff)) and mask
|
||||||
swapped.show
|
# finally, AND with the inverse of mask so that only the values being
|
||||||
s.data = (s.data and bitnot(mask)) or swapped
|
# swapped are erased, and combine that with the swapped values
|
||||||
s.data.show
|
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 =
|
proc `$`(s: ColorStack): string =
|
||||||
@ -137,11 +164,11 @@ proc `$`(s: ColorStack): string =
|
|||||||
|
|
||||||
|
|
||||||
var one: ColorStack
|
var one: ColorStack
|
||||||
|
one.add(cRed)
|
||||||
one.add(cGreen)
|
one.add(cGreen)
|
||||||
one.add(cBlue)
|
one.add(cBlue)
|
||||||
one.add(cYellow)
|
one.add(cYellow)
|
||||||
one.add(cPurple)
|
one.add(cPurple)
|
||||||
one.add(cRed)
|
|
||||||
|
|
||||||
var two: ColorStack
|
var two: ColorStack
|
||||||
# two.add(cPurple)
|
# two.add(cPurple)
|
||||||
@ -149,9 +176,9 @@ two.add(cRed)
|
|||||||
# two.add(cYellow)
|
# two.add(cYellow)
|
||||||
|
|
||||||
echo "one: ", one
|
echo "one: ", one
|
||||||
echo "two: ", two
|
# echo "two: ", two
|
||||||
|
|
||||||
one.swap(0, 4)
|
one.reverse(0, 4)
|
||||||
echo "one: ", one
|
echo "one: ", one
|
||||||
# one[^2] = cPurple
|
# one[^2] = cPurple
|
||||||
# echo "one: ", one
|
# echo "one: ", one
|
||||||
|
Loading…
x
Reference in New Issue
Block a user