Skip to content

Commit 8a79ca7

Browse files
typescript/matrix: minimal mentor notes (#727)
* typescript/matrix: minimal mentor notes * :nailcare: cleanup
1 parent 1881cc6 commit 8a79ca7

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
This exercise introduces:
2+
- String reader via [`String#split`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split)
3+
- [`Array#map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
4+
5+
### Reasonable solutions
6+
7+
There are two ways to transpose the matrix. Either non-destructive:
8+
9+
```typescript
10+
function transpose<T>(rows: Readonly<T[][]>): T[][] {
11+
return rows[0].map((_, i) => {
12+
return rows.map((row) => {
13+
return row[i]
14+
})
15+
})
16+
}
17+
```
18+
19+
Or destructive:
20+
21+
```typescript
22+
function transpose<T>(matrix: T[][]): T[][] {
23+
for (let i = 0; i < matrix.length; i++) {
24+
for (let j = 0; j < i; j++) {
25+
[matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]
26+
}
27+
}
28+
return matrix
29+
}
30+
```
31+
32+
In case of the latter, the logic becomes harder. Make sure the implementation of
33+
the student allows for calling both `columns` and `rows` on the same instance,
34+
multiple times. This is _not_ part of the test suite (yet). This is important if
35+
the student uses getters for example.
36+
37+
The matrix itself is straight-forward:
38+
39+
```typescript
40+
class Matrix {
41+
42+
public readonly rows: number[][]
43+
public readonly columns: number[][]
44+
45+
constructor(input: Readonly<string>) {
46+
this.rows = input.split('\n').map((row) => row.split(' ').map(Number))
47+
this.columns = transpose(this.rows)
48+
}
49+
}
50+
```
51+
52+
A student may use `parseInt` instead of `number`, and a student may use getters
53+
(`get rows() { return this.data }`) to make the transposing lazy.
54+
55+
### Common suggestions
56+
- If a student uses `foreach`, intermediary bookkeeping and `push`, suggest [`Array#map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).
57+
- If a student uses a dangerous version of transpose, suggest a non-destructive one, or make sure it's only ever called once.
58+
- If a student uses `map(arg => parseInt(arg))` or similar, explain they can drop the anonymous arrow function and pass in `parseInt` directly.
59+
- If a student uses `any[][]`, point them towards `name<T>(arg: Readonly<T[][]>): T[][]` which preserves the type of the arrays
60+
- If a student builds both array in one go, as shown below this suggestion, suggest `Array#map` and point them to "transpose algorithm":
61+
62+
```javascript
63+
const rows: number[][] = []
64+
const columns: number[][] = []
65+
66+
input.split('\n')
67+
.forEach((row, i) => {
68+
this.rows.push(row.split(' ').map(Number))
69+
this.rows[i].forEach(
70+
i === 0
71+
? (e) => this.columns.push([e])
72+
: (e, j) => this.columns[j].push((e))
73+
)
74+
})
75+
```
76+
77+
### Talking points
78+
- Functions are first class citizens, so you can pass one to `Array#map` and it executes on each one
79+
- Immutability and side effects

0 commit comments

Comments
 (0)