--- /dev/null
- 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
+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
- | pc >= size instr = (acc, True)
- | isMember pc vis = (acc, False)
++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) // 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)
+ Jmp i = int [pc:vis] (i + pc) acc