Skip to content

Commit 7afb03e

Browse files
committed
add answers to exercise 1-4 chapter 5
1 parent 30b1ae9 commit 7afb03e

File tree

2 files changed

+162
-4
lines changed

2 files changed

+162
-4
lines changed
Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,72 @@
1-
package org.learningconcurrency.exercises.ch5
1+
package org.learningconcurrency
2+
package exercises
3+
package ch5
24

3-
object Ex2 {
5+
import scala.util.Random
46

7+
/**
8+
* Count the occurrences of the whitespace character in a randomly generated string,
9+
* where the probability of a whitespace at each position is determined by a p parameter.
10+
*
11+
* Use the parallel foreach method.
12+
*
13+
* Plot a graph that correlates the running time of this operation with the p parameter.
14+
*/
15+
object Ex2 extends App {
16+
17+
import org.learningconcurrency.ch5._
18+
19+
var r = new Random
20+
21+
val chars = ('a' to 'z') ++ ('A' to 'Z')
22+
23+
def generateSymbol(p: Double): Char =
24+
if (r.nextDouble() > p) chars(Random.nextInt(chars.length)) else ' '
25+
26+
def generateString(p: Double, length: Int = 10000): Seq[Char] = {
27+
(0 to length).map((i) => generateSymbol(p))
28+
}
29+
30+
def timedForeach(s: Seq[Char]) = {
31+
var count = 0
32+
def add = synchronized {
33+
count += 1
34+
}
35+
36+
warmedTimed(times = 400) {
37+
s.par.foreach((s) => if (s == ' ') add)
38+
}
39+
}
40+
41+
def timedCount(s: Seq[Char]) = {
42+
warmedTimed(times = 400) {
43+
s.par.count(_ == ' ')
44+
}
45+
}
46+
47+
//probability
48+
val p = (0 until 10).map { i => i / 9.0 }
49+
50+
log("---- Calculation occurrences with foreach method")
51+
val dataForeach = p.map((p) => (p, generateString(p))).map {
52+
case (p, s) => log(s"p = $p"); (p, timedForeach(s))
53+
}
54+
55+
log("---- Calculation occurrences with count method")
56+
val dataCount = p.map((p) => (p, generateString(p))).map {
57+
case (p, s) => log(s"p = $p"); (p, timedCount(s))
58+
}
59+
60+
//plot graph
61+
//uses https://github.com/quantifind/wisp
62+
63+
import com.quantifind.charts.Highcharts._
64+
65+
hold
66+
line(dataForeach)
67+
line(dataCount)
68+
title("Ch5 Ex2")
69+
legend(Seq("foreach method", "count method"))
70+
xAxis("probability")
71+
yAxis("time (ms)")
572
}
Lines changed: 93 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,96 @@
1-
package org.learningconcurrency.exercises.ch5
1+
package org.learningconcurrency
2+
package exercises
3+
package ch5
24

3-
object Ex3 {
5+
import scala.annotation.tailrec
6+
import scalafx.application.JFXApp
7+
import scalafx.scene.Scene
8+
import scalafx.scene.layout.Pane
9+
import scalafx.scene.paint.Color
10+
import scalafx.scene.shape.Rectangle
11+
12+
/**
13+
* Implement a program that renders the Mandelbrot set in parallel.
14+
*/
15+
16+
object Ex3 extends JFXApp {
17+
18+
val width = 400
19+
val height = 400
20+
21+
val minX = -1.75
22+
val maxX = 0.8
23+
24+
val minY = -1.2
25+
val maxY = 1.2
26+
27+
val stepX = (maxX - minX) / width
28+
val stepY = (maxY - minY) / height
29+
30+
val threshold = 300
31+
32+
case class RGB(red: Int, green: Int, blue: Int)
33+
34+
case class Pixel(x: Int, y: Int, gray: Double)
35+
36+
def buildPixel(x: Int, y: Int) = {
37+
val xc = minX + stepX * x
38+
val yc = minY + stepY * y
39+
40+
val count = calcIterations(x = 0, y = 0, xc = xc, yc = yc, i = 0)
41+
42+
Pixel(x = x, y = y, gray = 1.0 - count * 1.0 / threshold)
43+
}
44+
45+
@tailrec
46+
def calcIterations(x: Double, y: Double, xc: Double, yc: Double, i: Int): Int = {
47+
48+
if ((x * x + y * y < 2) && (i < threshold))
49+
calcIterations(
50+
x = x * x - y * y + xc,
51+
y = 2 * x * y + yc,
52+
xc = xc,
53+
yc = yc,
54+
i = i + 1
55+
)
56+
else {
57+
i
58+
}
59+
}
60+
61+
//render set
62+
val pixels = (for {
63+
x <- 0 until width
64+
y <- 0 until height
65+
} yield (x,y)).par.map {
66+
case (x,y) => buildPixel(x,y)
67+
}
68+
69+
//build javaFX rectangle
70+
val rectangles = pixels.map {
71+
case p: Pixel => new Rectangle() {
72+
x = p.x
73+
y = p.y
74+
width = 1
75+
height = 1
76+
fill = Color.gray(p.gray)
77+
}
78+
}
79+
80+
val pane = new Pane {
81+
content = rectangles.toList
82+
}
83+
84+
//build scene
85+
stage = new JFXApp.PrimaryStage {
86+
title.value = "Ch5 Ex3"
87+
scene = new Scene {
88+
fill = Color.gray(1)
89+
content = pane
90+
}
91+
}
92+
93+
stage.setHeight(width)
94+
stage.setWidth(height)
495

596
}

0 commit comments

Comments
 (0)