Paste: AoC Day 10

Author: CapitalEx
Mode: factor
Date: Sat, 10 Dec 2022 16:57:35
Plain Text |
USING: accessors arrays combinators.short-circuit
combinators.smart grouping io io.backend io.encodings.utf8
io.files kernel math math.parser models multiline peg.ebnf
ranges sequences ;
FROM: models => change-model ;
IN: advent-of-code.day-10

: get-input-one ( -- seq )
    "vocab:advent-of-code/day-10/_input/one.txt" 
        normalize-path utf8 file-contents ;

: [-1..+1] ( n -- range )
    [ 1 - ] [ 1 + ] bi [a..b] ;

TUPLE: addx value ;
C: <addx> addx

TUPLE: noop ;
C: <noop> noop

EBNF: parse-input [=[
    number = ("-"? [0-9]+)   => [[ "" join dec> ]]
    addx   = "addx "~ number => [[ <addx> ]]
    noop   = "noop"~         => [[ <noop> ]]
    instr  = (addx | noop) ("\n"?)~
    rule   = instr*
]=]

! Build the device
TUPLE: cpu tick 
    { rx  fixnum initial: 1 } 
    { acc fixnum initial: 0 } ;

: <cpu> ( -- cpu )
    \ cpu new 0 <model> >>tick ;

TUPLE: screen pixels 
    { cursor fixnum initial: 0 } ;

: <screen> ( -- screen )
    \ screen new V{ } clone >>pixels ;


TUPLE: device program cpu screen ;
: connect-cpu ( device --  ) 
    [ cpu>> ] [ cpu>> tick>> ] bi add-connection ;

: connect-screen ( device -- )
    [ screen>> ] [ cpu>> tick>> ] bi add-connection ;

: <device> ( -- device )
    \ device new
        <cpu>    >>cpu
        <screen> >>screen
    [ connect-cpu ] [ connect-screen ] [  ] tri ;


! Showing the solutions
: show-screen. ( deivce -- )
    screen>> pixels>> "" join 40 group "\n" join print ;

: show-acc. ( device -- )
    cpu>> acc>> >dec print ;


! Updating the CPU
: ticks ( cpu -- n )
    tick>> value>> ;

: twentieth-tick? ( cpu -- ? )
    ticks 20 = ;

: fourty-ticks? ( cpu -- ? )
    ticks 20 - 40 rem zero? ;

: strength ( cpu -- n )
    [ rx>> ] [ ticks ] bi * ;

: track-rx ( cpu -- )
    dup [ swap strength + ] change-acc drop ;

: track? ( cpu -- ? )
    { [ twentieth-tick? ] [ fourty-ticks? ] } 1|| ;

M: cpu model-changed
    nip [ track? ] [ track-rx ] smart-when* ;

! Update the screen

: pixel-on? ( cpu screen -- ? )
    [ rx>> [-1..+1] ] [ cursor>> ] bi* swap member? ;

: on! ( screen -- )
    pixels>> "#" suffix! drop ;

: off! ( screen -- )
    pixels>> "." suffix! drop ;

: draw! ( screen ? -- )
    [ on! ] [ off! ] if ;

: move-cursor! ( screen -- )
    [ 1 + 40 rem ] change-cursor drop ;

M: screen model-changed
    [ connections>> first ] dip 
        [ tuck pixel-on? draw!  ]
        [ nip move-cursor! ] 2bi ;

! Running the program
: tick! ( cpu -- cpu )
    dup tick>> [ 1 + ] change-model ;

: addx! ( n cpu -- cpu )
    tick! tick! [ + ] change-rx ;

: run-instruction ( cpu instruction -- cpu )
    [ addx? ] [ value>> swap addx! ] [ tick! ] smart-if* ;

: run-program ( program -- device )
    <device> [ cpu>> [ run-instruction ] reduce drop ] keep ;

! Solve the problem
: solve. ( -- )
    get-input-one parse-input run-program 
        [ show-acc. ]
        [ show-screen. ] bi ;

New Annotation

Summary:
Author:
Mode:
Body: