3 people like it.
Like the snippet!
Print a list in a spiral
Prints a list in a spiral
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
|
module CircularPrint
open FsUnit
open NUnit.Framework
type Direction = int * int -> int * int
type Directions = Direction []
let right (x,y) = (x + 1, y)
let down (x,y) = (x, y + 1)
let left (x,y) = (x - 1, y)
let up (x,y) = (x, y - 1)
let directions : Directions = [| right; down; left; up; |]
let board n =
let count = ref 0
Array2D.init n n (fun x y -> count := !count + 1; !count)
let printBoard (directions : Directions) (board: int[,]) =
seq {
let (@) (twoDArr : 'a[,]) (x,y) = twoDArr.[y,x]
let length = Array2D.length1 board
let rec print pos moveNum bound =
seq{
let boundsCheck (x, y) =
let ``end`` = length - bound
let start = bound
x < ``end`` && y < ``end`` && x >= start && y >= start
let direction n = directions.[n % (length - 1)]
let move = moveNum |> direction
if boundsCheck pos then
yield board @ pos
let next = pos |> move
// go till the next guy hits the past bound
if boundsCheck next then
yield! print next moveNum bound
// if the next goes beyond the bound, shift directions on the original
// until we've moved N times, covering all elements of the board
else if moveNum < length then
yield! print pos (moveNum + 1) bound
}
for layer in 0.. Array2D.length1 board do
yield! print (layer, layer) 0 layer
} |> Seq.distinct
[<Test>]
let testSquare4 () =
board 4
|> printBoard directions
|> Seq.toList
|> should equal [1; 2; 3; 4; 8; 12; 16; 15; 14; 13; 6; 7; 11; 10]
[<Test>]
let testSquare5 () =
board 5
|> printBoard directions
|> Seq.toList
|> should equal [1; 2; 3; 4; 5; 10; 15; 20; 25; 24; 23; 22; 21; 16; 11; 6; 7; 8; 9; 14; 19; 18; 17; 12; 13]
|
module CircularPrint
namespace FsUnit
namespace NUnit
namespace NUnit.Framework
type Direction = int * int -> int * int
Full name: CircularPrint.Direction
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
type Directions = Direction []
Full name: CircularPrint.Directions
val right : x:int * y:'a -> int * 'a
Full name: CircularPrint.right
val x : int
val y : 'a
val down : x:'a * y:int -> 'a * int
Full name: CircularPrint.down
val x : 'a
val y : int
val left : x:int * y:'a -> int * 'a
Full name: CircularPrint.left
val up : x:'a * y:int -> 'a * int
Full name: CircularPrint.up
val directions : Directions
Full name: CircularPrint.directions
val board : n:int -> int [,]
Full name: CircularPrint.board
val n : int
val count : int ref
Multiple items
val ref : value:'T -> 'T ref
Full name: Microsoft.FSharp.Core.Operators.ref
--------------------
type 'T ref = Ref<'T>
Full name: Microsoft.FSharp.Core.ref<_>
module Array2D
from Microsoft.FSharp.Collections
val init : length1:int -> length2:int -> initializer:(int -> int -> 'T) -> 'T [,]
Full name: Microsoft.FSharp.Collections.Array2D.init
val printBoard : directions:Directions -> board:int [,] -> seq<int>
Full name: CircularPrint.printBoard
val directions : Directions
val board : int [,]
Multiple items
val seq : sequence:seq<'T> -> seq<'T>
Full name: Microsoft.FSharp.Core.Operators.seq
--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>
Full name: Microsoft.FSharp.Collections.seq<_>
val twoDArr : 'a [,]
val length : int
val length1 : array:'T [,] -> int
Full name: Microsoft.FSharp.Collections.Array2D.length1
val print : (int * int -> int -> int -> seq<int>)
val pos : int * int
val moveNum : int
val bound : int
val boundsCheck : (int * int -> bool)
val start : int
val direction : (int -> Direction)
val move : Direction
val next : int * int
val layer : int
module Seq
from Microsoft.FSharp.Collections
val distinct : source:seq<'T> -> seq<'T> (requires equality)
Full name: Microsoft.FSharp.Collections.Seq.distinct
Multiple items
type TestAttribute =
inherit Attribute
new : unit -> TestAttribute
member Description : string with get, set
Full name: NUnit.Framework.TestAttribute
--------------------
TestAttribute() : unit
val testSquare4 : unit -> unit
Full name: CircularPrint.testSquare4
val toList : source:seq<'T> -> 'T list
Full name: Microsoft.FSharp.Collections.Seq.toList
val should : f:('a -> #Constraints.Constraint) -> x:'a -> y:obj -> unit
Full name: FsUnit.TopLevelOperators.should
val equal : x:'a -> EqualsConstraint
Full name: FsUnit.TopLevelOperators.equal
val testSquare5 : unit -> unit
Full name: CircularPrint.testSquare5
More information