cmat ← {gap←1 {max←⎕pw}} ##.cols items      ⍝ Multi-column display.

Sometimes it's easier to peruse an alphabetic list of items if they are arranged
vertically in columns (where typically, the last  column  will  be  incomplete).
[cols]  returns a multi-column character-matrix format of the items in its right
argument.

[items]  may  be a vector or a matrix. In the latter case, _rows_ of the matrix,
with trailing blanks removed, are taken as the items of the list.

Optional  left  arguments  [gap] (default 1) and [max] (default ⎕pw) specify the
inter-column-gap and maximum "print width" of the display respectively.

If  any  of  the items are wider than [max], the result is a single column, with
longer items truncated to [max] characters.

Cols is similar to the Unix shell commmand "c -v".

        1 20 cols ⍳26           ⍝ width ≤ 20-column format of vector.
    1 5  9 13 17 21 25
    2 6 10 14 18 22 26
    3 7 11 15 19 23
    4 8 12 16 20 24

        0 8 cols ⎕a             ⍝ width ≤ 8-column format of vector.
    AEIMQUY
    BFJNRVZ
    CGKOSW
    DHLPTX

        cols ⎕nl 4              ⍝ width ≤ ⎕pw-column format of char matrix.
    Cut      ascana  bt     do   fnarray lof   of   ratsum   sam   time  while
    UndoRedo at      case   each foldl   logic or   ravt     saw   traj
    _fk      avl     cf     else for     ltrav perv redblack sbst  trav
    acc      bags    cond   file invr    mdf   pow  repl     splay until
    and      big     cxdraw fk   kcell   memo  pred roman    tc    vof
    ascan    bsearch dft    fk_  limit   nats  rats rows     ticks vwise

Technical note:

There  is  a circular problem in deciding the optimal number of columns in which
to arrange our vector:  until the columns are arranged, we don't know which will
be the widest item in each column and so how wide the column as a whole will be;
and  until  we  know the width of each column, we don't know how many columns to
use.

Here  is  an example of a vector whose 2-column arrangement is wider than its 3-
column arrangement:

    vec ← 1 1 1000000 1000000 1 1

    ⍉2 3⍴vec        ⍝ 2 cols → width 15.
      1 1000000
      1       1
1000000       1

    ⍉3 2⍴vec        ⍝ 3 cols → width 11.
1 1000000 1
1 1000000 1

For  this  reason, it is not easy to "home in" on an optimal solution using, for
example, a binary search (→bsearch←) technique. Instead, we search one column at
a time. We could equally well search a row at a time, but for large lists, where
performance  might  be a consideration, the number of rows would, typically, far
exceed the maximum "print width".

The  not-very-subtle solution adopted here is to start with the maximum possible
number  of columns and to keep reducing this number until the gap-separated col-
umns  would  fit within the required width. We don't need to use the items them-
selves for this exploration; a vector of their lengths will suffice.

Inner  function  "maxcols"  calculates the maximum number of columns. It employs
a small optimisation, which allows us to avoid some of the calculation.  For ex-
ample,  trying  to  arrange  9 items down 4 columns is infeasible because 2 rows
would require 5 columns and 3 rows would need only 3.

Given  "ni",  the  number  of  items and ⍵, the number of columns to attempt, we
calculate the implied number of rows together with the "excess" number of unused
rows in the final, right-most, column. Notice the use of APL's encode "⊤" funct-
ion with a negative argument:

    nr xs←|0 ⍵⊤-ni              ⍝ number of rows and excess.
    xs≥nr:∇ ⍵-1                 ⍝ one or more empty columns: ignore.

For example, to see if we can arrange 9 items along 4 rows, we might first think
to code:

    0 4⊤9       ⍝ 2 complete rows, remainder 1 item.
2 1

But this is not quite right; we need to know how many rows (complete or not) are
occupied, together with how many rows would be left unoccupied in the final col-
umn(s).  If  the  excess is equal to or greater than the number of rows, then we
can  ignore  this  (⍵-columns)  case as it is identical to a smaller value of ⍵,
which we will encounter later. Instead, we code:

    |0 4⊤-9     ⍝ 3 used rows, with 3 free rows in the final column (no good).
3 3

... representing an infeasible arrangement, which may be ignored.

Examples:

    cols ⍳123               ⍝ default multi-column display of vector.
1  6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 86 91  96 101 106 111 116 121
2  7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 82 87 92  97 102 107 112 117 122
3  8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 83 88 93  98 103 108 113 118 123
4  9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 84 89 94  99 104 109 114 119
5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120

    2 cols ⍳123             ⍝ ..    ..  with 2-blank inter-column gap.
