You are on page 1of 37

S`HH2H a+M G27i

S`HH2H S`Q;`KKBM; BM a+H


oBFiQ` EmM+F
S`HH2H b+M

>pBM; b22M T`HH2H KT M/ T`HH2H 7QH/


KT, TTHv 7mM+iBQM iQ 2+? 2H2K2Mi

! List(1,3,8).map(x => x*x) == List(1, 9, 64)

7QH/, +QK#BM2 2H2K2Mib rBi?  ;Bp2M QT2`iBQM

! List(1,3,8).fold(100)((s,x) => s + x) == 112

r2 MQr 2tKBM2 T`HH2H b+MG27i,


b+MG27i, HBbi Q7 i?2 7QH/b Q7 HH HBbi T`2}t2b
List(1,3,8).scanLeft(100)((s,x) => s + x) == List(100, 101, 104, 112)
b+MG27i, K2MBM; M/ T`QT2`iB2b

List(1,3,8).scanLeft(100)(_ + _) == List(100, 101, 104, 112)


List(a1, a2, a3).scanLeft(f)(a0) = List(b0, b1, b2, b3)
r?2`2

! b0 = a0
! b1 = f(b0, a1)
! b2 = f(b1, a2)
! b3 = f(b2, a3)

q2 bbmK2 i?i f Bb bbQ+iBp2- i?`Qm;?Qmi i?Bb b2;K2MiX


b+MG27i, K2MBM; M/ T`QT2`iB2b

List(1,3,8).scanLeft(100)(_ + _) == List(100, 101, 104, 112)


List(a1, a2, a3).scanLeft(f)(a0) = List(b0, b1, b2, b3)
r?2`2

! b0 = a0
! b1 = f(b0, a1)
! b2 = f(b1, a2)
! b3 = f(b2, a3)

q2 bbmK2 i?i f Bb bbQ+iBp2- i?`Qm;?Qmi i?Bb b2;K2MiX


scanRight Bb /Bz2`2Mi 7`QK scanLeft- 2p2M B7 f Bb bbQ+BiBp2
List(1,3,8).scanRight(100)(_ + _) == List(112, 111, 108, 100)
q2 +QMbB/2` QMHv scanLeft- #mi scanRight Bb /mHX
a2[m2MiBH a+M

GBbi(1 , 2 , ..., L ).b+MG27i(7)(0 ) = GBbi(#0 , #1 , #2 , ..., #L )

r?2`2 #0 = 0 M/ #B = 7(#B−1 , B ) 7Q` 1 ≤ B ≤ LX


a2[m2MiBH a+M

GBbi(1 , 2 , ..., L ).b+MG27i(7)(0 ) = GBbi(#0 , #1 , #2 , ..., #L )

r?2`2 #0 = 0 M/ #B = 7(#B−1 , B ) 7Q` 1 ≤ B ≤ LX


:Bp2  b2[m2MiBH /2}MBiBQM Q7 scanLeft,

! iF2 M ``v inp- M 2H2K2Mi a0- M/ #BM`v QT2`iBQM f


! r`Bi2 i?2 QmiTmi iQ ``v out- bbmKBM; out.length >= inp.length + 1

def scanLeft[A](inp: Array[A],


a0: A, f: (A,A) => A,
out: Array[A]): Unit
a2[m2MiBH a+M aQHmiBQM

def scanLeft[A](inp: Array[A],


a0: A, f: (A,A) => A,
out: Array[A]): Unit = {
out(0)= a0
var a= a0
var i= 0
while (i < inp.length) {
a= f(a,inp(i))
i= i + 1
out(i)= a
}
}
JFBM; b+M T`HH2H

*M scanLeft #2 K/2 T`HH2H\ bbmK2 i?i f Bb bbQ+BiBp2X


:QH, M H;Q`Bi?K i?i `mMb BM P(HQ; M) ;Bp2M BM}MBi2 T`HH2HBbK
JFBM; b+M T`HH2H

*M scanLeft #2 K/2 T`HH2H\ bbmK2 i?i f Bb bbQ+BiBp2X


:QH, M H;Q`Bi?K i?i `mMb BM P(HQ; M) ;Bp2M BM}MBi2 T`HH2HBbK
i }`bi- i?2 ibF b22Kb BKTQbbB#H2c Bi b22Kb i?i,

