math.combinatorics sequences ; IN: rosetta-code.two-sum DEFER: (two-sum) TUPLE: helper sum seq index hash ; : ( sum seq -- helper ) \ helper new swap >>seq swap >>sum 0 >>index H{ } clone >>hash ; : no-sum ( helper -- empty ) drop { } ; : in-bounds? ( helper -- ? ) [ index>> ] [ seq>> length ] bi < ; : next-sum ( helper -- pair ) dup in-bounds? [ (two-sum) ] [ no-sum ] if ; : next-index ( helper -- helper ) [ 1 + ] change-index ; : remember-item ( helper -- helper ) dup [ hash>> ] [ index>> dup ] [ seq>> ] tri nth swap set-of drop ; : result ( helper index -- helper ) swap index>> 2array ; : find-compliment-index ( helper -- helper index/f ) dup [ sum>> ] [ index>> ] [ seq>> nth - ] [ ] quad hash>> at ; : (two-sum) ( helper -- pair ) remember-item find-compliment-index [ result ] [ next-index next-sum ] if* ; : two-sum ( sum seq -- pair )