Inhaltsverzeichnis

Aufgabe 1

Aufgabe 2

Block 1
new CyclicBarrier(nThreads);
Block 2
// Lösung mit einzelnen Thread-Objekten auch denkbar
ExecutorService es = Executors.newFixedThreadPool(nThreads);
for (int i = 0; i < nThreads; i++) {
  GRunnable gr = new GRunnable(i, nThreads, barrier);
  es.execute(gr),
}
Block 3
es.shutdown();
es.awaitTermination(60, TimeUnit.SECONDS);
Block 4
for (int col = id; col < size; col += nThreads) {
  for (int row = 0; row < size; row++) {
    dest[row][col] = step(row, col);
  }
}
Block 5
if (barrier.await() == 0) { // alternativ auch barrier.await() und dann if (id == 0)
  swap();
}
barrier.await();
Block 6
// Beabsichtigt leer gelassen
// Falls in 1 new CyclicBarrier(nThreads + 1) und im Mainthread in 3 mittels barrier.await() synchronisiert wird, muss hier auch ebarrier.await() stehen.

Aufgabe 3

Aufgabe 4

Aufgabe 5

def aliveNeighbors: (Cell => List[Cell]) => Cell => Int =
  f => cell => f(cell).count(_.alive)
 
def tick: Field => Field = field => field.map(cell => aliveNeighbors(neighbors(field))(cell) match {
  case n i f(n < 2 || n > 3) => Cell(cell.x, cell.y, false)
  case 3 => Cell(cell.x, cell.y, true)
  case default => cell
})
 
def game: Field => Stream[Field] = f => f #:: game(tick(f))

Aufgabe 6

def first: List[Solution] => Solution = sols =>
  // alternativ sols.foldLeft(Nil: List[Transition)...
  sols.foldLeft(List[Transition]())((acc, cur) => acc match {
    case Nil => cur
    case default => acc
  })
case (s::ss, sol) if s == end => sol
case (s::ss, sol) if ss.contains(s) => Nil      
case (s::ss, sol) => {
  val next = passage(s)
  first(next.map({
    case (nextState, nextTransition) => helper(nextState::s::ss, sol ::: List(nextTransition))
  }))
}