! i?2 pHm2 Q7 i?2 Hbi 2H2K2Mi BM b2[m2M+2 /2T2M/b QM HH T`2pBQmb QM2b
! M22/ iQ rBi QM HH T`2pBQmb T`iBH `2bmHib iQ #2 +QKTmi2/ }`bi
! bm+? TT`Q+? ;Bp2b P(M) 2p2M rBi? BM}MBi2 T`HH2HBbK
JFBM; b+M T`HH2H

*M scanLeft #2 K/2 T`HH2H\ bbmK2 i?i f Bb bbQ+BiBp2X


:QH, M H;Q`Bi?K i?i `mMb BM P(HQ; M) ;Bp2M BM}MBi2 T`HH2HBbK
i }`bi- i?2 ibF b22Kb BKTQbbB#H2c Bi b22Kb i?i,

! i?2 pHm2 Q7 i?2 Hbi 2H2K2Mi BM b2[m2M+2 /2T2M/b QM HH T`2pBQmb QM2b
! M22/ iQ rBi QM HH T`2pBQmb T`iBH `2bmHib iQ #2 +QKTmi2/ }`bi
! bm+? TT`Q+? ;Bp2b P(M) 2p2M rBi? BM}MBi2 T`HH2HBbK

A/2, ;Bp2 mT QM `2mbBM; HH BMi2`K2/Bi2 `2bmHib

! /Q KQ`2 rQ`F UKQ`2 f TTHB+iBQMbV


! BKT`Qp2 T`HH2HBbK- KQ`2 i?M +QKT2Mbi2 7Q` `2+QKTmiiBQM
>B;?@H2p2H TT`Q+?, 2tT`2bb b+M mbBM; KT M/ `2/m+2

*M vQm /2}M2 `2bmHi Q7 scanLeft mbBM; map M/ reduce\


>B;?@H2p2H TT`Q+?, 2tT`2bb b+M mbBM; KT M/ `2/m+2

*M vQm /2}M2 `2bmHi Q7 scanLeft mbBM; map M/ reduce\


bbmK2 BMTmi Bb ;Bp2M BM ``v inp M/ i?i vQm ?p2 reduceSeg1 M/
mapSeg 7mM+iBQMb QM ``v b2;K2Mib,

def reduceSeg1[A](inp: Array[A], left: Int, right: Int,


a0: Int, f: (A,A) => A): A

def mapSeg[A,B](inp: Array[A], left: Int, right: Int,


fi : (Int,A) => B,
out: Array[B]): Unit
>B;?@G2p2H aQHmiBQM

++Q`/BM; iQ /2}MBiBQM- 2H2K2Mi QM TQbBiBQM B Bb i?2 `2/m+2 Q7 i?2 T`2pBQmb


2H2K2MibX
q2 i?mb KT i?2 ``v rBi?  7mM+iBQM /2}M2/ mbBM; `2/m+2,

def scanLeft[A](inp: Array[A], a0: A, f: (A,A) => A, out: Array[A]) = {


val fi = { (i:Int,v:A) => reduceSeg1(inp, 0, i, a0, f) }
mapSeg(inp, 0, inp.length, fi, out)
val last = inp.length - 1
out(last + 1) = f(out(last), inp(last))
}

JT Hrvb ;Bp2b b KMv 2H2K2Mib b i?2 BMTmi- bQ r2 //BiBQMHHv


+QKTmi2 i?2 Hbi 2H2K2MiX
_2mbBM; BMi2`K2/Bi2 `2bmHib Q7 `2/m+2

AM i?2 T`2pBQmb bQHmiBQM r2 /Q MQi `2mb2 Mv +QKTmiiBQMX


