Zhang-Suen thinning algorithm: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Perl}}: quiet the warnings about 'uninitialized' variables)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(3 intermediate revisions by 2 users not shown)
Line 646:
# ####
</pre>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">' version 08-10-2016
' compile with: fbc -s console
 
Data "00000000000000000000000000000000"
Data "01111111110000000111111110000000"
Data "01110001111000001111001111000000"
Data "01110000111000001110000111000000"
Data "01110001111000001110000000000000"
Data "01111111110000001110000000000000"
Data "01110111100000001110000111000000"
Data "01110011110011101111001111011100"
Data "01110001111011100111111110011100"
Data "00000000000000000000000000000000"
Data "END"
 
' ------=< MAIN >=------
 
Dim As UInteger x, y, m, n
Dim As String input_str
 
Do ' find out how big it is
Read input_str
If input_str = "END" Then Exit Do
If x < Len(input_str) Then x = Len(input_str)
y = y + 1
Loop
 
m = x -1 : n = y -1
ReDim As UByte old(m, n), new_(m, n)
 
y = 0
Restore ' restore data pointer
Do ' put data in array
Read input_str
If input_str="END" Then Exit Do
For x = 0 To Len(input_str) -1
old(x,y) = input_str[x] - Asc("0")
' print image
If old(x, y) = 0 Then Print "."; Else Print "#";
Next
Print
y = y + 1
Loop
 
'corners and sides do not change
For x = 0 To m
new_(x, 0) = old(x, 0)
new_(x, n) = old(x, n)
Next
 
For y = 0 To n
new_(0, y) = old(0, y)
new_(m, y) = old(m, y)
Next
 
Dim As UInteger tmp, change, stage = 1
Do
change = 0
For y = 1 To n -1
For x = 1 To m -1
' -1-
If old(x,y) = 0 Then ' first condition, p1 must be black
new_(x,y) = 0
Continue For
End If
' -2-
tmp = old(x, y -1) + old(x +1, y -1)
tmp = tmp + old(x +1, y) + old(x +1, y +1) + old(x, y +1)
tmp = tmp + old(x -1, y +1) + old(x -1, y) + old(x -1, y -1)
If tmp < 2 OrElse tmp > 6 Then ' 2 <= B(p1) <= 6
new_(x, y) = 1
Continue For
End If
' -3-
tmp = 0
If old(x , y ) = 0 And old(x , y -1) = 1 Then tmp += 1 ' p1 > p2
If old(x , y -1) = 0 And old(x +1, y -1) = 1 Then tmp += 1 ' p2 > p3
If old(x +1, y -1) = 0 And old(x +1, y ) = 1 Then tmp += 1 ' p3 > p4
If old(x +1, y ) = 0 And old(x +1, y +1) = 1 Then tmp += 1 ' p4 > p5
If old(x +1, y +1) = 0 And old(x , y +1) = 1 Then tmp += 1 ' p5 > p6
If old(x , y +1) = 0 And old(x -1, y +1) = 1 Then tmp += 1 ' p6 > p7
If old(x -1, y +1) = 0 And old(x -1, y ) = 1 Then tmp += 1 ' p7 > p8
If old(x -1, y ) = 0 And old(x -1, y -1) = 1 Then tmp += 1 ' p8 > p9
If old(x -1, y -1) = 0 And old(x , y -1) = 1 Then tmp += 1 ' p9 > p2
' tmp = 1 ==> A(P1) = 1
If tmp <> 1 Then
new_(x, y) = 1
Continue For
End If
If (stage And 1) = 1 Then
' step 1 -4- -5-
If (old(x, y -1) + old(x +1, y) + old(x, y +1)) = 3 OrElse _
(old(x +1, y) + old(x, y +1) + old(x -1, y)) = 3 Then
new_(x, y) = 1
Continue For
End If
Else
' step 2 -4- -5-
If (old(x, y -1) + old(x +1, y) + old(x -1, y)) = 3 OrElse _
(old(x, y -1) + old(x, y +1) + old(x -1, y)) = 3 Then
new_(x, y) = 1
Continue For
End If
End If
' all condition are met, make p1 white (0)
new_(x, y) = 0
change = 1 ' flag change
Next
Next
 
' copy new_() into old()
For y = 0 To n
For x = 0 To m
old(x, y) = new_(x, y)
Next
Next
 
stage += 1
Loop Until change = 0 ' stop when there are no changes made
 
Print ' print result
Print "End result"
For y = 0 To n
For x = 0 To m
If old(x, y) = 0 Then Print "."; Else Print "#";
Next
Print
Next
 
 
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>................................
.#########.......########.......
.###...####.....####..####......
.###....###.....###....###......
.###...####.....###.............
.#########......###.............
.###.####.......###....###......
.###..####..###.####..####.###..
.###...####.###..########..###..
................................
 
