Welcome to Matrix on Exercism's AWK Track.
If you need help running the tests or submitting your code, check out HELP.md
.
Given a string representing a matrix of numbers, return the rows and columns of that matrix.
So given a string with embedded newlines like:
9 8 7
5 3 2
6 6 7
representing this matrix:
1 2 3
|---------
1 | 9 8 7
2 | 5 3 2
3 | 6 6 7
your code should be able to spit out:
- A list of the rows, reading each row left-to-right while moving top-to-bottom across the rows,
- A list of the columns, reading each column top-to-bottom while moving from left-to-right.
The rows for our example matrix:
- 9, 8, 7
- 5, 3, 2
- 6, 6, 7
And its columns:
- 9, 5, 6
- 8, 3, 6
- 7, 2, 7
This is the first exercise where the solution is not a "main" script. The goal is to write a library of functions to be included into other awk programs. There are several interesting new concepts to see in this exercise.
The following sections that are tagged with "(gawk)" are specifically GNU awk extensions.
In this exercise, you'll be reading data from a file, not from the main input stream.
Read about getline
in the Gnu awk manual,
particularly the Getline/File
and Getline/Variable/File
forms.
A two-dimensional array might be a way to implement this solution. GNU awk has two ways to represent one:
Notice the @include
directive in the test file.
This instructs gawk to read and evaluate the named file.
All awk variables are global (except for function parameters which are local to the function).
There is a high potential for name collisions, particularly when third-party libraries get included.
Namespaces are a way to partition where variables are stored.
Notice the @namespace
directive in the exercise's files.
The default namespace is named "awk". Having a default namespace allows the programmer to call a builtin awk function from inside a function in a different namespace.
Array parameters are passed by reference. Changes to the array made in the function are visible in the caller.
Non-array parameters are passed by value.
For untyped parameters, it depends on what the function does with them:
- if the function initializes it as an array, then it becomes a parameter passed by reference,
- if the function initializes it as a scalar value (a number or a string), then it is not a reference.
Full details are in the manual in Passing Function Arguments by Value Or by Reference.
Function scoped (local) variables can be created by using "pass by value" parameters. It is not an error to pass fewer values to a function than the number of listed parameters; the excess parameters are "untyped" until they get used. They are available to be assigned scalar values in the function that are not stored in the global namespace.
- If you assign a scalar value to a parameter, that is local to the function.
- If you assign a scalar to a variable not named in the parameter list, that variable is global.
By convention, in the function signature the expected parameters appear first followed by some whitespace and then the local parameters. An example:
function add(a, b, total) {
# here, `typeof(total)` is "untyped"
total = a + b
# now, `typeof(total)` is "number"
return total
}
BEGIN {
sum = add(5, 10)
print sum # 15
print typeof(total) # untyped, meaning "total" is unused in this scope
}
- @glennj
Exercise by the JumpstartLab team for students at The Turing School of Software and Design. - https://turing.edu