richashworth
12/16/2015 - 3:43 PM

clapping.scala

abstract sealed class Beat
case object Rest extends Beat
case object Note extends Beat
case class Note(pitch: Int, duration: Int) extends Beat

case class Pattern(beats: Seq[Beat])

def formatBeat(b: Beat): String = b match {
  case Rest => " _ "
  case Note => " X "
}

def play(p: Pattern): String = p.beats.map(b => formatBeat(b)) mkString ""

def phaseShift(pattern: Pattern, degrees: Int): Pattern = {
  val beats = pattern.beats
  val shiftAmount = degrees % beats.length
  new Pattern(beats.drop(shiftAmount) ++ beats.take(shiftAmount))
}

def phaseVariations(originalPattern: Pattern): Seq[Pattern] = {
  val patternsRange = (1 until originalPattern.beats.length)
  patternsRange.map(i => phaseShift(originalPattern, i))
}

def drawPattern(p: Pattern): Unit = println(play(p))

val clappingMusicPhrase = Pattern(Seq(Note, Note, Rest, Note, Note, Note, Rest, Note, Rest, Note, Note))
val clappingMusicPartTwo = clappingMusicPhrase +: phaseVariations(clappingMusicPhrase)
val clappingMusicPartOne = Seq.fill(clappingMusicPartTwo.length)(clappingMusicPhrase)

val clappingMusic: Seq[(Pattern, Pattern)] = clappingMusicPartOne.zip(clappingMusicPartTwo)
clappingMusic.foreach((a) => {
  drawPattern(a._1)
  drawPattern(a._2)
  println(Seq.fill(a._1.beats.length)("---") mkString (""))
})