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?