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