Paste: AOC day 8

Author: chunes
Mode: factor
Date: Tue, 8 Dec 2020 15:27:43
Plain Text |
USING: arrays assocs combinators io.encodings.ascii io.files
kernel literals math math.parser namespaces prettyprint qw
sequences sets splitting ;
FROM: namespaces => set ;
IN: aoc.2020.08

CONSTANT: instructions $[
    "input.txt" ascii file-lines
    [ " " split1 string>number swap 2array ] map
]

CONSTANT: seen $[ HS{ } clone ]     ! Which indices in the instructions have we visited?

SYMBOL: iptr                        ! Instruction pointer; index of the current instruction.

SYMBOL: acc

: execute-instruction ( -- )
    iptr get instructions nth first2
    {
        { "acc" [ acc +@ iptr inc ] }
        { "jmp" [ iptr +@ ] }
        [ 2drop iptr inc ]  ! nop
    } case ;

: reset ( -- ) 0 iptr set 0 acc set seen clear-set ;
: visit ( -- ) iptr get seen adjoin ;
: step ( -- ) visit execute-instruction ;
: loop? ( -- ? ) iptr get seen in? ;
: halted? ( -- ? ) iptr get instructions length >= ;
: run ( -- ? ) reset [ loop? halted? or ] [ step ] until halted? ;
: part1 ( -- ) run drop acc get . ;


! ~~===={[ PART 2 ]}====~~

: invert-instruction ( index -- )
    instructions
    [ first2 "jmp" = "nop" "jmp" ? 2array ] change-nth ;

: invertible? ( seq -- ? ) second qw{ jmp nop } member? ;

: invertible ( -- indices )
    instructions <enumerated>
    [ second invertible? ] filter keys ;

: attempt-repair ( index -- finished? )
    [ invert-instruction run ] [ invert-instruction ] bi ;

: part2 ( -- ) invertible [ attempt-repair ] find 2drop acc get . ;

New Annotation

Summary:
Author:
Mode:
Body: