Skip to content
Snippets Groups Projects
Commit 442d5377 authored by Brady James Garvin's avatar Brady James Garvin
Browse files

Initial commit.

parents
Branches
No related tags found
No related merge requests found
# 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:soft-core/soft-260/eslint-config.git
# Homework 5
Starter code for Homework 5 in the SOFT 260 course at UNL.
# Quick Start
Recursively clone this repository and `cd` into the root folder:
```
$ git clone --recursive git@git.unl.edu:soft-core/soft-260/2023-fall-homework-5.git
$ cd 2023-fall-homework-5
```
(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/162939/assignments/1631899>.
Subproject commit a85278e2bd62f637800bc32fa6b372bc2855546e
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.eol": "\n",
"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-5",
"version": "1.0.0",
"description": "Starter code for Homework 5.",
"type": "module",
"private": true,
"license": "UNLICENSED",
"scripts": {
"lint:js": "eslint --max-warnings 0 ./src",
"lint": "run-s --continue-on-error lint:**",
"test-once:dataStructure": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t \"the tape data structure holds correct data\"",
"test-once:consistency": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t \"is consistent\"",
"test-once:performance": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t \"returns hash values that\"",
"test-once": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watchAll"
},
"dependencies": {
"npm-run-all": "^4.1.5"
},
"devDependencies": {
"@unlsoft/eslint-config": "file:../eslint-config",
"eslint": "^8.20.0",
"jest": "^29.5.0",
"jest-environment-node": "^29.5.0"
},
"eslintConfig": {
"extends": "@unlsoft"
},
"jest": {
"clearMocks": true,
"resetMocks": false,
"restoreMocks": false,
"testEnvironment": "./src/testing/failFast.js",
"transform": {}
},
"//": [
"See https://github.com/facebook/jest/issues/9430 for information on Jest+ES6."
]
}
const INITIAL_HASH_TABLE_CAPACITY = 31;
const MAXIMUM_LOAD_FACTOR = 0.7;
const MASK = BigInt(Number.MAX_SAFE_INTEGER);
function mod(value, modulus) {
const result = value % modulus;
/* istanbul ignore next -- "then" case will go unused if hash values are never negative */
return result < 0 ? result + modulus : result;
}
function isPseudoPrime(number) {
/* istanbul ignore if -- "then" case should be unreachable if INITIAL_HASH_TABLE_CAPACITY is reasonable */
if (number <= 2 || number % 2 === 0) {
return false;
}
let residue = 1;
for (let i = number - 1, power = 2; i > 0; i >>>= 1, power *= power, power %= number) {
if (i & 1) {
residue *= power;
residue %= number;
}
}
return residue === 1;
}
function increaseToPseudoPrime(number) {
let result = Math.ceil((Math.max(number, 2) - 1) / 2) * 2 + 1;
while (!isPseudoPrime(result)) {
result += 2;
}
return result;
}
function createBuckets(count) {
const result = Array(count);
for (let i = result.length; i--;) {
result[i] = [];
}
return result;
}
export class HashTable {
constructor() {
this._hashFunction = (element) => mod(Number(element.hash & MASK), this._buckets.length);
this._buckets = createBuckets(increaseToPseudoPrime(INITIAL_HASH_TABLE_CAPACITY));
this._size = 0;
}
_resize() {
const oldBuckets = this._buckets;
this._buckets = createBuckets(increaseToPseudoPrime(2 * oldBuckets.length));
this._size = 0;
for (const bucket of oldBuckets) {
for (const element of bucket) {
this.add(element);
}
}
}
get size() {
return this._size;
}
get occupiedBucketCount() {
let occupiedBucketCount = 0;
for (const bucket of this._buckets) {
if (bucket.length > 0) {
++occupiedBucketCount;
}
}
return occupiedBucketCount;
}
has(element) {
return this._buckets[this._hashFunction(element)].findIndex((candidate) => candidate.equals(element)) >= 0;
}
add(element) {
const bucket = this._buckets[this._hashFunction(element)];
if (bucket.findIndex((candidate) => candidate.equals(element)) >= 0) {
return false;
}
bucket.push(element);
++this._size;
if (this._size / this._buckets.length > MAXIMUM_LOAD_FACTOR) {
this._resize();
}
return true;
}
delete(element) {
const bucket = this._buckets[this._hashFunction(element)];
const index = bucket.findIndex((candidate) => candidate.equals(element));
if (index < 0) {
return false;
}
--this._size;
bucket.splice(index, 1);
return true;
}
}
/* IMPORTANT: Remove this directive when you start working on the code so that
* the linter will warn you about code style issues. */
/* eslint-disable no-unused-vars */
const SYMBOLS = [undefined, ...'abcdef'];
function hashSymbol(symbol) {
return BigInt(SYMBOLS.indexOf(symbol));
}
function quasipush(stack, symbol) {
if (stack.length === 0 && symbol === undefined) {
return; // JavaScript treats negative indices as containing undefined, so no need to store them.
}
stack.push(symbol);
}
function quasipop(stack) {
return stack.pop(); // JavaScript already ignores pops on empty stacks.
}
export class Tape {
constructor() {
this.left = [];
this.right = [];
this.hash = 0n; // Add code to make this a memoized hash of the tape.
}
scroll(distance) {
let remaining = distance;
for (; remaining > 0; --remaining) {
quasipush(this.left, quasipop(this.right));
}
for (; remaining < 0; ++remaining) {
quasipush(this.right, quasipop(this.left));
}
}
get current() {
return this.right[this.right.length - 1];
}
set current(symbol) {
console.assert(symbol !== undefined);
quasipop(this.right);
quasipush(this.right, symbol);
}
equals(other) {
return this.left.length === other.left.length &&
this.right.length === other.right.length &&
this.left.every((symbol, i) => symbol === other.left[i]) &&
this.right.every((symbol, i) => symbol === other.right[i]);
}
}
This diff is collapsed.
This diff is collapsed.
import jestEnvironmentNode from 'jest-environment-node';
export default class FailFastEnvironment extends jestEnvironmentNode.default {
constructor(...rest) {
super(...rest);
this.failed = false;
}
async handleTestEvent(event, state) {
switch (event.name) {
case 'hook_failure':
case 'test_fn_failure':
this.failed = true;
break;
case 'test_start':
if (this.failed) {
event.test.mode = 'skip';
}
break;
default:
}
if (super.handleTestEvent !== undefined) {
await super.handleTestEvent(event, state);
}
}
}
This diff is collapsed.
{
"name": "@unlsoft/homework-5",
"version": "1.0.0",
"description": "Starter code for Homework 5.",
"private": true,
"license": "UNLICENSED",
"scripts": {
"postinstall:eslint-config": "cd eslint-config && npm install",
"postinstall:app": "cd homework-5 && npm install",
"postinstall": "run-s postinstall:**",
"lint:app": "cd homework-5 && npm run lint",
"lint": "run-s --continue-on-error lint:**",
"test-once:dataStructure": "cd homework-5 && npm run test-once:dataStructure",
"test-once:consistency": "cd homework-5 && npm run test-once:consistency",
"test-once:performance": "cd homework-5 && npm run test-once:performance",
"test-once": "cd homework-5 && npm run test-once",
"test": "run-s test-once"
},
"devDependencies": {
"ghooks": "^2.0.4",
"npm-run-all": "^4.1.5"
},
"config": {
"ghooks": {
"pre-commit": "npm run lint"
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment