Skip to content

Commit 5cf4d14

Browse files
author
kennyledet
committed
Merge pull request kennyledet#402 from aaronabf/master
Added Javascript implemented for 4 problems
2 parents f679d85 + 8f927b2 commit 5cf4d14

File tree

4 files changed

+179
-0
lines changed

4 files changed

+179
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Author: Aaron Friedlander 2014
2+
3+
// Problem: You have 100 doors in a row that are all initially closed. You make
4+
// 100 passes by the doors. The first time through, you visit every door and
5+
// toggle the door (if the door is closed, you open it; if it is open, you
6+
// close it). The second time you only visit every 2nd door (door #2, #4, #6,
7+
// ...). The third time, every 3rd door (door #3, #6, #9, ...), etc, until you
8+
// only visit the 100th door.
9+
10+
// Question: What state are the doors in after the last pass? Which are open,
11+
// which are closed?
12+
13+
// Implemented in two ways:
14+
// 1) Loop through array of "doors" opening respective doors in each iteration
15+
// 2) The only doors that remain open are whose numbers are perfect squares.
16+
// Using this knowledge, only doors with indices of a perfect square + 1 are
17+
// opened.
18+
19+
function run(numberOfDoors) {
20+
// Array to represent the doors: false represents closed, true represents open
21+
var doors = Array.apply(null, new Array(numberOfDoors)).map(Boolean.prototype.valueOf,false);
22+
23+
// Run algorithms
24+
var doorOutcome1 = iterateDoors(doors);
25+
var doorOutcome2 = perfectSquareDoors(doors);
26+
27+
// Print out results
28+
if (doorOutcome1 === doorOutcome2) {
29+
for (var i = 0; i < numberOfDoors; i++) {
30+
var doorNum = i + 1;
31+
var doorVal = doorOutcome1[i] ? 'Open' : 'Closed';
32+
console.log('Door #' + doorNum + ' is ' + doorVal);
33+
}
34+
} else {
35+
console.log('There was a issue in the algorithm');
36+
}
37+
}
38+
39+
function iterateDoors(doors) {
40+
for (var pass = 0; pass < doors.length; pass++) {
41+
for (var i = pass; i < doors.length; i += (pass + 1)) {
42+
doors[i] = !doors[i];
43+
}
44+
}
45+
46+
return doors;
47+
}
48+
49+
function isPerfectSquare(num) {
50+
// Javascript trick for determining if a number is a perfect square
51+
var sqrt = Math.sqrt(num);
52+
return (sqrt === (sqrt | 0));
53+
}
54+
55+
function perfectSquareDoors(doors) {
56+
for (var i = 0; i < doors.length; i++) {
57+
if (isPerfectSquare(i+1)) {
58+
doors[i] = true;
59+
}
60+
}
61+
62+
return doors;
63+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Author: Aaron Friedlander 2014
2+
3+
// A function that memoizes a function
4+
// Adapted from my code here https://github.com/aaronabf/memoization/blob/master/memoizer.js
5+
6+
// Stores cached results
7+
var dict = {};
8+
9+
// Memoizes a function
10+
function memoizer(f) {
11+
function newFunction(n) {
12+
if (dict[n]) {
13+
return dict[n];
14+
}
15+
16+
var newVal = f(newFunction, n);
17+
dict[n] = newVal;
18+
return newVal;
19+
}
20+
21+
return newFunction;
22+
}
23+
24+
// Test on fibonnaci
25+
function fibMemo(g, n) {
26+
if (n === 0) {
27+
return 0;
28+
} else if (n === 1) {
29+
return 1;
30+
} else {
31+
return g(n-2) + g(n-1);
32+
}
33+
}
34+
var fib = memoizer(fibMemo);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Author: Aaron Friedlander 2014
2+
3+
// A function that memoizes a function
4+
// Adapted from my code here https://github.com/aaronabf/n-queens/blob/master/n_queen.js
5+
6+
// To test on 8 queens:
7+
// console.log(attemp(8));
8+
9+
// Main function, abstracted helper function
10+
function attemp(n) {
11+
return try1(point(1,1), n, []);
12+
}
13+
14+
// Converts two numbers into a "point" object
15+
function point(x,y) {
16+
return { i : x, j : y };
17+
}
18+
19+
// Tests that the point does not conflict with any other points on the board
20+
function conflict(p1, board) {
21+
return board.some(function(p2) {
22+
return ((p1.i === p2.i) ||
23+
(p1.j === p2.j) ||
24+
(p1.i - p1.j === p2.i - p2.j) ||
25+
(p1.i + p1.j === p2.i + p2.j));
26+
});
27+
}
28+
29+
// First mutual recursive function, helps construct array of points
30+
function try1(p, n, board) {
31+
var results = try2(p, n, board);
32+
33+
if (results) {
34+
return results;
35+
} else if (p.j === n) {
36+
return false;
37+
} else {
38+
return try1(point(p.i, p.j+1), n, board);
39+
}
40+
}
41+
42+
// Second mutual recursive function, helps construct array of points
43+
function try2(p, n, board) {
44+
if (conflict(p, board)) {
45+
return false;
46+
} else if (p.i === n) {
47+
board.unshift(p);
48+
return board;
49+
} else {
50+
var boardCopy = board.slice(0);
51+
boardCopy.unshift(p);
52+
return try1(point(p.i+1, 1), n, boardCopy);
53+
}
54+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// ALL CREDIT GOES TO Steven Levithan @ http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
2+
3+
function romanize (num) {
4+
if (!+num)
5+
return false;
6+
var digits = String(+num).split(""),
7+
key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
8+
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
9+
"","I","II","III","IV","V","VI","VII","VIII","IX"],
10+
roman = "",
11+
i = 3;
12+
while (i--)
13+
roman = (key[+digits.pop() + (i * 10)] || "") + roman;
14+
return Array(+digits.join("") + 1).join("M") + roman;
15+
}
16+
17+
function deromanize (str) {
18+
var str = str.toUpperCase(),
19+
validator = /^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/,
20+
token = /[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,
21+
key = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},
22+
num = 0, m;
23+
if (!(str && validator.test(str)))
24+
return false;
25+
while (m = token.exec(str))
26+
num += key[m[0]];
27+
return num;
28+
}

0 commit comments

Comments
 (0)