@@ -15,19 +15,67 @@ local function diff_u(fn1,fn2)
1515 local function li (fn ,o ,l )f ,e = io.open (fn ," rb" )if not f then return nil ,e end f :seek (S ,o )local g = f :read (l )f :close ()return g end
1616 b1 ,e ,b2 = li (fn1 ,o1 ,l1 )if not b1 then error (e )end b2 ,e = li (fn2 ,o2 ,l2 )if not b2 then error (e )end return b1 == b2 end
1717 h ,w ,la ,m =# f1 // ps ,# f2 // ps ,1 ,{}
18- for x = 1 , h do
19- for y = la , w do
20- if cmp ( x , y ) then
21- if # m > 0 and m [ # m ]. x + m [ # m ]. l == x and m [ # m ]. y + m [ # m ]. l == y then
22- m [ # m ]. l = m [ # m ]. l + 1
23- else
24- table.insert ( m ,{ y = y , x = x , l = 1 })
18+ local function build ( a1 , a2 , alo , ahi , blo , bhi )
19+ if alo > ahi or blo > bhi then return end
20+ if alo == ahi then
21+ for j = blo , bhi do
22+ if cmp ( alo , j ) then
23+ m [ # m + 1 ] = { x = alo , y = j , l = 1 }
24+ break
2525 end
26- la = y
27- break
2826 end
27+ return
2928 end
30- end la = nil
29+ local mid = (alo + ahi )// 2
30+ -- forward DP from alo..mid
31+ local F = {}
32+ for j = blo , bhi do F [j ]= 0 end
33+ for i = alo , mid do
34+ local prev = 0
35+ for j = blo , bhi do
36+ local save = F [j ]
37+ if cmp (i ,j ) then F [j ] = prev + 1
38+ elseif F [j - 1 ] and F [j - 1 ] > F [j ] then F [j ] = F [j - 1 ] end
39+ prev = save
40+ end
41+ end
42+ -- backward DP from ahi..mid+1
43+ local B = {}
44+ for j = blo , bhi do B [j ]= 0 end
45+ for i = ahi , mid + 1 , - 1 do
46+ local prev = 0
47+ for j = bhi , blo , - 1 do
48+ local save = B [j ]
49+ if cmp (i ,j ) then B [j ] = prev + 1
50+ elseif B [j + 1 ] and B [j + 1 ] > B [j ] then B [j ] = B [j + 1 ] end
51+ prev = save
52+ end
53+ end
54+ -- find best split on the B-axis
55+ local best ,jcut = - 1 ,blo
56+ for j = blo ,bhi do
57+ local s = (F [j ] or 0 ) + (B [j ] or 0 )
58+ if s > best then best ,s ,jcut = s ,s ,j end
59+ end
60+ -- recurse on the two halves
61+ build (a1 ,a2 ,alo , mid , blo , jcut )
62+ build (a1 ,a2 ,mid + 1 ,ahi , jcut + 1 , bhi )
63+ end
64+
65+ build (fn1 ,fn2 , 1 , h , 1 , w )
66+
67+ local co = {}
68+ for _ ,p in ipairs (m ) do
69+ local t = co [# co ]
70+ if t and t .x + t .l == p .x and t .y + t .l == p .y then
71+ t .l = t .l + 1
72+ else
73+ co [# co + 1 ] = { x = p .x , y = p .y , l = 1 }
74+ end
75+ end
76+ m = co
77+ la = nil
78+
3179 local function get (fn ,p ,x )local l ,_ ,o ,f ,r = string.unpack (PF ,p ,(x - 1 )* ps + 1 )f = assert (io.open (fn ," rb" ))f :seek (S ,o )r = f :read (l )f :close ()return r end
3280 local function pfl (p ,s )return (p .. s :gsub (' \n $' ,' ' ):gsub (' \r $' ,' ' ))end
3381 local function flush ()if # u .l > 0 then if u .e >= 4 then table.remove (u .l )u .o .l ,u .n .l = u .o .l - 1 ,u .n .l - 1 end
0 commit comments