*M r2 `2mb2 bQK2 Q7 Bi\
_2+HH i?i reduce T`Q+22/b #v TTHvBM; i?2 QT2`iBQMb BM  i`22
A/2, bp2 i?2 BMi2`K2/Bi2 `2bmHib Q7 i?Bb T`HH2H +QKTmiiBQMX
_2mbBM; BMi2`K2/Bi2 `2bmHib Q7 `2/m+2

AM i?2 T`2pBQmb bQHmiBQM r2 /Q MQi `2mb2 Mv +QKTmiiBQMX


*M r2 `2mb2 bQK2 Q7 Bi\
_2+HH i?i reduce T`Q+22/b #v TTHvBM; i?2 QT2`iBQMb BM  i`22
A/2, bp2 i?2 BMi2`K2/Bi2 `2bmHib Q7 i?Bb T`HH2H +QKTmiiBQMX
q2 }`bi bbmK2 i?i BMTmi +QHH2+iBQ Bb HbQ UMQi?2`V i`22X
h`22 /2}MBiBQMb

h`22b biQ`BM; Qm` BMTmi +QHH2+iBQM QMHv ?p2 pHm2b BM H2p2b,

sealed abstract class Tree[A]


case class Leaf[A](a: A) extends Tree[A]
case class Node[A](l: Tree[A], r: Tree[A]) extends Tree[A]

h`22b biQ`BM; BMi2`K2/Bi2 pHm2b HbQ ?p2 UresV pHm2b BM MQ/2b,

sealed abstract class TreeRes[A] { val res: A }


case class LeafRes[A](override val res: A) extends TreeRes[A]
case class NodeRes[A](l: TreeRes[A],
override val res: A,
r: TreeRes[A]) extends TreeRes[A]
h`22 /2}MBiBQMb

h`22b biQ`BM; Qm` BMTmi +QHH2+iBQM QMHv ?p2 pHm2b BM H2p2b,

sealed abstract class Tree[A]


case class Leaf[A](a: A) extends Tree[A]
case class Node[A](l: Tree[A], r: Tree[A]) extends Tree[A]

h`22b biQ`BM; BMi2`K2/Bi2 pHm2b HbQ ?p2 UresV pHm2b BM MQ/2b,

sealed abstract class TreeRes[A] { val res: A }


case class LeafRes[A](override val res: A) extends TreeRes[A]
case class NodeRes[A](l: TreeRes[A],
override val res: A,
r: TreeRes[A]) extends TreeRes[A]

*M vQm /2}M2 reduceRes 7mM+iBQM i?i i`Mb7Q`Kb Tree BMiQ TreeRes\
_2/m+2 i?i T`2b2`p2b i?2 +QKTmiiBQM i`22

def reduceRes[A](t: Tree[A], f: (A,A) => A): TreeRes[A]


_2/m+2 i?i T`2b2`p2b i?2 +QKTmiiBQM i`22

def reduceRes[A](t: Tree[A], f: (A,A) => A): TreeRes[A] = t match {


case Leaf(v) => LeafRes(v)
case Node(l, r) => { •
val (tL, tR) = (reduceRes(l, f), reduceRes(r, f)) • •
NodeRes(tL, f(tL.res, tR.res), tR)
1 3 8 50
}
}
_2/m+2 i?i T`2b2`p2b i?2 +QKTmiiBQM i`22

def reduceRes[A](t: Tree[A], f: (A,A) => A): TreeRes[A] = t match {


case Leaf(v) => LeafRes(v)
case Node(l, r) => { •
62
val (tL, tR) = (reduceRes(l, f), reduceRes(r, f)) • •
4 58
NodeRes(tL, f(tL.res, tR.res), tR)
1 3 8 50
}
}
val t1 = Node(Node(Leaf(1), Leaf(3)), Node(Leaf(8), Leaf(50)))
val plus = (x:Int,y:Int) => x+y
scala> reduceRes(t1, plus)
res0: TreeRes[Int] = NodeRes(NodeRes(LeafRes(1),4,LeafRes(3)),
62,
NodeRes(LeafRes(8),58,LeafRes(50)))
S`HH2H `2/m+2 i?i T`2b2`p2b i?2 +QKTmiiBQM i`22 UmTbr22TV

