yay

first commit

node_modules
\ No newline at end of file
{
"name": "hw",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "node src/index.js"
},
"dependencies": {
"fs-extra": "^6.0.1"
}
}
const { assign } = require("./tools");
function searchBlock(state, process) {
let candidates = state
.map((block, key) => assign(block, { key }))
.filter(block => block.id == -1 && block.size >= process.size);
candidates.sort((blockX, blockY) => {
const x = blockY.size;
const y = blockY.size;
if (x < y) return -1;
else if (x > y) return 1;
else return 0;
});
return candidates.length != 0 ? candidates[0].key : -1;
}
const getCapacity = state =>
state
.filter(block => block.id == -1)
.reduce((capacity, block) => capacity + block.size, 0);
function insert(state, process, target) {
const bound = target.from + process.size;
return target.size == process.size
? [assign(target, { id: process.id })]
: [
assign(target, { id: process.id, size: process.size }),
assign(target, { size: target.size - process.size })
];
}
function compact(state) {
const size = getCapacity(state);
return [...state.filter(block => block.id != -1), { id: -1, size }];
}
function allocate(state, process) {
const capacity = getCapacity(state);
if (capacity < process.size) {
throw new Error("OUT OF MEMORY");
}
let idx = searchBlock(state, process);
if (idx == -1) {
state = compact(state);
idx = searchBlock(state, process);
}
const target = state[idx];
const nextState = [
...state.slice(0, idx),
...insert(state, process, target),
...state.slice(idx + 1)
];
const offset = idx;
return nextState;
}
module.exports = allocate;
const { assign } = require("./tools");
function coalscence(state) {
const last = xs => xs[xs.length - 1];
const join = (state, block) => [
...state.slice(0, -1),
{ id: -1, size: block.size + last(state).size }
];
const [firstBlock, ...restBlock] = state;
let idx = -1;
let offset = 0;
const nextState = restBlock.reduce(
(nextState, block) => {
offset += block.size;
if (last(nextState).id == -1 && block.id == -1) {
idx = offset;
return join(nextState, block);
} else {
return [...nextState, block];
}
},
[firstBlock]
);
return nextState;
}
function free(state, pid) {
const nextState = state.map(
block => (block.id == pid ? assign(block, { id: -1 }) : block)
);
return coalscence(nextState);
}
module.exports = free;
const allocate = require("./allocate");
const free = require("./free");
const { printMemory, printStatus } = require("./print");
const parse = require("./parse");
const fs = require("fs");
function run(request, state) {
const { type, payload } = request;
const method = type == "allocate" ? allocate : free;
const head =
type == "allocate"
? `Request ${payload.id}: ${payload.size}K`
: `Free Request ${payload}`;
const nextState = method(state, payload);
printMemory(nextState);
printStatus(nextState);
return nextState;
}
try {
const raw = String(fs.readFileSync("test.txt"));
const { MAX_CAPACITY, requests } = parse(raw);
const init = { id: -1, size: MAX_CAPACITY };
let state = [init];
for (const request of requests) state = run(request, state);
} catch (e) {
console.error(e);
}
function buffer2(xs) {
const ys = xs.filter((_, i) => !(i % 2));
const zs = xs.filter((_, i) => i % 2);
let ws = [];
for (let i = 0; i < ys.length; ++i) {
ws.push([ys[i], zs[i]]);
}
return ws;
}
function parse(raw) {
const [MAX_CAPACITY, rawRequests] = raw.split(/\r?\n/);
const requests = buffer2(rawRequests.split(" ").map(v => parseInt(v))).map(
([id, size]) =>
size
? { type: "allocate", payload: { id, size } }
: { type: "free", payload: id }
);
return { MAX_CAPACITY, requests }
}
module.exports = parse;
\ No newline at end of file
function printMemory(state) {
let addr = 0;
console.log(`----------------`);
for (const block of state) {
if (block.id == -1) {
console.log(`| free |`);
} else {
const pid = `${block.id}`.padStart(6, " ");
console.log(`| pid: ${pid} |`);
}
const size = `${block.size}`.padStart(5, " ");
const from = `${addr}`.padStart(5, " ");
addr += block.size;
const to = `${addr}`.padStart(5, " ");
console.log(`| |`);
console.log(`| size: ${size}K |`);
console.log(`| from: ${from}K |`);
console.log(`| to: ${to}K |`);
console.log(`----------------`);
}
}
function printStatus(state) {
const freeBlocks = state.filter(block => block.id == -1);
const count = freeBlocks.length;
const totalFree = freeBlocks.reduce((z, block) => z + block.size, 0);
console.log(`${totalFree}K free`);
console.log(`${count} block(s)`);
console.log(`Average: ${Math.round(totalFree / count)}\n`);
}
module.exports = { printMemory, printStatus };
const assign = (origin, diff) => Object.assign({}, origin, diff);
module.exports = { assign };
256
1 64 2 64 3 32 4 16 1 0 3 0 5 32 2 0
\ No newline at end of file
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
fs-extra@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.1.tgz#8abc128f7946e310135ddc93b98bddb410e7a34b"
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
universalify "^0.1.0"
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
optionalDependencies:
graceful-fs "^4.1.6"
universalify@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"