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 (""))
})