Abelian sandpile model/Identity: Difference between revisions

Content added Content deleted
(Realize in F#)
Line 257: Line 257:
</pre>
</pre>


=={{header|F_Sharp|F#}}==
<lang fsharp>
// Abelian sandpile model/Identity. Nigel Galloway: July 20th., 2020
type Sandpile (N:array<int>)=
member private this.i=let rec topple n=match Array.tryFindIndex(fun n->n>3)n with
None->n
|Some g->n.[g]<-n.[g]-4
match g with 0->n.[3]<-n.[3]+1;n.[1]<-n.[1]+1;topple n
|1->n.[4]<-n.[4]+1;n.[0]<-n.[0]+1;n.[2]<-n.[2]+1;topple n
|2->n.[5]<-n.[5]+1;n.[1]<-n.[1]+1;topple n
|3->n.[0]<-n.[0]+1;n.[6]<-n.[6]+1;n.[4]<-n.[4]+1;topple n
|4->n.[1]<-n.[1]+1;n.[7]<-n.[7]+1;n.[3]<-n.[3]+1;n.[5]<-n.[5]+1;topple n
|5->n.[2]<-n.[2]+1;n.[8]<-n.[8]+1;n.[4]<-n.[4]+1;topple n
|6->n.[3]<-n.[3]+1;n.[7]<-n.[7]+1;topple n
|7->n.[4]<-n.[4]+1;n.[6]<-n.[6]+1;n.[8]<-n.[8]+1;topple n
|8->n.[5]<-n.[5]+1;n.[7]<-n.[7]+1;topple n
topple N
static member (+) ((n:Sandpile), g:Sandpile)=Sandpile(Array.map2(fun n g->n+g) n.i g.i)
member this.toS=sprintf "%A" (this.i|>Array.chunkBySize 3|>array2D)

let s1=Sandpile[|1;2;0;2;1;1;0;1;3|]
let s2=Sandpile[|2;1;3;1;0;1;0;1;0|]

printfn "%s\n" ((s1+s2).toS)
printfn "%s\n" ((s2+s1).toS);;
printfn "%s\n" ((s1+s1).toS)
printfn "%s\n" ((s2+s2).toS);;
printfn "%s\n" (Sandpile [|4;3;3;3;1;2;0;2;3|]).toS;;
let s3=Sandpile(Array.create 9 3)
let s3_id=Sandpile[|2;1;2;1;0;1;2;1;2|]
printfn "%s\n" (s3+s3_id).toS
printfn "%s\n" (s3_id+s3_id).toS
</lang>
{{out}}
<pre>
[[3; 3; 3]
[3; 1; 2]
[0; 2; 3]]

[[3; 3; 3]
[3; 1; 2]
[0; 2; 3]]

[[0; 2; 2]
[2; 2; 1]
[2; 1; 0]]

[[1; 0; 3]
[3; 1; 3]
[0; 2; 0]]

[[2; 1; 0]
[0; 3; 3]
[1; 2; 3]]

[[3; 3; 3]
[3; 3; 3]
[3; 3; 3]]

[[2; 1; 2]
[1; 0; 1]
[2; 1; 2]]
</pre>
=={{header|Factor}}==
=={{header|Factor}}==
I wouldn't call it a translation, but the idea of storing sandpiles as flat arrays came from the Wren entry.
I wouldn't call it a translation, but the idea of storing sandpiles as flat arrays came from the Wren entry.