# Flouring the loaf

Here’s a task that cries out for a simple solution: put a border round a matrix. My matrix is boolean and represents a QR code (yes, we’ll come to that) but its the same problem as, say, putting a 1px border on an image.

So lets examine it as wrapping a char matrix in spaces.
We’ll use `("LOAF";"loaf";"LOAF")`

as our loaf.

## Amend At

Our first strategy is to manipulate indexes, which is often an efficient approach in q. We make a larger blank matrix for the result and write the original matrix in the right place.

Start with the *shape* of the matrix; that is, count the rows and columns.
(Shape is a concept that q did not inherit from its ancestor APL, but is easy enough to calculate.)
We use the Zen monks for a point-free expression.

```
q)show LOAF:string`LOAF`loaf`LOAF
"LOAF"
"loaf"
"LOAF"
q)count each 1 first\LOAF / shape of LOAF
3 4
```

`2+3 4`

, i.e. `5 6`

, and here is our blank template:
```
q){n:2+count each 1 first\x; n#" "}LOAF
" "
" "
" "
" "
" "
```

`.'`

to map each item of `LOAF`

to a row-column pair in the result.
But it should be more efficient to raze `LOAF`

and use Amend At `@`

to map all its items to the vector `prd[n]#" "`

and then reshape it.
Something like
```
q){n:2+s:count each 1 first\x; n#@[prd[n]#" "; ??? ;:;raze x]}LOAF
" "
" LOAF "
" loaf "
" LOAF "
" "
```

`???`

is some expression that returns the target indices for the items of `LOAF`

.
Let’s start with an easy expression – wrong, but easy.
We’ll write the items of `LOAF`

into the first positions of the result.
```
q){n:2+s:count each 1 first\x; n#@[prd[n]#" ";til prd s;:;raze x]}LOAF
"LOAFlo"
"afLOAF"
" "
" "
" "
```

`vs`

and `sv`

: they encode and decode different (and variable) arithmetic bases.
English pounds have 100 pennies (once known as New Pence) but once had 240, of which 12 made a shilling; and 20 shillings a pound.
```
q)240*4.50 / £4.50 in old pence
1080f
q)100 20 12 vs 240*4.50 / £4.50 was £4 10s 0d.
4 10 0f
q)%[;240]100 20 12 sv 4 10 0 / £4/10/- in decimal coinage
4.5
q)%[;240]100 20 12 sv 4 17 6 / not every £ amount has an exact equivalent
4.875
```

`vs`

and `sv`

to convert between row-col pairs and equivalent vector indices.
```
q)shp:{count each 1 first\x} / shape
q){n:2+s:shp x; n#@[prd[n]#" ";n sv flip 1 1+/:s vs/:til prd s;:;raze x]}LOAF
" "
" LOAF "
" loaf "
" LOAF "
" "
```

## Join

Join `,`

looks like an obvious candidate.
(And it will lead us to something about `flip`

we might not have known; but we’ll come to that.)
We have to apply it to each of four sides, but we have decided we don’t necessarily need the fastest expression for this.

Looks straightforward: Join for top and bottom, Join Each for the sides.

```
q),[;" "] " ",'" ",M,'" "
" "
" LOAF "
" loaf "
" LOAF "
" "
```

```
q){row:enlist(count first x)#" ";" ",'(row,x,row),'" "}M
" "
" LOAF "
" loaf "
" LOAF "
" "
```

The simplest operation is the Join Each, which exploits scalar extension.

When I flour an unbaked loaf, I dont daub flour over it, I roll it in the flour.

```
q)" ",'reverse flip LOAF
" FfF"
" AaA"
" OoO"
" LlL"
q)" ",'reverse flip " ",'reverse flip LOAF
" FAOL"
" faol"
" FAOL"
" "
q)4{" ",'reverse flip x}/LOAF
" "
" LOAF "
" loaf "
" LOAF "
" "
```

```
q)4(" ",' reverse flip ::)/LOAF
" "
" LOAF "
" loaf "
" LOAF "
" "
```

Now here’s a surprise: we don’t need the Each.

```
q)4{" ",reverse flip x}/LOAF
" "
" LOAF "
" loaf "
" LOAF "
" "
```

## Flip and scalar extension

It turns out that `flip`

uses scalar extension.
The items of its *argument* must conform; that is, they must be same-length lists or atoms.
But the *result* will have same-length lists.

```
q)flip M:3 4#"ABCDEFGHIJKL"
"AEI"
"BFJ"
"CGK"
"DHL"
q)flip M,enlist "XYZ" / must conform!
'length
[0] flip M,enlist "XYZ" / must conform!
^
q)flip M,"X"
"AEIX"
"BFJX"
"CGKX"
"DHLX"
```