         [ values ] map [ 0 [ length + ] accumulate nip ] [ ] bi zip
     ] [ length f <array> ] bi
     [ '[ first2 [ _ set-nth ] with each ] each ] keep ;
-

: normalized-histogram ( seq -- alist )
    [ histogram ] [ length ] bi '[ _ / ] assoc-map ;

: collect-pairs ( seq quot: ( x -- v k ) -- hashtable )
    [ push-at ] sequence>hashtable ; inline

: collect-by ( seq quot: ( x -- x' ) -- hashtable )
    [ dup ] prepose collect-pairs ; inline

: mode ( seq -- x )
    histogram >alist


<PRIVATE

: (sequence>assoc) ( seq map-quot insert-quot assoc -- assoc )
    [ swap curry compose each-index ] keep ; inline

PRIVATE>

: sequence>assoc! ( assoc seq map-quot: ( x -- ..y ) insert-quot: ( ..y index assoc -- ) -- assoc )
    4 nrot (sequence>assoc) ; inline

: sequence>assoc ( seq map-quot insert-quot exemplar -- assoc )
    clone (sequence>assoc) ; inline

: sequence>hashtable ( seq map-quot insert-quot -- hashtable )
    H{ } sequence>assoc ; inline

: histogram! ( hashtable seq -- hashtable )
    [ ] [ nip inc-at ] sequence>assoc! ;

: histogram-by ( seq quot: ( x -- bin ) -- hashtable )
    [ nip inc-at ] sequence>hashtable ; inline

: histogram-index-by ( seq quot: ( x -- bin ) -- hashtable )
    [ inc-at ] sequence>hashtable ; inline

: histogram ( seq -- hashtable )
