Functional way to get a matrix from text
Posted
by Elazar Leibovich
on Stack Overflow
See other posts from Stack Overflow
or by Elazar Leibovich
Published on 2010-03-26T11:36:54Z
Indexed on
2010/03/26
12:43 UTC
Read the original article
Hit count: 407
I'm trying to solve some Google Code Jam problems, where an input matrix is typically given in this form:
2 3 #matrix dimensions
1 2 3 4 5 6 7 8 9 # all 3 elements in the first row
2 3 4 5 6 7 8 9 0 # each element is composed of three integers
where each element of the matrix is composed of, say, three integers. So this example should be converted to
#!scala
Array(
Array(A(1,2,3),A(4,5,6),A(7,8,9),
Array(A(2,3,4),A(5,6,7),A(8,9,0),
)
An imperative solution would be of the form
#!python
input = """2 3
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 0
"""
lines = input.split('\n')
print lines[0]
m,n = (int(x) for x in lines[0].split())
array = []
row = []
A = []
for line in lines[1:]:
for elt in line.split():
A.append(elt)
if len(A)== 3:
row.append(A)
A = []
array.append(row)
row = []
from pprint import pprint
pprint(array)
A functional solution I've thought of is
#!scala
def splitList[A](l:List[A],i:Int):List[List[A]] = {
if (l.isEmpty) return List[List[A]]()
val (head,tail) = l.splitAt(i)
return head :: splitList(tail,i)
}
def readMatrix(src:Iterator[String]):Array[Array[TrafficLight]] = {
val Array(x,y) = src.next.split(" +").map(_.trim.toInt)
val mat = src.take(x).toList.map(_.split(" ").
map(_.trim.toInt)).
map(a => splitList(a.toList,3).
map(b => TrafficLight(b(0),b(1),b(2))
).toArray
).toArray
return mat
}
But I really feel it's the wrong way to go because:
- I'm using the functional
List
structure for each line, and then convert it to an array. The whole code seems much less efficeint - I find it longer less elegant and much less readable than the python solution. It is harder to which of the map functions operates on what, as they all use the same semantics.
What is the right functional way to do that?
© Stack Overflow or respective owner