1   8  15  22  29  36  43  50  57  64  71  78  85  92   99  106  113  120
2   9  16  23  30  37  44  51  58  65  72  79  86  93  100  107  114  121
3  10  17  24  31  38  45  52  59  66  73  80  87  94  101  108  115  122
4  11  18  25  32  39  46  53  60  67  74  81  88  95  102  109  116  123
5  12  19  26  33  40  47  54  61  68  75  82  89  96  103  110  117
6  13  20  27  34  41  48  55  62  69  76  83  90  97  104  111  118
7  14  21  28  35  42  49  56  63  70  77  84  91  98  105  112  119

    2 50 cols ⍳123          ⍝ ..    ..  restricted to a print-width of 50.
 1  12  23  34  45  56  67  78  89  100  111  122
 2  13  24  35  46  57  68  79  90  101  112  123
 3  14  25  36  47  58  69  80  91  102  113
 4  15  26  37  48  59  70  81  92  103  114
 5  16  27  38  49  60  71  82  93  104  115
 6  17  28  39  50  61  72  83  94  105  116
 7  18  29  40  51  62  73  84  95  106  117
 8  19  30  41  52  63  74  85  96  107  118
 9  20  31  42  53  64  75  86  97  108  119
10  21  32  43  54  65  76  87  98  109  120
11  22  33  44  55  66  77  88  99  110  121

    cols ⎕nl 3 4            ⍝ multi-column display of character matrix.
Cholesky  bt       draw         gperm   m91     packZ    rows      trav
Cut       cache    dscan        hex     mac     parse    rr        tree
Depth     cal      dsp          hexdump match   path     sam       turtle
H         case     dtb          hexf    mayan   pco      saw       tview
NormRand  cf       dxb          htx     maze    perv     sbst      type
UndoRedo  cfract   each         in      mdf     phinary  scc       ucase
X         chksum   easter       index   mean    pmat     search    unify
_fk       cmat     efract       inslink memo    polar    segs      uns
acc       cmpx     eis          insnode mmind   pow      select    until
adic      cols     else         int     mns     pred     shannon   unwrap
alget     colsum   enlist       invr    morse   profile  sieve     up
alpop     compidn  esh          iotag   mp3     putfile  span      utf8get
alpush    cond     exit         isdfn   mscan   queens   splay     utf8put
alset     cxdraw   externs      joy     mtrim   quzzle   squeeze   vof
alt       dab      f32          just    nats    range    ss        von
ambiv     date     factorial    justify ncpath  rational ssmat     vtol
and       days     factors      k6174   nicediv rats     ssword    vtrim
apportion deb      fibonacci    kball   nlines  ratsum   stamps    vwise
ary       dec      file         kcell   nspack  ravt     stdists   wcost
ascan     defs     filefind     kind    of      redblack stpath    while
ascana    det      find         kk      or      refmatch stpaths   wmst
assign    dfspan   fix          ksphere osc     refmt    subs      words
at        dft      fk           kt      pack    refpath  subvec    wpath
attrib    dice     fk_          lcase   pack4   refs     sudoku    wrap
avl       din      fnarray      le      packB   refws    tc        wrapnote
baby      disp     fndiff       life    packD   remlink  test      wsdiff
bags      display  fnrefs       limit   packH   remnode  tfmt      wsmerge
base64    displayr fnrepl       lisp    packN   rep      ticks     wspan
bayes     displays foldl        list    packQ   repl     time      wsreq
bf        dist     for          lof     packR   ripple   timestamp xpower
big       dlb      from         logic   packS   rmcm     tnest     xrefs
birthday  dmb      gauss_jordan lsys    packT   roman    to        xtabs
box       do       gcd          ltov    packU   root     tokens    xtimes
bsearch   dots     getfile      ltrav   packX   roots    traj

    class←{' '~⍨⍵,'.',⍕⎕nc ⍵}   ⍝ name classification.

    class¨ 'display' 'memo'     ⍝ fns.3 ops.4.
 display.3  memo.4

    cols class¨ ↓⎕nl 3 4        ⍝ classified names.