def upsweep[A](t: Tree[A], f: (A,A) => A): TreeRes[A] = t match {


case Leaf(v) => LeafRes(v)
case Node(l, r) => {
val (tL, tR) = parallel(upsweep(l, f), upsweep(r, f))
NodeRes(tL, f(tL.res, tR.res), tR)
}
}
lbBM; i`22 rBi? `2bmHib iQ +`2i2 i?2 }MH +QHH2+iBQM


62 L2ti,  i`22 7Q` Ryy- RyR- Ry9- RRk- Rek
• •
4 58
1 3 8 50
lbBM; i`22 rBi? `2bmHib iQ +`2i2 i?2 }MH +QHH2+iBQM


62 L2ti,  i`22 7Q` Ryy- RyR- Ry9- RRk- Rek
• •
4 58
1 3 8 50

// āa0ā is reduce of all elements left of the tree ātā


def downsweep[A](t: TreeRes[A], a0: A, f : (A,A) => A): Tree[A] = t match {
case LeafRes(a) => Leaf(f(a0, a))
case NodeRes(l, _, r) => {
val (tL, tR) = parallel(downsweep[A](l, a0, f),
downsweep[A](r, f(a0, l.res), f))
Node(tL, tR) } }
lbBM; i`22 rBi? `2bmHib iQ +`2i2 i?2 }MH +QHH2+iBQM


62 L2ti,  i`22 7Q` Ryy- RyR- Ry9- RRk- Rek
• •
4 58
1 3 8 50

// āa0ā is reduce of all elements left of the tree ātā


def downsweep[A](t: TreeRes[A], a0: A, f : (A,A) => A): Tree[A] = t match {
case LeafRes(a) => Leaf(f(a0, a))
case NodeRes(l, _, r) => {
val (tL, tR) = parallel(downsweep[A](l, a0, f),
downsweep[A](r, f(a0, l.res), f))
Node(tL, tR) } }

scala> downsweep(res0, 100, plus)


res1: Tree[Int] = Node(Node(Leaf(101),Leaf(104)),Node(Leaf(112),Leaf(162)))
b+MG27i QM i`22b

def scanLeft[A](t: Tree[A], a0: A, f: (A,A) => A): Tree[A] = {


val tRes = upsweep(t, f)
val scan1 = downsweep(tRes, a0, f)
prepend(a0, scan1)
}
b+MG27i QM i`22b

def scanLeft[A](t: Tree[A], a0: A, f: (A,A) => A): Tree[A] = {


val tRes = upsweep(t, f)
val scan1 = downsweep(tRes, a0, f)
prepend(a0, scan1)
}

.2}M2 prependX
b+MG27i QM i`22b

def scanLeft[A](t: Tree[A], a0: A, f: (A,A) => A): Tree[A] = {


val tRes = upsweep(t, f)
val scan1 = downsweep(tRes, a0, f)
prepend(a0, scan1)
}

.2}M2 prependX

def prepend[A](x: A, t: Tree[A]): Tree[A] = t match {


case Leaf(v) => Node(Leaf(x), Leaf(v))
case Node(l, r) => Node(prepend(x, l), r)
}
b+MG27i M/ ``vb

S`2pBQmb /2}MBiBQM QM i`22b Bb ;QQ/ 7Q` mM/2`biM/BM;


