Commit c98d751d authored by Brady James Garvin's avatar Brady James Garvin
Browse files

Initial commit.

parents
# Disable line-ending conversions for this repository.
* -text
# dependencies
/node_modules
# testing
/coverage
# production
/build
# environments
.env.local
.env.development.local
.env.test.local
.env.production.local
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# misc
*~
.DS_Store
[submodule "eslint-config"]
path = eslint-config
url = git@git.unl.edu:csce-310/eslint-config.git
# Tests-Only Starter Code
A minimal project to be used as starter code for Homework 2 in the 250 section
of the CSCE 310 course at UNL.
# Quick Start
Recursively clone this repository and `cd` into the root folder:
```
$ git clone --recursive git@git.unl.edu:csce-310/2021-fall-homework-2.git
$ cd 2021-fall-homework-2
```
(If you forget `--recursive` when cloning, you can `cd` into your clone and run
`git submodule update --init --recursive` instead.)
Install dependencies:
```
$ npm install
```
# Instructions
See <https://canvas.unl.edu/courses/114253/assignments/1093847>.
Subproject commit 24df42fb655d234b83c93b0fb24d012e4d9ecb58
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.eol": "LF",
"files.exclude": {
"**/node_modules": true
},
"files.trimFinalNewlines": true,
"files.trimTrailingWhitespace": true
}
}
# dependencies
/node_modules
# testing
/coverage
# production
/build
# environments
.env.local
.env.development.local
.env.test.local
.env.production.local
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# misc
*~
.DS_Store
This diff is collapsed.
{
"name": "@unlsoft/homework-2-implementation",
"version": "1.0.0",
"description": "A minimal project to be used as starter code for Homework 2.",
"type": "module",
"private": true,
"license": "UNLICENSED",
"scripts": {
"lint:js": "eslint --max-warnings 0 ./src",
"lint": "run-s --continue-on-error lint:**",
"test-once:closestPair": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage -t 'findClosestPair'",
"test-once:sumToN": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage -t 'findElementsSummingTo'",
"test-once:intervals": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage -t 'findChromaticNumber'",
"test-once:trains": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage -t 'planJourney'",
"test-once": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watchAll --coverage"
},
"dependencies": {
"npm-run-all": "^4.1.5"
},
"devDependencies": {
"@unlsoft/eslint-config": "file:../eslint-config",
"eslint": "^7.30.0",
"jest": "^27.0.6",
"jest-environment-node": "^27.0.6"
},
"eslintConfig": {
"extends": "@unlsoft"
},
"jest": {
"clearMocks": true,
"collectCoverageFrom": [
"src/**/*.js",
"!src/testing/**/*.js"
],
"resetMocks": false,
"restoreMocks": false,
"testEnvironment": "./src/testing/failFast.js",
"transform": {}
},
"//": [
"See https://github.com/facebook/jest/issues/9430 for information on Jest+ES6."
]
}
export class BasicOperationObserver {
constructor(array) {
this.count = 0;
for (const index of array.keys()) {
const value = array[index];
Object.defineProperty(array, index, {
get: () => {
++this.count;
return value;
},
enumerable: true,
configurable: true,
});
}
}
}
export function findClosestPair(list) {
// INSTRUCTIONS: For the functional correctness points, complete this
// JavaScript function so that it finds the minimum difference between two
// distinct elements of `list`. You may assume that the input `list` is
// sorted.
//
// For the performance points, modify the search so that it runs in linear
// time. Consider that, while a straightforward exhaustive search will need
// Θ(n²) time, your generate step does not need to consider all possible pairs
// because the list is presorted.
}
/* eslint-disable no-magic-numbers */
import { BasicOperationObserver } from './basicOperationCounting.js';
import { findClosestPair } from './closestPair.js';
describe('the findClosestPair function', () => {
test('finds a shortest distance of infinity in an empty list', () => {
expect(findClosestPair([])).toBe(Infinity);
});
test('finds a shortest distance of infinity in a one-element list', () => {
expect(findClosestPair([464])).toBe(Infinity);
});
test('finds a shortest distance of 146 in sample list 0', () => {
expect(findClosestPair([150, 296])).toBe(146);
});
test('finds a shortest distance of 3 in sample list 1', () => {
expect(findClosestPair([500, 938, 941])).toBe(3);
});
test('finds a shortest distance of 141 in sample list 2', () => {
expect(findClosestPair([48, 342, 483, 736])).toBe(141);
});
test('finds a shortest distance of 95 in sample list 3', () => {
expect(findClosestPair([118, 346, 486, 581, 686])).toBe(95);
});
test('finds a shortest distance of 19 in sample list 4', () => {
expect(findClosestPair([288, 477, 547, 662, 681, 759])).toBe(19);
});
test('finds a shortest distance of 13 in sample list 5', () => {
expect(findClosestPair([90, 321, 429, 442, 644, 739, 772])).toBe(13);
});
test('finds a shortest distance of 6 in sample list 6', () => {
expect(findClosestPair([42, 192, 291, 438, 563, 703, 784, 790])).toBe(6);
});
test('finds a shortest distance of 6 in sample list 7', () => {
expect(findClosestPair([176, 256, 262, 358, 457, 560, 572, 698, 918])).toBe(6);
});
test('finds a shortest distance of 7 in sample list 8', () => {
expect(findClosestPair([65, 117, 392, 458, 593, 600, 729, 760, 915, 933])).toBe(7);
});
test('finds a shortest distance of 49 in sample list 9', () => {
expect(findClosestPair([82, 143, 296, 397, 483, 576, 625, 715, 781, 993])).toBe(49);
});
test('finds a shortest distance of 4 in sample list 10', () => {
expect(findClosestPair([10, 170, 174, 192, 343, 366, 387, 462, 647, 728])).toBe(4);
});
test('finds a shortest distance of 8 in sample list 11', () => {
expect(findClosestPair([13, 169, 276, 326, 366, 398, 456, 493, 501, 908])).toBe(8);
});
test('finds a shortest distance of 10 in sample list 12', () => {
expect(findClosestPair([68, 481, 504, 581, 708, 718, 741, 755, 843, 962])).toBe(10);
});
test('finds a shortest distance of 10 in sample list 13', () => {
expect(findClosestPair([44, 200, 348, 443, 453, 588, 670, 681, 698, 973])).toBe(10);
});
test('finds a shortest distance of 5 in sample list 14', () => {
expect(findClosestPair([142, 209, 343, 411, 483, 499, 566, 571, 931, 986])).toBe(5);
});
test('finds a shortest distance of 3 in sample list 15', () => {
expect(findClosestPair([74, 109, 112, 215, 501, 550, 698, 791, 850, 904])).toBe(3);
});
test('finds a shortest distance of 4 in sample list 16', () => {
expect(findClosestPair([109, 113, 156, 365, 414, 422, 473, 552, 556, 855])).toBe(4);
});
test('finds a shortest distance of 9 in sample list 17', () => {
expect(findClosestPair([197, 227, 377, 406, 479, 516, 538, 663, 979, 988])).toBe(9);
});
test('finds a shortest distance of 8 in sample list 18', () => {
expect(findClosestPair([2, 80, 337, 383, 391, 595, 682, 835, 861, 918])).toBe(8);
});
test('finds a shortest distance of 7 in sample list 19', () => {
expect(findClosestPair([82, 90, 130, 254, 428, 477, 492, 953, 960, 977])).toBe(7);
});
test('finds a shortest distance of 23 in sample list 20', () => {
expect(findClosestPair([149, 199, 279, 302, 342, 414, 504, 800, 936, 996])).toBe(23);
});
test('finds a shortest distance of 23 in sample list 21', () => {
expect(findClosestPair([82, 116, 150, 283, 329, 352, 517, 578, 654, 935])).toBe(23);
});
test('finds a shortest distance of 4 in sample list 22', () => {
expect(findClosestPair([62, 103, 237, 244, 267, 383, 533, 590, 594, 693])).toBe(4);
});
test('finds a shortest distance of 11 in sample list 23', () => {
expect(findClosestPair([8, 115, 166, 240, 283, 662, 827, 923, 934, 971])).toBe(11);
});
test('finds a shortest distance of 3 in sample list 24', () => {
expect(findClosestPair([19, 178, 193, 293, 457, 460, 536, 745, 827, 977])).toBe(3);
});
test('finds a shortest distance of 14 in sample list 25', () => {
expect(findClosestPair([39, 211, 380, 581, 725, 807, 821, 925, 952, 991])).toBe(14);
});
test('finds a shortest distance of 10 in sample list 26', () => {
expect(findClosestPair([83, 302, 529, 545, 583, 777, 875, 886, 966, 976])).toBe(10);
});
test('finds a shortest distance of 5 in sample list 27', () => {
expect(findClosestPair([35, 189, 279, 392, 397, 407, 478, 550, 923, 981])).toBe(5);
});
test('finds a shortest distance of 19 in sample list 28', () => {
expect(findClosestPair([10, 275, 294, 376, 413, 604, 687, 753, 815, 995])).toBe(19);
});
test('finds a shortest distance of 27 in sample list 29', () => {
expect(findClosestPair([47, 74, 150, 198, 727, 783, 814, 864, 941, 979])).toBe(27);
});
test('finds a shortest distance of 2 in sample list 30', () => {
expect(findClosestPair([121, 183, 185, 251, 363, 436, 675, 773, 817, 898])).toBe(2);
});
test('finds a shortest distance of 26 in sample list 31', () => {
expect(findClosestPair([63, 89, 119, 287, 348, 394, 420, 529, 606, 719])).toBe(26);
});
test('finds a shortest distance of 0 in sample list 32', () => {
expect(findClosestPair([241, 241, 318, 364, 416, 491, 523, 614, 742, 907])).toBe(0);
});
test('finds a shortest distance of 29 in sample list 33', () => {
expect(findClosestPair([101, 260, 452, 490, 610, 694, 773, 874, 903, 935])).toBe(29);
});
test('finds a shortest distance of 3 in sample list 34', () => {
expect(findClosestPair([49, 334, 374, 384, 573, 629, 691, 694, 764, 935])).toBe(3);
});
test('finds a shortest distance of 6 in sample list 35', () => {
expect(findClosestPair([61, 180, 244, 250, 516, 634, 795, 807, 828, 848])).toBe(6);
});
test('finds a shortest distance of 7 in sample list 36', () => {
expect(findClosestPair([95, 303, 461, 468, 484, 539, 693, 732, 830, 944])).toBe(7);
});
test('finds a shortest distance of 8 in sample list 37', () => {
expect(findClosestPair([21, 236, 254, 295, 356, 380, 489, 895, 963, 971])).toBe(8);
});
test('finds a shortest distance of 4 in sample list 38', () => {
expect(findClosestPair([46, 50, 178, 347, 368, 497, 661, 689, 695, 958])).toBe(4);
});
test('finds a shortest distance of 5 in sample list 39', () => {
expect(findClosestPair([1, 28, 409, 477, 482, 552, 561, 605, 687, 711])).toBe(5);
});
test('finds a shortest distance of 1 in sample list 40', () => {
expect(findClosestPair([492, 639, 658, 683, 684, 718, 821, 878, 946, 973])).toBe(1);
});
test('finds a shortest distance of 13 in sample list 41', () => {
expect(findClosestPair([2, 16, 41, 146, 163, 267, 280, 402, 539, 670])).toBe(13);
});
test('finds a shortest distance of 3 in sample list 42', () => {
expect(findClosestPair([29, 236, 495, 505, 648, 711, 737, 740, 777, 903])).toBe(3);
});
test('finds a shortest distance of 5 in sample list 43', () => {
expect(findClosestPair([19, 125, 295, 408, 480, 599, 825, 931, 979, 984])).toBe(5);
});
test('finds a shortest distance of 4 in sample list 44', () => {
expect(findClosestPair([147, 197, 203, 286, 502, 506, 657, 719, 780, 802])).toBe(4);
});
test('finds a shortest distance of 1 in sample list 45', () => {
expect(findClosestPair([26, 74, 164, 183, 243, 267, 268, 380, 412, 889])).toBe(1);
});
test('finds a shortest distance of 2 in sample list 46', () => {
expect(findClosestPair([16, 360, 624, 635, 651, 790, 880, 883, 885, 947])).toBe(2);
});
test('finds a shortest distance of 6 in sample list 47', () => {
expect(findClosestPair([96, 176, 277, 338, 364, 436, 442, 689, 810, 979])).toBe(6);
});
test('finds a shortest distance of 8 in sample list 48', () => {
expect(findClosestPair([117, 191, 209, 258, 324, 855, 882, 890, 986, 998])).toBe(8);
});
test('finds a shortest distance of 3 in sample list 49', () => {
expect(findClosestPair([145, 148, 234, 263, 350, 380, 448, 527, 702, 938])).toBe(3);
});
test('finds a shortest distance of 5 in sample list 50', () => {
expect(findClosestPair([7, 87, 108, 165, 379, 413, 486, 822, 827, 860])).toBe(5);
});
test('finds a shortest distance of 1 in sample list 51', () => {
expect(findClosestPair([104, 353, 511, 620, 635, 665, 684, 848, 921, 922])).toBe(1);
});
test('finds a shortest distance of 19 in sample list 52', () => {
expect(findClosestPair([54, 239, 285, 372, 514, 608, 627, 771, 816, 925])).toBe(19);
});
test('finds a shortest distance of 21 in sample list 53', () => {
expect(findClosestPair([113, 326, 380, 415, 436, 611, 691, 750, 782, 833])).toBe(21);
});
test('finds a shortest distance of 5 in sample list 54', () => {
expect(findClosestPair([138, 186, 205, 245, 273, 320, 325, 662, 778, 845])).toBe(5);
});
test('finds a shortest distance of 1 in sample list 55', () => {
expect(findClosestPair([59, 222, 361, 405, 445, 534, 539, 818, 819, 836])).toBe(1);
});
test('finds a shortest distance of 6 in sample list 56', () => {
expect(findClosestPair([17, 40, 103, 132, 138, 325, 599, 638, 816, 883])).toBe(6);
});
test('finds a shortest distance of 4 in sample list 57', () => {
expect(findClosestPair([118, 230, 300, 418, 452, 674, 698, 702, 710, 725])).toBe(4);
});
test('finds a shortest distance of 5 in sample list 58', () => {
expect(findClosestPair([231, 246, 514, 519, 658, 693, 729, 780, 793, 850])).toBe(5);
});
test('finds a shortest distance of 4 in sample list 59', () => {
expect(findClosestPair([84, 97, 101, 261, 391, 486, 555, 642, 697, 795])).toBe(4);
});
test('finds a shortest distance of 7 in sample list 60', () => {
expect(findClosestPair([161, 187, 348, 355, 550, 735, 750, 812, 902, 968])).toBe(7);
});
test('finds a shortest distance of 7 in sample list 61', () => {
expect(findClosestPair([177, 188, 201, 382, 530, 537, 689, 747, 859, 887])).toBe(7);
});
test('finds a shortest distance of 2 in sample list 62', () => {
expect(findClosestPair([115, 551, 621, 677, 679, 792, 800, 802, 962, 997])).toBe(2);
});
test('finds a shortest distance of 33 in sample list 63', () => {
expect(findClosestPair([77, 134, 167, 294, 351, 425, 536, 630, 711, 823])).toBe(33);
});
test('finds a shortest distance of 17 in sample list 64', () => {
expect(findClosestPair([15, 32, 215, 419, 580, 685, 720, 829, 865, 932])).toBe(17);
});
test('finds a shortest distance of 13 in sample list 65', () => {
expect(findClosestPair([162, 358, 416, 433, 510, 534, 560, 688, 701, 809])).toBe(13);
});
test('finds a shortest distance of 15 in sample list 66', () => {
expect(findClosestPair([109, 142, 263, 465, 537, 552, 648, 725, 785, 965])).toBe(15);
});
test('finds a shortest distance of 22 in sample list 67', () => {
expect(findClosestPair([168, 267, 371, 424, 546, 646, 672, 694, 765, 920])).toBe(22);
});
test('finds a shortest distance of 16 in sample list 68', () => {
expect(findClosestPair([119, 135, 226, 256, 313, 399, 549, 907, 935, 974])).toBe(16);
});
test('finds a shortest distance of 7 in sample list 69', () => {
expect(findClosestPair([0, 106, 113, 397, 405, 594, 624, 719, 881, 916])).toBe(7);
});
test('finds a shortest distance of 0 in sample list 70', () => {
expect(findClosestPair([25, 145, 215, 343, 400, 588, 588, 591, 667, 815])).toBe(0);
});
test('finds a shortest distance of 2 in sample list 71', () => {
expect(findClosestPair([27, 129, 283, 536, 577, 800, 802, 880, 903, 920])).toBe(2);
});
test('finds a shortest distance of 2 in sample list 72', () => {
expect(findClosestPair([8, 132, 134, 254, 298, 496, 574, 614, 717, 829])).toBe(2);
});
test('finds a shortest distance of 3 in sample list 73', () => {
expect(findClosestPair([70, 191, 296, 385, 388, 504, 534, 768, 861, 873])).toBe(3);
});
test('finds a shortest distance of 9 in sample list 74', () => {
expect(findClosestPair([144, 287, 335, 475, 484, 565, 645, 794, 885, 999])).toBe(9);
});
test('finds a shortest distance of 18 in sample list 75', () => {
expect(findClosestPair([33, 66, 164, 187, 234, 440, 484, 502, 631, 900])).toBe(18);
});
test('finds a shortest distance of 19 in sample list 76', () => {
expect(findClosestPair([66, 302, 430, 477, 596, 707, 726, 807, 919, 953])).toBe(19);
});
test('finds a shortest distance of 38 in sample list 77', () => {
expect(findClosestPair([202, 292, 370, 409, 464, 600, 660, 698, 737, 887])).toBe(38);
});
test('finds a shortest distance of 6 in sample list 78', () => {
expect(findClosestPair([55, 61, 111, 133, 218, 512, 677, 786, 901, 955])).toBe(6);
});
test('finds a shortest distance of 12 in sample list 79', () => {
expect(findClosestPair([18, 137, 149, 178, 247, 285, 607, 799, 823, 853])).toBe(12);
});
test('finds a shortest distance of 10 in sample list 80', () => {
expect(findClosestPair([91, 131, 141, 485, 519, 564, 616, 632, 810, 994])).toBe(10);
});
test('finds a shortest distance of 3 in sample list 81', () => {
expect(findClosestPair([94, 208, 291, 388, 399, 415, 822, 867, 870, 902])).toBe(3);
});
test('finds a shortest distance of 1 in sample list 82', () => {
expect(findClosestPair([282, 401, 402, 725, 776, 792, 867, 883, 960, 967])).toBe(1);
});
test('finds a shortest distance of 1 in sample list 83', () => {
expect(findClosestPair([72, 276, 277, 481, 501, 526, 595, 768, 900, 950])).toBe(1);
});
test('finds a shortest distance of 14 in sample list 84', () => {
expect(findClosestPair([79, 370, 415, 452, 588, 630, 788, 906, 920, 947])).toBe(14);
});
test('finds a shortest distance of 26 in sample list 85', () => {
expect(findClosestPair([72, 133, 159, 428, 518, 672, 756, 803, 926, 954])).toBe(26);
});
test('finds a shortest distance of 10 in sample list 86', () => {
expect(findClosestPair([5, 36, 48, 184, 194, 308, 413, 454, 464, 930])).toBe(10);
});
test('finds a shortest distance of 4 in sample list 87', () => {
expect(findClosestPair([141, 157, 302, 411, 466, 635, 708, 956, 960, 979])).toBe(4);
});
test('finds a shortest distance of 5 in sample list 88', () => {
expect(findClosestPair([137, 224, 229, 321, 371, 478, 489, 525, 661, 728])).toBe(5);
});
test('finds a shortest distance of 7 in sample list 89', () => {
expect(findClosestPair([2, 19, 261, 376, 404, 468, 676, 683, 801, 809])).toBe(7);
});
test('finds a shortest distance of 8 in sample list 90', () => {
expect(findClosestPair([149, 242, 445, 465, 479, 613, 621, 672, 934, 966])).toBe(8);
});
test('finds a shortest distance of 3 in sample list 91', () => {
expect(findClosestPair([287, 290, 309, 537, 571, 716, 721, 779, 871, 986])).toBe(3);
});
test('finds a shortest distance of 1 in sample list 92', () => {
expect(findClosestPair([38, 169, 203, 211, 263, 406, 789, 885, 936, 937])).toBe(1);
});
test('finds a shortest distance of 18 in sample list 93', () => {
expect(findClosestPair([84, 173, 198, 275, 359, 444, 563, 581, 935, 978])).toBe(18);
});
test('finds a shortest distance of 1 in sample list 94', () => {
expect(findClosestPair([73, 208, 297, 317, 545, 559, 626, 744, 892, 893])).toBe(1);
});
test('finds a shortest distance of 6 in sample list 95', () => {
expect(findClosestPair([7, 320, 388, 394, 529, 595, 722, 730, 819, 921])).toBe(6);
});
test('finds a shortest distance of 1 in sample list 96', () => {
expect(findClosestPair([31, 172, 179, 469, 498, 519, 802, 845, 961, 962])).toBe(1);
});
test('finds a shortest distance of 35 in sample list 97', () => {
expect(findClosestPair([9, 160, 208, 413, 494, 812, 849, 891, 926, 963])).toBe(35);
});
test('finds a shortest distance of 4 in sample list 98', () => {
expect(findClosestPair([42, 123, 369, 373, 429, 461, 672, 689, 700, 761])).toBe(4);
});
test('finds a shortest distance of 8 in sample list 99', () => {
expect(findClosestPair([271, 484, 501, 685, 786, 845, 853, 866, 946, 983])).toBe(8);
});
test('needs fewer than 2.5n array accesses on a small list', () => {
const list = [122, 152, 423, 464, 497, 589, 596, 714, 806, 888];
const basicOperations = new BasicOperationObserver(list);
findClosestPair(list);
expect(basicOperations.count).toBeLessThan(25);
});
test('needs fewer than 2.5n array accesses on a medium list', () => {
const list = [25, 34, 52, 66, 130, 159, 173, 215, 240, 286, 350, 384, 421, 440, 492, 647, 719, 765, 792, 919];
const basicOperations = new BasicOperationObserver(list);
findClosestPair(list);
expect(basicOperations.count).toBeLessThan(50);
});
test('needs fewer than 2.5n array accesses on a large list', () => {
const list = [
12, 49, 106, 206, 277, 287, 340, 356, 369, 447, 485, 489, 489, 492, 560,
598, 606, 698, 727, 733, 780, 816, 848, 906, 911, 912, 921, 928, 940, 976,
];
const basicOperations = new BasicOperationObserver(list);
findClosestPair(list);
expect(basicOperations.count).toBeLessThan(75);
});
});
export class PriorityQueue {
constructor() {
this._vertices = [];
}
get size() {
return this._vertices.length;
}
insert(element, measure) {
let index = this._vertices.length;
while (index > 0) {
const parentIndex = Math.floor((index - 1) / 2);
const parent = this._vertices[parentIndex];
if (parent.measure < measure) {
break;
}
this._vertices[index] = parent;
index = parentIndex;
}
this._vertices[index] = {
element,
measure,
};
}
remove() {
console.assert(this._vertices.length > 0, 'Cannot remove an element from an empty priority queue');
const result = this._vertices[0].element;
const vertex = this._vertices[this._vertices.length - 1];
for (let index = 0; ;) {
this._vertices[index] = vertex;
let swapIndex = index;
for (const candidateIndex of [2 * index + 1, 2 * index + 2]) {
if (candidateIndex < this._vertices.length - 1 &&
this._vertices[candidateIndex].measure < this._vertices[swapIndex].measure) {
swapIndex = candidateIndex;
}
}
if (swapIndex === index) {
this._vertices[index] = vertex;
this._vertices.pop();
return result;
}
this._vertices[index] = this._vertices[swapIndex];
index = swapIndex;
}
}
}