/** Counting the Pieces of Fruit Socrates said to some secondary school students that excellent work is correct because it is interesting to the students. This is done by being interested in people from the area of study, and how they can provide a use to society. David counted the number of pieces of fruit. He saved his life by eating each piece of fruit. David stood on the step-ladder, to pick the apple. He ate the apple. He dried his mouth with a napkin. The algorithm regioncounter1/4 counts the number of non-touching pieces of each type of fruit, in the horizontal and vertical directions. Note "r" stands for red, and "b" stands for blue. regioncounter1([[0, 0, ''], [1, 0, ''], [2, 0, r], [0, 1, ''], [1, 1, r], [2, 1, b], [0, 2, r], [1, 2, ''], [2, 2, b]], 2, 2, Counts). Counts = [[b, 1], [r, 3]] ; regioncounter1(+Area, +MaxX, +MaxY, -Counts) (+ means input, - means output) Area - The area in which to count the different coloured regions. The area is a list of items with pixels' x-coordinate, y-coordinate and colour. MaxX - The maximum X coordinate of the area. MaxY - The maximum Y coordinate of the area. Counts - A list of letters standing for the colour, and each of their counts. **/ regioncounter1(Area, MaxX, MaxY, Counts1) :- regioncounter2(Area, MaxX, MaxY, [], Counts2), delete(Counts2, ['', _], Counts1). /** regioncounter2(+Items, +MaxX, +MaxY, +Counts1, -Counts2) Items - The items in the area which haven't been counted as part of a region. MaxX - The maximum X coordinate of the area. MaxY - The maximum Y coordinate of the area. Counts1 - The colours and their counts. Counts2 - The colours and their counts to return. **/ regioncounter2([], _, _, Counts, Counts). regioncounter2(Items1, MaxX, MaxY, Counts1, Counts2) :- Items1 = [Item | _], Item = [X, Y, Colour], increment(Colour, Counts1, Counts3), test1(X, Y, Colour, MaxX, MaxY, Items1, Items3), regioncounter2(Items3, MaxX, MaxY, Counts3, Counts2). /** test1(+X, +Y, +Colour, +MaxX, +MaxY, +Items1, -Items2) X - The x-coordinate of the item to test is part of a region. Y - The y-coordinate of the item to test is part of a region. Colour - The colour that the item should be, i.e. the colour of the initial item taken from the list of Items in regioncounter2/5. MaxX - The maximum X coordinate of the area. MaxY - The maximum Y coordinate of the area. Items1 - The list of items which will be tested are part of a region. Items2 - The list of items which will be tested are part of a region, to return. **/ test1(X1, Y1, Colour, MaxX, MaxY, Items, Items) :- not(test2(X1, Y1, Colour, MaxX, MaxY, Items, _)). test1(X1, Y1, Colour, MaxX, MaxY, Items1, Items2) :- test2(X1, Y1, Colour, MaxX, MaxY, Items1, Items3), test3(X1, Y1, Colour, MaxX, MaxY, Items3, Items2). /** test2(+X, +Y, +Colour, +MaxX, +MaxY, +Items1, -Items2) X - The x-coordinate of the item to test is within the minimum and maximum coordinates and is of a certain colour. Y - The y-coordinate of the item to test is within the minimum and maximum coordinates and is of a certain colour. Colour - The colour that the item should be, i.e. the colour of the initial item taken from the list of Items in regioncounter2/5. MaxX - The maximum X coordinate of the area. MaxY - The maximum Y coordinate of the area. Items1 - The list of items which the current item is tested to be a member of and deleted from. Items2 - The list of items which the current item is tested to be a member of and deleted from, to return. **/ test2(X1,Y1, Colour, MaxX, MaxY, Items1, Items2) :- 0 =< X1, X1 =< MaxX, 0 =< Y1, Y1 =< MaxY, Item = [X1, Y1, Colour], member(Item, Items1), delete(Items1, Item, Items2). /** test3(+X, +Y, +Colour, +MaxX, +MaxY, +Items1, -Items2) X - The x-coordinate of the item to increment and decrement to test neighbouring pixels. Y - The y-coordinate of the item to increment and decrement to test neighbouring pixels. Colour - The colour that the neighbouring pixels should be, i.e. the colour of the initial item taken from the list of Items in regioncounter2/5. MaxX - The maximum X value of the area. MaxY - The maximum Y value of the area. Items1 - The list of items which will be tested are part of a region. Items2 - The list of items which will be tested are part of a region, to return. **/ test3(X1, Y1, Colour, MaxX, MaxY, Items1, Items2) :- X0 is X1 - 1, X2 is X1 + 1, Y0 is Y1 - 1, Y2 is Y1 + 1, test1(X0, Y1, Colour, MaxX, MaxY, Items1, Items3), test1(X2, Y1, Colour, MaxX, MaxY, Items3, Items4), test1(X1, Y0, Colour, MaxX, MaxY, Items4, Items5), test1(X1, Y2, Colour, MaxX, MaxY, Items5, Items2). /** increment(+Colour, +Counts1, -Counts2) Colour - The colour to increment the count of. Counts1 - The current list of counts. Counts2 - The list of counts to return. **/ increment(Colour, Counts1, Counts2) :- member(Item1, Counts1), delete(Counts1, Item1, Counts3), Item1 = [Colour, Count1], Count2 is Count1 + 1, Item2 = [Colour, Count2], append(Counts3, [Item2], Counts2), !. increment(Colour, Counts1, Counts2) :- Item = [Colour, 1], append(Counts1, [Item], Counts2).