1. val C = io.Source.fromFile("input").getLines.toList
  2. def parseMask(m: String) = {
  3. val oneIndexes = m.zipWithIndex.filter(_._1 == '1').map(x => 35L - x._2).toList
  4. val xIndexes = m.zipWithIndex.filter(_._1 == 'X').map(x => 35L - x._2).toList
  5. (oneIndexes, xIndexes)
  6. }
  7. def flipBitAtIndex(cur: Long, mIndexBit: (Long, Long)): Long = {
  8. val (mIdx, bitFlip) = mIndexBit
  9. bitFlip match {
  10. case 1L cur | (1L << mIdx)
  11. case 0L cur & ~(1L << mIdx)
  12. }
  13. }
  14. def applyMaskOnXIndexes(mIndex: Long, xIndexes: List[Long], mask: Long): Long = {
  15. // Flip X Indexes into 1 and 0 according to mask
  16. xIndexes.zipWithIndex.map {
  17. case (v, idx) v ((mask & (1L << idx)) >> idx)
  18. }
  19. // Apply it now to mIndex
  20. .foldLeft(mIndex)(flipBitAtIndex)
  21. }
  22. def expandMemoryIndexes(oneIndexes: List[Long], xIndexes: List[Long], index: Long) = {
  23. // Turn on all oneIndexes.
  24. var maskedIndex = oneIndexes.map(idx (idx, 1L)).foldLeft(index)(flipBitAtIndex)
  25. // Turn off all xIndexes
  26. maskedIndex = xIndexes.map(idx (idx, 0L)).foldLeft(maskedIndex)(flipBitAtIndex)
  27. var expandedIndexes: List[Long] = Nil
  28. // We iterate on how many Xes we have. 5 X? 2^5 masks iterated
  29. for (mask 0 until 1 << xIndexes.length) {
  30. expandedIndexes = applyMaskOnXIndexes(maskedIndex, xIndexes, mask) :: expandedIndexes
  31. }
  32. expandedIndexes
  33. }
  34. var oneIndexes = List[Long]()
  35. var xIndexes = List[Long]()
  36. var memory = scala.collection.mutable.Map[Long, Long]()
  37. C.foreach { line =>
  38. line.split(" = ") match {
  39. case Array("mask", maskString)
  40. val (ones, exes) = parseMask(maskString)
  41. oneIndexes = ones
  42. xIndexes = exes
  43. case Array(memCmd, memValue)
  44. val index = memCmd.substring(4, memCmd.length - 1).toLong
  45. expandMemoryIndexes(oneIndexes, xIndexes, index).foreach { idx =>
  46. memory(idx) = memValue.toLong
  47. }
  48. }
  49. }
  50. println(memory.values.sum)

Day 14 2