- val C = io.Source.fromFile("input").getLines.toList
- def parseMask(m: String) = {
- val oneIndexes = m.zipWithIndex.filter(_._1 == '1').map(x => 35L - x._2).toList
- val xIndexes = m.zipWithIndex.filter(_._1 == 'X').map(x => 35L - x._2).toList
- (oneIndexes, xIndexes)
- }
- def flipBitAtIndex(cur: Long, mIndexBit: (Long, Long)): Long = {
- val (mIdx, bitFlip) = mIndexBit
- bitFlip match {
- case 1L ⇒ cur | (1L << mIdx)
- case 0L ⇒ cur & ~(1L << mIdx)
- }
- }
- def applyMaskOnXIndexes(mIndex: Long, xIndexes: List[Long], mask: Long): Long = {
- // Flip X Indexes into 1 and 0 according to mask
- xIndexes.zipWithIndex.map {
- case (v, idx) ⇒ v → ((mask & (1L << idx)) >> idx)
- }
- // Apply it now to mIndex
- .foldLeft(mIndex)(flipBitAtIndex)
- }
- def expandMemoryIndexes(oneIndexes: List[Long], xIndexes: List[Long], index: Long) = {
- // Turn on all oneIndexes.
- var maskedIndex = oneIndexes.map(idx ⇒ (idx, 1L)).foldLeft(index)(flipBitAtIndex)
- // Turn off all xIndexes
- maskedIndex = xIndexes.map(idx ⇒ (idx, 0L)).foldLeft(maskedIndex)(flipBitAtIndex)
- var expandedIndexes: List[Long] = Nil
- // We iterate on how many Xes we have. 5 X? 2^5 masks iterated
- for (mask ← 0 until 1 << xIndexes.length) {
- expandedIndexes = applyMaskOnXIndexes(maskedIndex, xIndexes, mask) :: expandedIndexes
- }
- expandedIndexes
- }
- var oneIndexes = List[Long]()
- var xIndexes = List[Long]()
- var memory = scala.collection.mutable.Map[Long, Long]()
- C.foreach { line =>
- line.split(" = ") match {
- case Array("mask", maskString) ⇒
- val (ones, exes) = parseMask(maskString)
- oneIndexes = ones
- xIndexes = exes
- case Array(memCmd, memValue) ⇒
- val index = memCmd.substring(4, memCmd.length - 1).toLong
- expandMemoryIndexes(oneIndexes, xIndexes, index).foreach { idx =>
- memory(idx) = memValue.toLong
- }
- }
- }
- println(memory.values.sum)
Day 14 2