An opposite to .succ! Or, a predecessor method for String.
This little thing is for my own use, and entertainment.
There are those that might recoil from by beginners drivel, but I
need a little help…
I keep getting ‘out of range’ error no matter what I try
when “a”.pred!
class String
def pred!
begin
get the ascii value of the last element in string and decrement it…
self[self.size - 1] = (self[self.size - 1] - 1)
if self[self.size - 1] == 96 # 'a' is the last char we want
self.chop! # when 'a'.pred! .chop char
self[self.size - 1] = 122 # set new last element to 'z'
end
return self
end while self.size > 0 # hmmmm...
end
end
“abcd”.my_pred_alpha
=> “abcc”
“abcd”.my_succ_alpha
=> “abce”
“z”.my_succ_alpha
=> “00”
“00”.my_pred_alpha
=> “z”
batsman@tux-chan:/tmp$ ruby /tmp/yy.rb
Loaded suite /tmp/yy
Started
…
Finished in 1.525721 seconds.
5 tests, 20011 assertions, 0 failures, 0 errors
class String
ALPHA = [(‘0’…‘9’), (‘A’…‘Z’), (‘a’…‘z’)].
inject(){|a,b| a + b.to_a}.map{|x| x[0]}
def my_succ_alpha
vals = self.unpack("C*")
carry = (vals.size-1).downto(0) do |idx|
if (i = ALPHA.index(vals[idx])) < ALPHA.size - 1
vals[idx] = ALPHA[i+1]
break false
else
vals[idx] = ALPHA[0]
end
end
vals.unshift(ALPHA[0]) if carry
vals.pack("C*")
end
def my_pred_alpha # breaks for "0"
vals = self.unpack("C*")
carry = (vals.size-1).downto(0) do |idx|
if (i = ALPHA.index(vals[idx])) > 0
vals[idx] = ALPHA[i-1]
break false
else
vals[idx] = ALPHA[-1]
end
end
vals.shift if carry
vals.pack("C*")
end
def my_succ # just operating on byte values
vals = self.unpack("C*")
carry = (vals.size-1).downto(0) do |idx|
if vals[idx] < 255
vals[idx] += 1
break false
else
vals[idx] = 0
end
end
vals.unshift(0) if carry
vals.pack("C*")
end
def my_pred # 'reverse' of my_succ
vals = self.unpack("C*")
carry = (vals.size-1).downto(0) do |idx|
if vals[idx] > 0
vals[idx] -= 1
break false
else
vals[idx] = 255
end
end
vals.shift if carry
vals.pack("C*")
end
end
require ‘test/unit’
class TC_my_succ < Test::Unit::TestCase
def arr_succ(a)
a.pack(“C*”).my_succ.unpack(“C*”)
end
def arr_pred(a)
a.pack("C*").my_pred.unpack("C*")
end
def test_rand
5000.times do
txt = (0..rand(20)).map{rand(255)}.pack("C*")
assert_equal(txt, txt.my_succ.my_pred)
assert_equal(txt, txt.my_pred.my_succ)
end
end
def test_rand_alpha
5000.times do
txt = (0..rand(20)).inject("") do |a,b|
a << String::ALPHA[rand(String::ALPHA.size)]
end
next if txt == "0" # my_pred_alpha is undefined
assert_equal(txt, txt.my_succ_alpha.my_pred_alpha)
assert_equal(txt, txt.my_pred_alpha.my_succ_alpha)
end
end
def test_my_pred_alpha
assert_equal("aa", "ab".my_pred_alpha)
assert_equal("aZ", "aa".my_pred_alpha)
assert_equal("z", "00".my_pred_alpha)
assert_equal("0", "1".my_pred_alpha)
assert_equal("00", "01".my_pred_alpha)
assert_equal("9", "A".my_pred_alpha)
end
def test_my_succ
assert_equal("ab", "aa".my_succ)
assert_equal("a:", "a9".my_succ)
assert_equal([0, 0], arr_succ([255]))
assert_equal([?b, 0], arr_succ([?a, 255]))
end
def test_my_pred
assert_equal("aa", "ab".my_pred)
assert_equal("a9", "a:".my_pred)
assert_equal([0, 255], arr_pred([1,0]))
assert_equal([255], arr_pred([0,0]))
assert_equal([?a, 255], arr_pred([?b, 0]))
end
end
···
On Fri, Mar 05, 2004 at 06:09:43PM +0900, illocutionist wrote:
–
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com
*** PUBLIC flooding detected from erikyyy
THAT’s an erik, pholx…
– Seen on #LinuxGER