End result
................................
..#######.........######........
..#.....#........##.............
..#......#.......#..............
..#.....#........#..............
..#####.#........#..............
.......##........#..............
........#....#...##....##...#...
.........#.........####.........
................................</pre>
 
==={{header|VBA}}===
{{trans|Phix}}
<syntaxhighlight lang="vb">Public n As Variant
Private Sub init()
n = [{-1,0;-1,1;0,1;1,1;1,0;1,-1;0,-1;-1,-1;-1,0}]
End Sub
 
Private Function AB(text As Variant, y As Integer, x As Integer, step As Integer) As Variant
Dim wtb As Integer
Dim bn As Integer
Dim prev As String: prev = "#"
Dim next_ As String
Dim p2468 As String
For i = 1 To UBound(n)
next_ = Mid(text(y + n(i, 1)), x + n(i, 2), 1)
wtb = wtb - (prev = "." And next_ <= "#")
bn = bn - (i > 1 And next_ <= "#")
If (i And 1) = 0 Then p2468 = p2468 & prev
prev = next_
Next i
If step = 2 Then '-- make it p6842
p2468 = Mid(p2468, 3, 2) & Mid(p2468, 1, 2)
'p2468 = p2468(3..4)&p2468(1..2)
End If
Dim ret(2) As Variant
ret(0) = wtb
ret(1) = bn
ret(2) = p2468
AB = ret
End Function
Private Sub Zhang_Suen(text As Variant)
Dim wtb As Integer
Dim bn As Integer
Dim changed As Boolean, changes As Boolean
Dim p2468 As String '-- (p6842 for step 2)
Dim x As Integer, y As Integer, step As Integer
Do While True
changed = False
For step = 1 To 2
changes = False
For y = 1 To UBound(text) - 1
For x = 2 To Len(text(y)) - 1
If Mid(text(y), x, 1) = "#" Then
ret = AB(text, y, x, step)
wtb = ret(0)
bn = ret(1)
p2468 = ret(2)
If wtb = 1 _
And bn >= 2 And bn <= 6 _
And InStr(1, Mid(p2468, 1, 3), ".") _
And InStr(1, Mid(p2468, 2, 3), ".") Then
changes = True
text(y) = Left(text(y), x - 1) & "!" & Right(text(y), Len(text(y)) - x)
End If
End If
Next x
Next y
If changes Then
For y = 1 To UBound(text) - 1
text(y) = Replace(text(y), "!", ".")
Next y
changed = True
End If
Next step
If Not changed Then Exit Do
Loop
Debug.Print Join(text, vbCrLf)
End Sub
 
Public Sub main()
init
Dim Small_rc(9) As String
Small_rc(0) = "................................"
Small_rc(1) = ".#########.......########......."
Small_rc(2) = ".###...####.....####..####......"
Small_rc(3) = ".###....###.....###....###......"
Small_rc(4) = ".###...####.....###............."
Small_rc(5) = ".#########......###............."
Small_rc(6) = ".###.####.......###....###......"
Small_rc(7) = ".###..####..###.####..####.###.."
Small_rc(8) = ".###...####.###..########..###.."
Small_rc(9) = "................................"
Zhang_Suen (Small_rc)
End Sub</syntaxhighlight>{{out}}
<pre>................................
...######.........######........
...#....#.........#....##.......
...#....#.........#......#......
...#....#.........#.............
...####.#.........#.............
.......##.........#.............
........#....#....#....##...#...
.........#....#....####......#..
................................</pre>
 
=={{header|C}}==
Line 1,427 ⟶ 1,684:
 
=={{header|Elena}}==
ELENA 56.0x :
{{trans|Java}}
<syntaxhighlight lang="elena">import system'collections;
Line 1,454 ⟶ 1,711:
" "};
 
static int[][] nbrs = new int[][]
{
new int[]{0, -1}, new int[]{1, -1}, new int[]{1, 0}, new int[]{1, 1}, new int[]{0, 1},
Line 1,460 ⟶ 1,717:
};
 
