Find unique matrices from a larger matrix

I am new to functional programming, so I do some practical exercises. I want to write a function defined by a matrix of unique natural numbers, say 5x5, to return a collection of unique smaller matrices, say 3x3, where the matrices should be intact, i.e. Created from values ​​contiguous in the original.

01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25

Simple Just move, then down, one after another in groups of 3 to get something similar:

01 02 03 | 02 03 04 | 03 04 05 | 06 07 08
06 07 08 | 07 08 09 | 08 09 10 | 11 12 13
11 12 13 | 12 13 14 | 13 14 15 | 16 17 18

or, in Scala,

List(List(1, 2, 3), List(6, 7, 8), List(11, 12, 13))
List(List(2, 3, 4), List(7, 8, 9), List(12, 13, 14))
List(List(3, 4, 5), List(8, 9, 10), List(13, 14, 15))
List(List(6, 7, 8), List(11, 12, 13), List(16, 17, 18))

etc. etc.

So, I will go out with Scala (my language of choice, because it allows me to evolve from imperative to functional, and I spent the last few years in Java.

val array2D = "01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25".grouped(3).map(_.trim.toInt).grouped(5)
val sliced = array2D.map(row => row.sliding(3, 1).toList).sliding(3, 1).toList

, , . , sliced, var matrix = new ListBuffer[Seq[Int]]() , .

, , Scala, . zip 3 - ... ScalaDocs , , .

+1
2

. , , . , . , array2D a List, .: -)

val input = "01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25"
val intArray = (input split " " map (_.toInt) toList)
val array2D = (intArray grouped 5 toList)
val sliced = array2D.map(row => row.sliding(3, 1).toList).sliding(3, 1).toList

, , :

List(List(List( 1,  2,  3), List( 2,  3,  4), List( 3,  4,  5)), 
     List(List( 6,  7,  8), List( 7,  8,  9), List( 8,  9, 10)), 
     List(List(11, 12, 13), List(12, 13, 14), List(13, 14, 15)))

, :

List(List(List(1, 2, 3), List(6, 7,  8), List(11, 12, 13)), 
     List(List(2, 3, 4), List(7, 8,  9), List(12, 13, 14)), 
     List(List(3, 4, 5), List(8, 9, 10), List(13, 14, 15)))

? - :

List(List(1, 2, 3), List(6, 7,  8), List(11, 12, 13))

01 02 03
06 07 08
11 12 13

, , . :

val subMatrices = sliced map (_.transpose)

List[List[List[Seq[Int]]]]. ... 2D- ​​ , List[Seq[Int]] . :

type Matrix = Seq[Seq[Int]]
val subMatrices: List[List[Matrix]] = sliced map (_.transpose)

, :

type Matrix = Seq[Seq[Int]]
val subMatrices: List[Matrix] = (sliced map (_.transpose) flatten)

, , a map a flatten flatMap:

type Matrix = Seq[Seq[Int]]
val subMatrices: List[Matrix] = sliced flatMap (_.transpose)

. : .

val uniqueSubMatrices = subMatrices.toSet

, ,

val uniqueSubMatrices = subMatrices.distinct

. :

type Matrix = Seq[Seq[Int]]
val input = "01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25"
val intArray = (input split " " map (_.toInt) toList)
val array2D: Matrix = (intArray grouped 5 toList)
val sliced: List[List[Matrix]] = (array2D map (row => row sliding 3 toList) sliding 3 toList)
val subMatrices: List[Matrix] = sliced flatMap (_.transpose)
val uniqueSubMatrices: Set[Matrix] = subMatrices.toSet

, , . (|>, ), , , .

+2

Edit: , , , , , . , , , . ( Java- , , .)

-, , 2D . 1D- 2D- . . . .

, , .

val big = (1 to 25).grouped(5).map(_.toList).toList

, . ,

val smaller = (for (r <- big.sliding(3)) yield r.toList).toList

- , . 2D, -, 1D-. :

val small = smaller.map(xss =>
  Iterator.iterate(xss.map(_.sliding(3)))(identity).
    takeWhile(_.forall(_.hasNext)).
    map(_.map(_.next)).
    toList
).toList

, , (xss.map(_.sliding(3))), , , , ( ).

, , , . :

val flattened = small.flatten

, , ( , 2D- 1D- ):

val sidebyside = flattened.reduceRight((l,r) => (l,r).zipped.map(_ ::: _))

(note reduceRight, O (n) O (n ^ 2) - - - , , , ).

+1

Source: https://habr.com/ru/post/1738648/


All Articles