Skip to content

Instantly share code, notes, and snippets.

@raven29
Created June 11, 2012 07:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raven29/2908925 to your computer and use it in GitHub Desktop.
Save raven29/2908925 to your computer and use it in GitHub Desktop.
Skip finder corrected
class File
attr_reader :pos_start_line, :eol_length
def set_eol_length
rewind
str = gets
@eol_length = self.pos - str.length + 1
rewind
end
def seek_line(pos)
if pos < 1
seek(0)
@pos_start_line = 0
return gets
else
seek(pos-1)
end
begin
if self.pos == 0
@pos_start_line = 0
return gets
end
c = getc_reverse
end while c != $/
seek(2, IO::SEEK_CUR)
@pos_start_line = self.pos
return gets
end
def getc_reverse
c = getbyte.chr
if self.pos > 1
seek(-2, IO::SEEK_CUR)
else
seek(0)
end
return c
end
end
def check_range_pos(pos_start, pos_end, f, skipped)
s1 = f.seek_line(pos_start)
pos1 = f.pos
n1 = s1.to_i
l1 = s1.length - 1
s2 = f.seek_line(pos_end)
pos2 = f.pos_start_line-1
n2 = s2.to_i
l2 = s2.length - 1
if pos1 < pos2+1
npos = pos_count(n1, l1, n2, l2, f.eol_length)
if npos == pos2 - pos1 + 1 + l1 + l2 + 2*f.eol_length
return
else
pos_medial = (pos1 + pos2) / 2
check_range_pos(pos_start, pos_medial, f, skipped)
check_range_pos(pos_medial, pos_end, f, skipped)
end
elsif pos1 == pos2+1
(n1+1).upto(n2-1) {|i| skipped << i}
return
else pos1 > pos2+1
return
end
end
def check_range_num(pos_start, pos_end, f, skipped)
s1 = f.seek_line(pos_start)
pos1 = f.pos
n1 = s1.to_i
l1 = s1.length - 1
s2 = f.seek_line(pos_end)
pos2 = f.pos_start_line-1
n2 = s2.to_i
l2 = s2.length - 1
if pos1 < pos2+1
npos = pos_count(n1, l1, n2, l2, f.eol_length)
if npos == pos2 - pos1 + 1 + l1 + l2 + 2*f.eol_length
return
else
n_medial = (n1 + n2) / 2
mpos = pos_count(n1+1, (n1+1).to_s.length, n_medial, n_medial.to_s.length, f.eol_length)
pos_medial = pos_start + mpos
check_range_num(pos_start, pos_medial, f, skipped)
check_range_num(pos_medial, pos_end, f, skipped)
end
elsif pos1 == pos2+1
(n1+1).upto(n2-1) {|i| skipped << i}
return
else pos1 > pos2+1
return
end
end
def pos_count(n1, l1, n2, l2, leol)
if l1 == l2
res = (n2 - n1 + 1) * (l1 + leol)
else
res = (10**l1 - n1) * (l1 + leol) + (n2 - 10**(l2-1) + 1) * (l2 + leol)
(l1 + 1).upto(l2 - 1){|m| res = res + (10**m - 10**(m-1)) * (m + leol)}
end
return res
end
fn = 'data.txt'
f = File.open(fn)
f.set_eol_length
first_num = f.gets.to_i
a = []
1.upto(first_num-1){|i| a << i}
ts1 = Time.now.to_f
check_range_pos(0, f.size-1, f, a)
ts2 = Time.now.to_f
puts "\"5/8\" type (byte) partition: "
p a
puts (ts2 - ts1).to_s + "s"
puts "--------------"
a = []
ts3 = Time.now.to_f
check_range_num(0, f.size-1, f, a)
ts4 = Time.now.to_f
f.close
puts "\"1/2\" type (number) partition: "
p a
puts (ts4 - ts3).to_s + "s"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment