UNB/ CS/ David Bremner/ teaching/ cs2613/ labs/ Lab 10

Before the lab

Questions

Time
5 Minutes
Activity
Group discussion / Announcments

A Vector class

Time
25 minutes
Activity
Exercise from book.

Do the Vector Type exercise.

test("addition", (t) =>
    assert.deepStrictEqual(new Vec(1, 2).plus(new Vec(2, 3)),
                           new Vec(3,5)));
test("subtraction", (t)=>
    assert.deepStrictEqual(new Vec(1, 2).minus(new Vec(2, 3)),
                           new Vec(-1,-1)));
test("length", (t) =>
    assert.strictEqual(new Vec(3, 4).length,5));

A Set ("Group") class

Time
25 minutes
Activity
Exercise from book.

Do the Group exercise. Instead of the suggested array, use an object to store the elements of the "Group". The simplest way to implement from is to loop over the iterable argument and repeatedly call add.

const test=require("node:test");
const assert=require("assert");
class Group {
    constructor() {
        this.elements={}
    }
    add(element) {
        this.elements[element]=true;
    }
    has(element) {
    }
    delete(element) {
    }
    static from(iterable) {
    }
}
let group = Group.from([10, 20]);
test("has yes",(t)=>assert.strictEqual(group.has(10),true));
test("has no",(t)=>assert.strictEqual(group.has(30),false));
test("add existing is not error", (t)=>group.add(10));
test("delete existing", (t) => {
    group.delete(10);
    assert.strictEqual(group.has(10),false);
});

Timing functions

Time
40 minutes
Activity
Individual work.

We are presented with two different implementations of the Fibonacci function, and we want to see which one is faster 1.

const test=require("node:test");
const assert=require("assert");

function fib(n) {
    if (n<=2)
        return 1;
    else
        return fib(n-1)+fib(n-2);
}

let cache = {};
function memfib(n) {
    if (cache[n] !== undefined)
        return cache[n];

    if (n<=2)
        cache[n] = 1;
    else
        cache[n] = memfib(n-1)+memfib(n-2);

    return cache[n];
}

test("fib(35)=9227465",(t)=>assert.strictEqual(fib(35),9227465));
test("memfib(35)=9227465",(t)=>assert.strictEqual(memfib(35),9227465));

Using the function noisy as a template, write the higher order function timed that uses the builtins console.time and console.timeEnd to output timing information. The wrapped function produced by timed should produce the same values as the original function, as shown by the following tests.

test("timed(fib)(35)=9227465", (t)=>assert.strictEqual(timed(fib)(35),9227465));
test("timed(memfib)(35)=9227465",(t)=>assert.strictEqual(timed(memfib)(35),9227465));

let out=timed(fib)(42);
let out2=timed(memfib)(42);

test("fib(42)≈memfib(42)",assert.ok(Math.abs(out-out2)<0.000001))

It turns out that memfib is much faster. On my computer, the output from the last two timed calls is

fib(42): 970.887ms
memfib(42): 0.034ms

Notice how I have included the name of the function and the parameter in the output. Try to do the same.

Before Next Lab


  1. There are much faster ways to compute Fibonacci numbers↩