Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions exercises/concept/bird-watcher/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ You already digitalized the bird counts per day for the past weeks that you kept

Now you want to determine the total number of birds that you counted, calculate the bird count for a specific week and correct a counting mistake.

<!-- prettier-ignore-start -->
<!-- prettier-ignore -->
~~~~exercism/note
To practice, use a for loop to solve each of the tasks below.
To practice, use a `for` loop to solve each of the tasks below.
~~~~
<!-- prettier-ignore-end -->

## 1. Determine the total number of birds that you counted so far

Expand Down
7 changes: 5 additions & 2 deletions exercises/concept/bird-watcher/.meta/exemplar.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
*/
export function totalBirdCount(birdsPerDay) {
let total = 0;

for (let i = 0; i < birdsPerDay.length; i++) {
total += birdsPerDay[i];
}

return total;
}

Expand All @@ -27,10 +29,12 @@ export function totalBirdCount(birdsPerDay) {
*/
export function birdsInWeek(birdsPerDay, week) {
let total = 0;

const start = 7 * (week - 1);
for (let i = start; i < start + 7; i++) {
total += birdsPerDay[i];
}

return total;
}

Expand All @@ -39,11 +43,10 @@ export function birdsInWeek(birdsPerDay, week) {
* by one for every second day.
*
* @param {number[]} birdsPerDay
* @returns {number[]} corrected bird count data
* @returns {void} should not return anything
*/
export function fixBirdCountLog(birdsPerDay) {
for (let i = 0; i < birdsPerDay.length; i += 2) {
birdsPerDay[i]++;
}
return birdsPerDay;
}
2 changes: 1 addition & 1 deletion exercises/concept/bird-watcher/bird-watcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function birdsInWeek(birdsPerDay, week) {
* by one for every second day.
*
* @param {number[]} birdsPerDay
* @returns {number[]} corrected bird count data
* @returns {void} should not return anything
*/
export function fixBirdCountLog(birdsPerDay) {
throw new Error('Please implement the fixBirdCountLog function');
Expand Down
105 changes: 78 additions & 27 deletions exercises/concept/bird-watcher/bird-watcher.spec.js
Original file line number Diff line number Diff line change
@@ -1,79 +1,130 @@
import { describe, expect, test } from '@jest/globals';
import { birdsInWeek, fixBirdCountLog, totalBirdCount } from './bird-watcher';

const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom');
const customLogSymbol = Symbol.for('exercism.javascript.util.log');

// Follow the instructions in case you are stuck on "list.method is not a function"
class CountingReport {
constructor(counts) {
// Enables array[index]
counts.forEach((count, index) => {
this[index] = count;
});

// Enables .length
this.length = counts.length;
}

// Log value in non-upgraded environments
toString() {
return arrayOf(this).toString();
}

// Overrides logging in node (ie. students working locally)
[customInspectSymbol]() {
return `Seen birds per day: ${arrayOf(this)}`;
}

// Overrides log overrides in web environment (ie. students working in editor)
[customLogSymbol]() {
return `Seen birds per day: ${arrayOf(this)}`;
}
}

function report(...values) {
return new CountingReport(values);
}

function arrayOf(countingReport) {
return Array.from(
{ length: countingReport.length },
(_, i) => countingReport[i],
);
}

function randomArray(length) {
return Array.from({ length }, () => Math.floor(Math.random() * 8));
}

describe('totalBirdCount', () => {
test('calculates the correct total number of birds', () => {
const birdsPerDay = [9, 0, 8, 4, 5, 1, 3];
const birdsPerDay = report(9, 0, 8, 4, 5, 1, 3);
expect(totalBirdCount(birdsPerDay)).toBe(30);
});

test('works for a short bird count list', () => {
const birdsPerDay = [2];
const birdsPerDay = report(2);
expect(totalBirdCount(birdsPerDay)).toBe(2);
});

test('works for a long bird count list', () => {
// prettier-ignore
const birdsPerDay = [2, 8, 4, 1, 3, 5, 0, 4, 1, 6, 0, 3, 0, 1, 5, 4, 1, 1, 2, 6];
const birdsPerDay = report(
2, 8, 4, 1, 3, 5, 0, 4, 1, 6, 0, 3, 0, 1, 5, 4, 1, 1, 2, 6
);

expect(totalBirdCount(birdsPerDay)).toBe(57);
});
});

describe('birdsInWeek', () => {
test('calculates the number of birds in the first week', () => {
const birdsPerDay = [3, 0, 5, 1, 0, 4, 1, 0, 3, 4, 3, 0, 8, 0];
const birdsPerDay = report(3, 0, 5, 1, 0, 4, 1, 0, 3, 4, 3, 0, 8, 0);
expect(birdsInWeek(birdsPerDay, 1)).toBe(14);
});

test('calculates the number of birds for a week in the middle of the log', () => {
// prettier-ignore
const birdsPerDay = [4, 7, 3, 2, 1, 1, 2, 0, 2, 3, 2, 7, 1, 3, 0, 6, 5, 3, 7, 2, 3];
const birdsPerDay = report(4, 7, 3, 2, 1, 1, 2, 0, 2, 3, 2, 7, 1, 3, 0, 6, 5, 3, 7, 2, 3);
expect(birdsInWeek(birdsPerDay, 2)).toBe(18);
});

test('works when there is only one week', () => {
const birdsPerDay = [3, 0, 3, 3, 2, 1, 0];
const birdsPerDay = report(3, 0, 3, 3, 2, 1, 0);
expect(birdsInWeek(birdsPerDay, 1)).toBe(12);
});

test('works for a long bird count list', () => {
const week21 = [2, 0, 1, 4, 1, 3, 0];
const birdsPerDay = randomArray(20 * 7)
.concat(week21)
.concat(randomArray(10 * 7));
const week21 = report(2, 0, 1, 4, 1, 3, 0);
const birdsPerDay = report(
...randomArray(20 * 7)
.concat(arrayOf(week21))
.concat(randomArray(10 * 7)),
);

expect(birdsInWeek(birdsPerDay, 21)).toBe(11);
});
});

describe('fixBirdCountLog', () => {
test('returns a bird count list with the corrected values', () => {
const birdsPerDay = [3, 0, 5, 1, 0, 4, 1, 0, 3, 4, 3, 0];
const birdsPerDay = report(3, 0, 5, 1, 0, 4, 1, 0, 3, 4, 3, 0);
const expected = [4, 0, 6, 1, 1, 4, 2, 0, 4, 4, 4, 0];
expect(fixBirdCountLog(birdsPerDay)).toEqual(expected);
});

test('does not create a new array', () => {
const birdsPerDay = [2, 0, 1, 4, 1, 3, 0];
fixBirdCountLog(birdsPerDay);

// This checks that the same object that was passed in is returned.
// https://jestjs.io/docs/expect#tobevalue
expect(Object.is(fixBirdCountLog(birdsPerDay), birdsPerDay)).toBe(true);
expect(arrayOf(birdsPerDay)).toEqual(expected);
});

test('works for a short bird count list', () => {
expect(fixBirdCountLog([4, 2])).toEqual([5, 2]);
const birdsPerDay = report(4, 2);
fixBirdCountLog(birdsPerDay);

expect(arrayOf(birdsPerDay)).toEqual([5, 2]);
});

test('works for a long bird count list', () => {
// prettier-ignore
const birdsPerDay = [2, 8, 4, 1, 3, 5, 0, 4, 1, 6, 0, 3, 0, 1, 5, 4, 1, 1, 2, 6];
const birdsPerDay = report(
2, 8, 4, 1, 3, 5, 0, 4, 1, 6, 0, 3, 0, 1, 5, 4, 1, 1, 2, 6
);

// prettier-ignore
const expected = [3, 8, 5, 1, 4, 5, 1, 4, 2, 6, 1, 3, 1, 1, 6, 4, 2, 1, 3, 6];
expect(fixBirdCountLog(birdsPerDay)).toEqual(expected);
const expected = [
3, 8, 5, 1, 4, 5, 1, 4, 2, 6, 1, 3, 1, 1, 6, 4, 2, 1, 3, 6
]

fixBirdCountLog(birdsPerDay);
expect(arrayOf(birdsPerDay)).toEqual(expected);
});
});

function randomArray(length) {
return Array.from({ length: length }, () => Math.floor(Math.random() * 8));
}