= (one instr, two instr)
one = fst o interpret
-two = hd o filter snd o map interpret o nopjump 0
-
-nopjump :: Int {Instr} -> [{Instr}]
-nopjump pc is
- | pc == size is = []
- = case is.[pc] of
- Nop i = [update {i\\i<-:is} pc (Jmp i):nopjump (pc+1) is]
- Jmp i = [update {i\\i<-:is} pc (Nop i):nopjump (pc+1) is]
- _ = nopjump (pc+1) is
+two is = [ acc \\i<-:is & pc<-[0..]
+ , let (acc, t) = interpret (update {i\\i<-:is} pc (swapnop i))
+ | t]
+where
+ swapnop (Nop i) = Jmp i
+ swapnop (Jmp i) = Nop i
+ swapnop i = i
interpret :: {Instr} -> (Int, Bool)
interpret instr = int [] 0 0
where
int vis pc acc
- | pc >= size instr = (acc, True)
- | isMember pc vis = (acc, False)
+ | pc >= size instr = (acc, True) // terminated
+ | isMember pc vis = (acc, False) // inf loop
= case instr.[pc] of
Nop _ = int [pc:vis] (1 + pc) acc
Acc i = int [pc:vis] (1 + pc) (i + acc)