Paste: my version of multi dimensional arrays - two variants

Author: kobi (randy7)
Mode: factor
Date: Thu, 3 Jun 2010 21:37:14
Plain Text |
USING: accessors arrays assocs fry hashtables kernel math
math.order math.vectors sequences ;
IN: mdarray

! the first variant is based on an array, and has less overhead.
! use this when the entire shape will probably be filled. for example, a game board.

! NOTE: in positions, last one is the most specific (1d)

 TUPLE: multi1
    default-value
    { planes sequence } 
    { underlying array } ;

: <multi1> ( planes default-value -- mdarray )
    2dup
    [ product ] dip <array>
    multi1 new
    swap >>underlying
    swap >>default-value
    swap >>planes ;
    

! the second variant has more overhead, but isn't filled with empty values.
! for example, if you want to mark a route in a map, then only the route will take space.

TUPLE: multi2
    default-value
    { planes sequence }
    { cells hashtable } ;
  
: <multi2> ( planes default-value -- mdarray )
    multi2 new 
    swap >>default-value
    swap >>planes
    H{ } clone >>cells ;

: within? ( positions planes -- ? )    
    [ 1 -  0 swap between? ] 2all? ;

ERROR: not-within! positions planes ;
: ensure-within ( positions seq -- positions seq )
    2dup planes>> within? [ planes>> not-within! ] unless ;
    
M: multi2 set-nth ( elt positions seq -- )
    ensure-within cells>> set-at ;
    
M: multi2 nth ( positions seq -- cell/default )
    ensure-within
    [ cells>> at* ] [ default-value>> ] bi
    '[ drop _  ] unless ;
    

!     { 2 3 5 } => { 15 3 1 }
!     { 2 3 3 } => { 9  3 1 }

    
: muls-seq ( planes -- calc-seq ) 
    { 1 } swap rest [ over first * prefix ] each ;
    

: coord>index ( positions planes -- index )
    muls-seq v* sum ;
    
: (positions>index) ( positions seq -- index seq )
    [ planes>> coord>index ] [ underlying>> ] bi ;
    
M: multi1 nth ( positions seq -- cell )
    ensure-within (positions>index) nth ;
    
M: multi1 set-nth ( elt positions seq -- )
    ensure-within (positions>index) set-nth ;

New Annotation

Summary:
Author:
Mode:
Body: