module one import StdEnv read :: *File -> [Instr] read f # (l, f) = freadline f | l.[size l - 1] <> '\n' = [] = [toInstr [c\\c<-:l | c <> '\n']:read f] where toInstr ['nop ':rs] = Nop (toInt (toString rs)) toInstr ['acc ':rs] = Acc (toInt (toString rs)) toInstr ['jmp ':rs] = Jmp (toInt (toString rs)) :: Instr = Nop Int | Acc Int | Jmp Int Start w # (io, w) = stdio w # instr = read io # instr = {c\\c<-instr} = (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 interpret :: {Instr} -> (Int, Bool) interpret instr = int [] 0 0 where int vis pc acc | pc >= size instr = (acc, True) | isMember pc vis = (acc, False) = case instr.[pc] of Nop _ = int [pc:vis] (1 + pc) acc Acc i = int [pc:vis] (1 + pc) (i + acc) Jmp i = int [pc:vis] (i + pc) acc