스칼라의 렌즈 라이브러리 인 monocle을 사용하여 코드가 출현함에 따라 day 12에 대한 코드를 리팩터링했습니다. 함께 Map.withDefaultValue
를 사용하는 방법이있다 : 스칼라에서 단안 문자로 보일러 플레이트를 줄이는 방법
type Register = String
type Mem = Map[String, Int]
@Lenses
case class State(mem: Mem, pointer: Int)
def processInstruction(instructions: Seq[Instruction]): State => State = { s =>
(instructions(s.pointer) match {
case Inc(r) =>
State.pointer.modify(_ + 1) andThen (State.mem composeLens at(r)).modify(_.map(_ + 1))
case Dec(r) =>
State.pointer.modify(_ + 1) andThen (State.mem composeLens at(r)).modify(_.map(_ - 1))
case CpyInt(v, to) =>
State.pointer.modify(_ + 1) andThen (State.mem composeLens at(to)).set(Some(v))
case CpyReg(from, to) =>
State.pointer.modify(_ + 1) andThen (State.mem composeLens at(to)).set(Some(s.mem(from)))
case Jnz(r, v) => if (r != "1" && s.mem(r) == 0)
State.pointer.modify(_ + 1)
else
State.pointer.modify(_ + v)
}).apply(s)
}
을 그리고 여기 또 다른 각 필드
def processInstruction2(instructions: Seq[Instruction]): State => State = { s =>
val ptr = instructions(s.pointer) match {
case Jnz(r, v) if !(r != "1" && s.mem(r) == 0) => State.pointer.modify(_ + v)
case _ => State.pointer.modify(_ + 1)
}
val mem = instructions(s.pointer) match {
case Inc(r) => (State.mem composeLens at(r)).modify(_.map(_ + 1))
case Dec(r) => (State.mem composeLens at(r)).modify(_.map(_ - 1))
case CpyInt(v, to) => (State.mem composeLens at(to)).set(Some(v))
case CpyReg(from, to) => (State.mem composeLens at(to)).set(Some(s.mem(from)))
case _ => identity[State]
}
(ptr andThen mem)(s)
}
하나 개 더 질문의 수정을 분리, 시도이다 단안경?
전체 코드
은 여기에 있습니다 : https://gist.github.com/YannMoisan/b8ba25afc041d88706545527d9ec1988
내가 대신 index''사용합니다 : 그래서 대신
foldLeft
의 우리는 포인터 다음 명령을 추출하는 몇 가지 재귀 함수가 필요합니다 map의 값을 수정하고자 할 때'at '를 사용한다. (State.mem composeLens at (r)). 수정 (_. map (_ + 1)) ' –