class ZhangSuen(str, black="1") { const NEIGHBOURS = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]] # 8 neighbors const CIRCULARS = (NEIGHBOURS + [NEIGHBOURS.first]) # P2, ... P9, P2 has r = 0 has image = [[]] method init { var s1 = str.lines.map{|line| line.chars.map{|c| c==black ? 1 : 0 }} var s2 = s1.len.of { s1[0].len.of(0) } var xr = range(1, s1.end-1) var yr = range(1, s1[0].end-1) do { r = 0 xr.each{|x| yr.each{|y| s2[x][y] = (s1[x][y] - self.zs(s1,x,y,1)) }} # Step 1 xr.each{|x| yr.each{|y| s1[x][y] = (s2[x][y] - self.zs(s2,x,y,0)) }} # Step 2 } while !r.is_zero image = s1 } method zs(ng,x,y,g) { (ng[x][y] == 0) -> || (ng[x-1][y] + ng[x][y+1] + ng[x+g][y+g - 1] == 3) -> || (ng[x+g - 1][y+g] + ng[x+1][y] + ng[x][y-1] == 3) -> && return 0 var bp1 = NEIGHBOURS.map {|p| ng[x+p[0]][y+p[1]] }.sum # B(P1) return 0 if ((bp1 < 2) || (6 < bp1)) var ap1 = 0 CIRCULARS.map {|p| ng[x+p[0]][y+p[1]] }.each_cons(2, {|a,b| ++ap1 if (a < b) # A(P1) }) return 0 if (ap1 != 1) r = 1 } method display { image.each{|row| say row.map{|col| col ? '#' : ' ' }.join } } } var text = <