Cholesky.3  cfract.3   else.4         just.3    of.4       refws.3   timestamp.3
Cut.4       chksum.3   enlist.3       justify.3 or.4       remlink.3 tnest.3
Depth.4     class.3    esh.3          k6174.3   osc.3      remnode.3 to.3
H.4         cmat.3     exit.3         kball.3   pack.3     rep.3     tokens.3
NormRand.3  cmpx.3     externs.3      kcell.4   pack4.3    repl.4    traj.4
UndoRedo.4  cols.3     f32.3          kind.3    packB.3    ripple.3  trav.4
X.3         colsum.3   factorial.3    kk.3      packD.3    rmcm.3    tree.3
_fk.4       compidn.3  factors.3      ksphere.3 packH.3    roman.4   turtle.3
acc.4       cond.4     fibonacci.3    kt.3      packN.3    root.3    tview.3
adic.3      cxdraw.4   file.4         lcase.3   packQ.3    roots.3   type.3
alget.3     dab.3      filefind.3     le.3      packR.3    rows.4    ucase.3
alpop.3     date.3     find.3         life.3    packS.3    rr.3      unify.3
alpush.3    days.3     fix.3          limit.4   packT.3    sam.4     uns.3
alset.3     deb.3      fk.4           lisp.3    packU.3    saw.4     until.4
alt.4       dec.3      fk_.4          list.3    packX.3    sbst.4    unwrap.3
ambiv.3     defs.3     fnarray.4      lof.4     packZ.3    scc.3     up.3
and.4       det.3      fndiff.3       logic.4   parse.3    search.3  utf8get.3
apportion.3 dfspan.3   fnrefs.3       lsys.3    path.3     segs.3    utf8put.3
ary.3       dft.4      fnrepl.3       ltov.3    pco.3      select.3  vof.4
ascan.4     dice.3     foldl.4        ltrav.4   perv.4     shannon.3 von.3
ascana.4    din.3      for.4          m91.3     phinary.3  sieve.3   vtol.3
assign.3    disp.3     from.3         mac.3     pmat.3     span.3    vtrim.3
at.4        display.3  gauss_jordan.3 match.3   polar.3    splay.4   vwise.4
attrib.3    displayr.3 gcd.3          mayan.3   pow.4      squeeze.3 wcost.3
avl.4       displays.3 getfile.3      maze.3    pred.4     ss.3      while.4
baby.3      dist.3     gperm.3        mdf.4     profile.4  ssmat.3   wmst.3
bags.4      dlb.3      hex.3          mean.3    putfile.3  ssword.3  words.3
base64.3    dmb.3      hexdump.3      memo.4    queens.3   stamps.3  wpath.3
bayes.3     do.4       hexf.3         mmind.3   quzzle.3   stdists.3 wrap.3
bf.3        dots.3     htx.3          mns.3     range.3    stpath.3  wrapnote.3
big.4       draw.3     in.3           morse.3   rational.3 stpaths.3 wsdiff.3
birthday.3  dscan.3    index.3        mp3.3     rats.4     subs.3    wsmerge.3
box.3       dsp.3      inslink.3      mscan.3   ratsum.4   subvec.3  wspan.3
bsearch.4   dtb.3      insnode.3      mtrim.3   ravt.4     sudoku.3  wsreq.3
bt.4        dxb.3      int.3          nats.4    redblack.4 tc.4      xpower.3
cache.3     each.4     invr.4         ncpath.3  refmatch.3 test.3    xrefs.3
cal.3       easter.3   iotag.3        nicediv.3 refmt.3    tfmt.3    xtabs.3
case.4      efract.3   isdfn.3        nlines.3  refpath.3  ticks.4   xtimes.3
cf.4        eis.3      joy.3          nspack.3  refs.3     time.4

    ∪{1 ⍵ cols ⍳10}¨0 to 20             ⍝ all possible wrappings of 1 .. 10.
┌┬─┬──┬────┬──────┬────────┬──────────┬────────────────────┐
││ │ 1│1  6│1 5  9│1 4 7 10│1 3 5 7  9│1 2 3 4 5 6 7 8 9 10│
││ │ 2│2  7│2 6 10│2 5 8   │2 4 6 8 10│                    │
││ │ 3│3  8│3 7   │3 6 9   │          │                    │
││ │ 4│4  9│4 8   │        │          │                    │
││ │ 5│5 10│      │        │          │                    │
││ │ 6│    │      │        │          │                    │
││ │ 7│    │      │        │          │                    │
││ │ 8│    │      │        │          │                    │
││ │ 9│    │      │        │          │                    │
││1│10│    │      │        │          │                    │
└┴─┴──┴────┴──────┴────────┴──────────┴────────────────────┘

    1 12 cols 2/10*0 6 0        ⍝ tricky case.
1 1000000 1
1 1000000 1

See also: wrap tree

Back to: contents

Back to: Workspaces