Abelian sandpile model/Identity: Difference between revisions
Content added Content deleted
m (→{{header|REXX}}: cleaned up some code.) |
No edit summary |
||
Line 730: | Line 730: | ||
1 0 1 |
1 0 1 |
||
2 1 2 |
2 1 2 |
||
</pre> |
|||
=={{header|Ada}}== |
|||
{{trans|C++}} |
|||
This Ada example works with Ada 2012 because of the use the aspect '''with Default_Component_Value'''. |
|||
The package specification for Abelian_Sandpile is: |
|||
<lang Ada>-- Works with Ada 2012 |
|||
package Abelian_Sandpile is |
|||
Limit : constant Integer := 4; |
|||
type Sandpile is array (0 .. 2, 0 .. 2) of Natural with |
|||
Default_Component_Value => 0; |
|||
procedure Stabalize (Pile : in out Sandpile); |
|||
function Is_Stable (Pile : in Sandpile) return Boolean; |
|||
procedure Topple (Pile : in out Sandpile); |
|||
function "+" (Left, Right : Sandpile) return Sandpile; |
|||
procedure Print(PIle : in Sandpile); |
|||
end Abelian_Sandpile; |
|||
</lang> |
|||
The package body for Abelian_Sandpile is |
|||
<lang Ada>with Ada.Text_Io; use Ada.Text_IO; |
|||
package body Abelian_Sandpile is |
|||
--------------- |
|||
-- Stabalize -- |
|||
--------------- |
|||
procedure Stabalize (Pile : in out Sandpile) is |
|||
begin |
|||
while not Is_Stable(Pile) loop |
|||
Topple(Pile); |
|||
end loop; |
|||
end Stabalize; |
|||
--------------- |
|||
-- Is_Stable -- |
|||
--------------- |
|||
function Is_Stable (Pile : in Sandpile) return Boolean is |
|||
begin |
|||
return (for all E of Pile => E < Limit); |
|||
end Is_Stable; |
|||
------------ |
|||
-- Topple -- |
|||
------------ |
|||
procedure Topple (Pile : in out Sandpile) is |
|||
begin |
|||
outer: |
|||
for Row in Pile'Range(1) loop |
|||
for Col in Pile'Range(2) loop |
|||
if Pile(Row, Col) >= Limit then |
|||
Pile(Row, Col) := Pile(Row, Col) - Limit; |
|||
if Row > 0 then |
|||
Pile(Row - 1, Col) := Pile(Row -1, Col) + 1; |
|||
end if; |
|||
if Row < Pile'Last(1) then |
|||
Pile(Row + 1, Col) := Pile(Row + 1, Col) + 1; |
|||
end if; |
|||
if Col > 0 then |
|||
Pile(Row, Col - 1) := Pile(Row, Col - 1) + 1; |
|||
end if; |
|||
if Col < Pile'Last(2) then |
|||
Pile(Row, Col + 1) := Pile(Row, Col + 1) + 1; |
|||
end if; |
|||
exit outer; |
|||
end if; |
|||
end loop; |
|||
end loop outer; |
|||
end Topple; |
|||
--------- |
|||
-- "+" -- |
|||
--------- |
|||
function "+" (Left, Right : Sandpile) return Sandpile is |
|||
Result : Sandpile; |
|||
begin |
|||
for I in Sandpile'Range(1) loop |
|||
for J in Sandpile'Range(2) loop |
|||
Result(I, J) := Left(I, J) + Right(I, J); |
|||
end loop; |
|||
end loop; |
|||
Stabalize(Result); |
|||
return Result; |
|||
end "+"; |
|||
----------- |
|||
-- Print -- |
|||
----------- |
|||
procedure Print(Pile : in Sandpile) is |
|||
begin |
|||
for row in Pile'Range(1) loop |
|||
for col in Pile'Range(2) loop |
|||
Put(Integer'Image(Pile(row, col))); |
|||
end loop; |
|||
New_Line; |
|||
end loop; |
|||
New_Line; |
|||
end Print; |
|||
end Abelian_Sandpile; |
|||
</lang> |
|||
The main procedure performing the same tests as the C++ example is |
|||
<lang Ada> |
|||
with Ada.Text_IO; use Ada.Text_IO; |
|||
with Abelian_Sandpile; use Abelian_Sandpile; |
|||
procedure Main is |
|||
sp : Sandpile := ((4, 3, 3), (3, 1, 2), (0, 2, 3)); |
|||
s1 : Sandpile := ((1, 2, 0), (2, 1, 1), (0, 1, 3)); |
|||
s2 : Sandpile := ((2, 1, 3), (1, 0, 1), (0, 1, 0)); |
|||
s3 : Sandpile := ((3, 3, 3), (3, 3, 3), (3, 3, 3)); |
|||
s3_id : Sandpile := ((2, 1, 2), (1, 0, 1), (2, 1, 2)); |
|||
sum1 : Sandpile := s1 + s2; |
|||
sum2 : Sandpile := s2 + s1; |
|||
sum3 : Sandpile := s3 + s3_id; |
|||
sum4 : Sandpile := s3_id + s3_id; |
|||
begin |
|||
Put_Line ("Avalanche:"); |
|||
while not Is_Stable (sp) loop |
|||
Print (sp); |
|||
Put_Line ("stable? " & Boolean'Image (Is_Stable (sp))); |
|||
New_Line; |
|||
Topple (sp); |
|||
end loop; |
|||
Print (sp); |
|||
Put_Line ("stable? " & Boolean'Image (Is_Stable (sp))); |
|||
New_Line; |
|||
Put_Line ("Commutivity:"); |
|||
Put_Line ("s1 + s2 equals s2 + s2? " & Boolean'Image (sum1 = sum2)); |
|||
New_Line; |
|||
Put_Line ("S1 : s2 ="); |
|||
Print (sum1); |
|||
New_Line; |
|||
Put_Line ("s2 + s1 ="); |
|||
Print (sum2); |
|||
New_Line; |
|||
Put_Line ("Identity:"); |
|||
Put_Line ("s3 + s3_id equals s3? " & Boolean'Image (sum3 = s3)); |
|||
Put_Line ("s3_id + s3_id equals s3_id? " & Boolean'Image (sum4 = s3_id)); |
|||
New_Line; |
|||
Put_Line ("s3 + s3_id ="); |
|||
Print (sum3); |
|||
Put_Line ("s3_id + s3_id ="); |
|||
Print (sum4); |
|||
end Main; |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
Avalanche: |
|||
4 3 3 |
|||
3 1 2 |
|||
0 2 3 |
|||
stable? FALSE |
|||
0 4 3 |
|||
4 1 2 |
|||
0 2 3 |
|||
stable? FALSE |
|||
1 0 4 |
|||
4 2 2 |
|||
0 2 3 |
|||
stable? FALSE |
|||
1 1 0 |
|||
4 2 3 |
|||
0 2 3 |
|||
stable? FALSE |
|||
2 1 0 |
|||
0 3 3 |
|||
1 2 3 |
|||
stable? TRUE |
|||
Commutivity: |
|||
s1 + s2 equals s2 + s2? TRUE |
|||
S1 : s2 = |
|||
3 3 3 |
|||
3 1 2 |
|||
0 2 3 |
|||
s2 + s1 = |
|||
3 3 3 |
|||
3 1 2 |
|||
0 2 3 |
|||
Identity: |
|||
s3 + s3_id equals s3? TRUE |
|||
s3_id + s3_id equals s3_id? TRUE |
|||
s3 + s3_id = |
|||
3 3 3 |
|||
3 3 3 |
|||
3 3 3 |
|||
s3_id + s3_id = |
|||
2 1 2 |
|||
1 0 1 |
|||
2 1 2 |
|||
</pre> |
</pre> |
||