b rBi? KT M/ `2/m+2- iQ KF2 Bi KQ`2 2{+B2Mi- r2 mb2 i`22b i?i ?p2
``vb BM H2p2b BMbi2/ Q7 BM/BpB/mH 2H2K2MibX
b+MG27i M/ ``vb

S`2pBQmb /2}MBiBQM QM i`22b Bb ;QQ/ 7Q` mM/2`biM/BM;


b rBi? KT M/ `2/m+2- iQ KF2 Bi KQ`2 2{+B2Mi- r2 mb2 i`22b i?i ?p2
``vb BM H2p2b BMbi2/ Q7 BM/BpB/mH 2H2K2MibX
1t2`+Bb2, /2}M2 scanLeft QM i`22b rBi? bm+? H`;2 H2p2b- mbBM; b2[m2MiBH
b+M H27i BM i?2 H2p2bX
b+MG27i M/ ``vb

S`2pBQmb /2}MBiBQM QM i`22b Bb ;QQ/ 7Q` mM/2`biM/BM;


b rBi? KT M/ `2/m+2- iQ KF2 Bi KQ`2 2{+B2Mi- r2 mb2 i`22b i?i ?p2
``vb BM H2p2b BMbi2/ Q7 BM/BpB/mH 2H2K2MibX
1t2`+Bb2, /2}M2 scanLeft QM i`22b rBi? bm+? H`;2 H2p2b- mbBM; b2[m2MiBH
b+M H27i BM i?2 H2p2bX
L2ti bi2T, T`HH2H b+M r?2M i?2 2MiB`2 +QHH2+iBQM Bb M ``v

! r2 rBHH biBHH M22/ iQ +QMbi`m+i i?2 BMi2`K2/Bi2 i`22


AMi2`K2/Bi2 i`22 7Q` ``v `2/m+2

sealed abstract class TreeResA[A] { val res: A }


case class Leaf[A](from: Int, to: Int,
override val res: A) extends TreeResA[A]
case class Node[A](l: TreeResA[A],
override val res: A,
r: TreeResA[A]) extends TreeResA[A]

h?2 QMHv /Bz2`2M+2 +QKT`2/ iQ T`2pBQmb h`22_2b, 2+? G27 MQr F22Tb
i`+F Q7 i?2 ``v b2;K2Mi `M;2 U7`QK- iQV 7`QK r?B+? res Bb +QKTmi2/X
q2 /Q MQi F22T i`+F Q7 i?2 ``v 2H2K2Mib BM i?2 G27 Bib2H7c r2 BMbi2/
Tbb `QmM/  `272`2M+2 iQ i?2 BMTmi ``vX
lTbr22T QM ``v

ai`ib 7`QK M ``v- T`Q/m+2b  i`22

def upsweep[A](inp: Array[A], from: Int, to: Int,


f: (A,A) => A): TreeResA[A] = {
if (to - from < threshold)
Leaf(from, to, reduceSeg1(inp, from + 1, to, inp(from), f))
else {
val mid = from + (to - from)/2
val (tL,tR) = parallel(upsweep(inp, from, mid, f),
upsweep(inp, mid, to, f))
Node(tL, f(tL.res,tR.res), tR)
}
}
a2[m2MiBH `2/m+2 7Q` b2;K2Mi

def reduceSeg1[A](inp: Array[A], left: Int, right: Int,


a0: A, f: (A,A) => A): A = {
var a= a0
var i= left
while (i < right) {
a= f(a, inp(i))
i= i+1
}
a
}
.QrMbr22T QM ``v

def downsweep[A](inp: Array[A],


a0: A, f: (A,A) => A,
t: TreeResA[A],
out: Array[A]): Unit = t match {
case Leaf(from, to, res) =>
scanLeftSeg(inp, from, to, a0, f, out)
case Node(l, _, r) => {
val (_,_) = parallel(
downsweep(inp, a0, f, l, out),
downsweep(inp, f(a0,l.res), f, r, out))
}
}
a2[m2MiBH b+M H27i QM b2;K2Mi

q`Bi2b iQ QmiTmi b?B7i2/ #v QM2X

def scanLeftSeg[A](inp: Array[A], left: Int, right: Int,


a0: A, f: (A,A) => A,
out: Array[A]) = {
if (left < right) {
var i= left
var a= a0
while (i < right) {
a= f(a,inp(i))
i= i+1
out(i)=a
}
}
}
6BMHHv, T`HH2H b+M QM i?2 ``v

def scanLeft[A](inp: Array[A],


a0: A, f: (A,A) => A,
out: Array[A]) = {
val t = upsweep(inp, 0, inp.length, f)
downsweep(inp, a0, f, t, out) // fills out[1..inp.length]
out(0)= a0 // prepends a0
}
1M/ Q7 aHB/2 .2+F

You might also like