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

Sometimes  it's easier to peruse a 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.
    _fk    bsearch dft     foldl   key   mdf   pow      roman squad vof
    acc    bt      do      for     lex   memo  pred     rows  ticks vwise
    ascan  case    else    inverse limit merge rank     sam   time  while
    ascana cf      file    invr    lof   nats  rats     saw   trace UndoRedo
    avl    cond    fk_     invs    logic of    ratsum   sbst  traj
    big    cx      fnarray kcell   ltrav perv  redblack splay until

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 50 columns.
 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.
_fk     cols      easter       insnode mns     polar    sieve     until
acc     colsum    efract       int     morse   popnode  span      unwrap
adic    cond      else         inverse mp3     pow      splay     up
alext   cx        enlist       invr    mscan   pred     squad     utf8
alrem   cxdraw    enss         invs    mtrim   putfile  squeeze   utf8get
alrems  cxsh      esh          iotag   nats    queens   ss        utf8put
alval   dab       exit         isdfn   nc      quzzle   ssmat     vof
alvals  date      factorial    just    ncpath  range    ssword    von
ambiv   days      factors      justify nicediv rank     stamps    vtol
and     dft       fibonacci    kball   nlines  rational stdists   vtrim
ary     deb       file         kcell   nspack  rats     stpath    vwise
ascan   dec       filefind     key     of      ratsum   stpaths   wcost
ascana  defn      find         ksphere or      redblack subs      while
assign  det       fix          kt      osc     refmatch subvec    wmst
attrib  dfnscode  fk_          lcase   pack    refmt    sudoku    words
avl     dfnsnotes fnarray      lex     packB   refs     test      wpath
baby    dfspan    fndiff       life    packD   refws    tfmt      wrap
bf      dice      fnrefs       limit   packH   remlink  ticks     wrapnote
big     disp      fnrepl       list    packN   remnode  time      wsdiff
box     display   foldl        lof     packQ   rep      timestamp wsmerge
bsearch displayr  for          logic   packR   ripple   tnest     wspan
bt      displays  from         ltov    packS   rmcm     to        wsreq
cache   dlb       gauss_jordan ltrav   packT   roman    tokens    xhtml
cal     dmb       gcd          mac     packU   root     trace     xrefs
case    do        getfile      mayan   packX   roots    traj      xtabs
cf      dots      hex          maze    packZ   rows     tree      xws
cfract  draw      hexdump      mdf     path    sam      tview     UndoRedo
chksum  dscan     hexf         mean    pco     saw      type
class   dtb       htx          memo    perv    sbst     ucase
cmat    dxb       index        merge   phinary search   unify
cmpx    each      inslink      mmind   pmat    select   uns

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

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

    cols class¨ ↓⎕nl 3 4        ⍝ classified names.
_fk.4     cxdraw.3    factors.3      ksphere.3 packD.3    ripple.3    traj.4
acc.4     cxsh.3      fibonacci.3    kt.3      packH.3    rmcm.3      tree.3
adic.3    dab.3       file.4         lcase.3   packN.3    roman.4     tview.3
alext.3   date.3      filefind.3     lex.4     packQ.3    root.3      type.3
alrem.3   days.3      find.3         life.3    packR.3    roots.3     ucase.3
alrems.3  dft.4       fix.3          limit.4   packS.3    rows.4      unify.3
alval.3   deb.3       fk_.4          list.3    packT.3    sam.4       uns.3
alvals.3  dec.3       fnarray.4      lof.4     packU.3    saw.4       until.4
ambiv.3   defn.3      fndiff.3       logic.4   packX.3    sbst.4      unwrap.3
and.4     det.3       fnrefs.3       ltov.3    packZ.3    search.3    up.3
ary.3     dfnscode.3  fnrepl.3       ltrav.4   path.3     select.3    utf8.3
ascan.4   dfnsnotes.3 foldl.4        mac.3     pco.3      sieve.3     utf8get.3
ascana.4  dfspan.3    for.4          mayan.3   perv.4     span.3      utf8put.3
assign.3  dice.3      from.3         maze.3    phinary.3  splay.4     vof.4
attrib.3  disp.3      gauss_jordan.3 mdf.4     pmat.3     squad.4     von.3
avl.4     display.3   gcd.3          mean.3    polar.3    squeeze.3   vtol.3
baby.3    displayr.3  getfile.3      memo.4    popnode.3  ss.3        vtrim.3
bf.3      displays.3  hex.3          merge.4   pow.4      ssmat.3     vwise.4
big.4     dlb.3       hexdump.3      mmind.3   pred.4     ssword.3    wcost.3
box.3     dmb.3       hexf.3         mns.3     putfile.3  stamps.3    while.4
bsearch.4 do.4        htx.3          morse.3   queens.3   stdists.3   wmst.3
bt.4      dots.3      index.3        mp3.3     quzzle.3   stpath.3    words.3
cache.3   draw.3      inslink.3      mscan.3   range.3    stpaths.3   wpath.3
cal.3     dscan.3     insnode.3      mtrim.3   rank.4     subs.3      wrap.3
case.4    dtb.3       int.3          nats.4    rational.3 subvec.3    wrapnote.3
cf.4      dxb.3       inverse.4      nc.3      rats.4     sudoku.3    wsdiff.3
cfract.3  each.4      invr.4         ncpath.3  ratsum.4   test.3      wsmerge.3
chksum.3  easter.3    invs.4         nicediv.3 redblack.4 tfmt.3      wspan.3
class.3   efract.3    iotag.3        nlines.3  refmatch.3 ticks.4     wsreq.3
cmat.3    else.4      isdfn.3        nspack.3  refmt.3    time.4      xhtml.3
cmpx.3    enlist.3    just.3         of.4      refs.3     timestamp.3 xrefs.3
cols.3    enss.3      justify.3      or.4      refws.3    tnest.3     xtabs.3
colsum.3  esh.3       kball.3        osc.3     remlink.3  to.3        xws.3
cond.4    exit.3      kcell.4        pack.3    remnode.3  tokens.3    UndoRedo.4
cx.4      factorial.3 key.4          packB.3   rep.3      trace.4

    1 1 0 disp ∪{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

Back to: contents

Back to: Workspaces

Trouble seeing APL font?