static int[][][] nbrGroups = new int[][][]
{
new int[][]{new int[]{0, 2, 4}, new int[]{2, 4, 6}},
Line 1,493 ⟶ 1,750:
int count := 0;
for (int i := 0,; i < nbrs.Length, - 1; i += 1)
{
if (self[r + nbrs[i][1]][c + nbrs[i + 1][0]] == $35)
{ count += 1 }
};
Line 1,506 ⟶ 1,763:
int count := 0;
for (int i := 0,; i < nbrs.Length, - 1; i += 1)
{
if (self[r + nbrs[i][1]][c + nbrs[i][0]] == $32)
Line 1,524 ⟶ 1,781:
int count := 0;
var group := nbrGroups[step];
for(int i := 0,; i < 3,2; i += 1)
{
for(int j := 0,; j < group[i].Length,; j += 1)
{
var nbr := nbrs[group[i][j]];
if (self[r + nbr[1]][c + nbr[0]] == $32)
{ count := count + 1; ^ true$break; };
^ false
}
};
Line 1,551 ⟶ 1,806:
firstStep := firstStep.Inverted;
for(int r := 1,; r < self.Rows, - 1; r += 1)
{
for(int c := 1,; c < self.Columns, - 1; c += 1)
{
if(self.proceed(r,c,toWhite,firstStep))
Line 1,560 ⟶ 1,815:
};
toWhite.forEach::(p){ self[p.y][p.x] := $32 };
toWhite.clear()
}
Line 1,569 ⟶ 1,824:
var it := self.enumerator();
it.forEach::(ch){ console.print(ch," ") };
while (it.next())
{
console.writeLine();
 
it.forEach::(ch){ console.print(ch," ") }
}
}
Line 1,601 ⟶ 1,856:
# # # # # # # # # # # # # # # # # # # #
# # # # # # # # #
# # # #
# # #
# # #
# # # # #
# # # # # # # # # # # #
# # # # # # # # # # # # #
# # #
# # #
# # #
# # #
# # #
# # # # # # # # # # # # #
# # # # # #
Line 1,917 ⟶ 2,172:
................................
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' version 08-10-2016
' compile with: fbc -s console
 
Data "00000000000000000000000000000000"
Data "01111111110000000111111110000000"
Data "01110001111000001111001111000000"
Data "01110000111000001110000111000000"
Data "01110001111000001110000000000000"
Data "01111111110000001110000000000000"
Data "01110111100000001110000111000000"
Data "01110011110011101111001111011100"
Data "01110001111011100111111110011100"
Data "00000000000000000000000000000000"
Data "END"
 
' ------=< MAIN >=------
 
Dim As UInteger x, y, m, n
Dim As String input_str
 
Do ' find out how big it is
Read input_str
If input_str = "END" Then Exit Do
If x < Len(input_str) Then x = Len(input_str)
y = y + 1
Loop
 
m = x -1 : n = y -1
ReDim As UByte old(m, n), new_(m, n)
 
y = 0
Restore ' restore data pointer
Do ' put data in array
Read input_str
If input_str="END" Then Exit Do
For x = 0 To Len(input_str) -1
old(x,y) = input_str[x] - Asc("0")
' print image
If old(x, y) = 0 Then Print "."; Else Print "#";
Next
Print
y = y + 1
Loop
 
'corners and sides do not change
For x = 0 To m
new_(x, 0) = old(x, 0)
new_(x, n) = old(x, n)
Next
 
For y = 0 To n
new_(0, y) = old(0, y)
new_(m, y) = old(m, y)
Next
 
Dim As UInteger tmp, change, stage = 1
Do
change = 0
For y = 1 To n -1
For x = 1 To m -1
' -1-
If old(x,y) = 0 Then ' first condition, p1 must be black
new_(x,y) = 0
Continue For
End If
' -2-
tmp = old(x, y -1) + old(x +1, y -1)
tmp = tmp + old(x +1, y) + old(x +1, y +1) + old(x, y +1)
tmp = tmp + old(x -1, y +1) + old(x -1, y) + old(x -1, y -1)
If tmp < 2 OrElse tmp > 6 Then ' 2 <= B(p1) <= 6
new_(x, y) = 1
Continue For
End If
' -3-
tmp = 0
If old(x , y ) = 0 And old(x , y -1) = 1 Then tmp += 1 ' p1 > p2
If old(x , y -1) = 0 And old(x +1, y -1) = 1 Then tmp += 1 ' p2 > p3
If old(x +1, y -1) = 0 And old(x +1, y ) = 1 Then tmp += 1 ' p3 > p4
If old(x +1, y ) = 0 And old(x +1, y +1) = 1 Then tmp += 1 ' p4 > p5
If old(x +1, y +1) = 0 And old(x , y +1) = 1 Then tmp += 1 ' p5 > p6
If old(x , y +1) = 0 And old(x -1, y +1) = 1 Then tmp += 1 ' p6 > p7
If old(x -1, y +1) = 0 And old(x -1, y ) = 1 Then tmp += 1 ' p7 > p8
If old(x -1, y ) = 0 And old(x -1, y -1) = 1 Then tmp += 1 ' p8 > p9
If old(x -1, y -1) = 0 And old(x , y -1) = 1 Then tmp += 1 ' p9 > p2
' tmp = 1 ==> A(P1) = 1
If tmp <> 1 Then
new_(x, y) = 1
Continue For
End If
If (stage And 1) = 1 Then
' step 1 -4- -5-
If (old(x, y -1) + old(x +1, y) + old(x, y +1)) = 3 OrElse _
(old(x +1, y) + old(x, y +1) + old(x -1, y)) = 3 Then
new_(x, y) = 1
Continue For
End If
Else
' step 2 -4- -5-
If (old(x, y -1) + old(x +1, y) + old(x -1, y)) = 3 OrElse _
(old(x, y -1) + old(x, y +1) + old(x -1, y)) = 3 Then
new_(x, y) = 1
Continue For
End If
End If
' all condition are met, make p1 white (0)
new_(x, y) = 0
change = 1 ' flag change
Next
Next
 
' copy new_() into old()
For y = 0 To n
For x = 0 To m
old(x, y) = new_(x, y)
Next
Next
 
stage += 1
Loop Until change = 0 ' stop when there are no changes made
 
Print ' print result
Print "End result"
For y = 0 To n
For x = 0 To m
If old(x, y) = 0 Then Print "."; Else Print "#";
Next
Print
Next
 
 
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>................................
.#########.......########.......
.###...####.....####..####......
.###....###.....###....###......
.###...####.....###.............
.#########......###.............
.###.####.......###....###......
.###..####..###.####..####.###..
.###...####.###..########..###..
................................
 
End result
................................
..#######.........######........
..#.....#........##.............
..#......#.......#..............
..#.....#........#..............
..#####.#........#..............
.......##........#..............
........#....#...##....##...#...
.........#.........####.........
................................</pre>
 
=={{header|Go}}==
Line 4,954 ⟶ 5,049:
................................
</pre>
 
=={{header|VBA}}==
{{trans|Phix}}
<syntaxhighlight lang="vb">Public n As Variant
Private Sub init()
n = [{-1,0;-1,1;0,1;1,1;1,0;1,-1;0,-1;-1,-1;-1,0}]
End Sub
 
Private Function AB(text As Variant, y As Integer, x As Integer, step As Integer) As Variant
Dim wtb As Integer
Dim bn As Integer
Dim prev As String: prev = "#"
Dim next_ As String
Dim p2468 As String
For i = 1 To UBound(n)
next_ = Mid(text(y + n(i, 1)), x + n(i, 2), 1)
wtb = wtb - (prev = "." And next_ <= "#")
bn = bn - (i > 1 And next_ <= "#")
If (i And 1) = 0 Then p2468 = p2468 & prev
prev = next_
Next i
If step = 2 Then '-- make it p6842
p2468 = Mid(p2468, 3, 2) & Mid(p2468, 1, 2)
'p2468 = p2468(3..4)&p2468(1..2)
End If
Dim ret(2) As Variant
ret(0) = wtb
ret(1) = bn
ret(2) = p2468
AB = ret
End Function
Private Sub Zhang_Suen(text As Variant)
Dim wtb As Integer
Dim bn As Integer
Dim changed As Boolean, changes As Boolean
Dim p2468 As String '-- (p6842 for step 2)
Dim x As Integer, y As Integer, step As Integer
Do While True
changed = False
For step = 1 To 2
changes = False
For y = 1 To UBound(text) - 1
For x = 2 To Len(text(y)) - 1
If Mid(text(y), x, 1) = "#" Then
ret = AB(text, y, x, step)
wtb = ret(0)
bn = ret(1)
p2468 = ret(2)
If wtb = 1 _
And bn >= 2 And bn <= 6 _
And InStr(1, Mid(p2468, 1, 3), ".") _
And InStr(1, Mid(p2468, 2, 3), ".") Then
changes = True
text(y) = Left(text(y), x - 1) & "!" & Right(text(y), Len(text(y)) - x)
End If
End If
Next x
Next y
If changes Then
For y = 1 To UBound(text) - 1
text(y) = Replace(text(y), "!", ".")
Next y
changed = True
End If
Next step
If Not changed Then Exit Do
Loop
Debug.Print Join(text, vbCrLf)
End Sub
 
Public Sub main()
init
Dim Small_rc(9) As String
Small_rc(0) = "................................"
Small_rc(1) = ".#########.......########......."
Small_rc(2) = ".###...####.....####..####......"
Small_rc(3) = ".###....###.....###....###......"
Small_rc(4) = ".###...####.....###............."
Small_rc(5) = ".#########......###............."
Small_rc(6) = ".###.####.......###....###......"
Small_rc(7) = ".###..####..###.####..####.###.."
Small_rc(8) = ".###...####.###..########..###.."
Small_rc(9) = "................................"
Zhang_Suen (Small_rc)
End Sub</syntaxhighlight>{{out}}
<pre>................................
...######.........######........
...#....#.........#....##.......
...#....#.........#......#......
...#....#.........#.............
...####.#.........#.............
.......##.........#.............
........#....#....#....##...#...
.........#....#....####......#..
................................</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="ecmascriptwren">class Point {
construct new(x, y) {
_x = x
9,486

edits