1、Validate US Telephone Numbers
如果傳入字串是一個有效的美國電話號碼,則返回 true。
下面是一些有效號碼的例子(還有下面測試時用到的一些變體寫法):
555-555-5555
(555)555-5555
(555) 555-5555
555 555 5555
5555555555
1 555 555 5555
在本節中你會看見如 800-692-7753 or 8oo-six427676;laskdjf這樣的字串。你的任務就是驗證前面給出的字串是否是有效的美國電話號碼。區號是必須有的。 如果字串中給出了國家程式碼, 你必須驗證其是 1。如果號碼有效就返回 true ; 否則返回 false。
解答:
function telephoneCheck(str) {
// Good luck!
var reg=/^1? ?(\d{3}|\(\d{3}\))[ -]?\d{3}[ -]?\d{4}$/;
var res=reg.test(str);
return res;
}
telephoneCheck("2 (757) 622-7382");
2、Symmetric Difference
建立一個函式,接受兩個或多個陣列,返回所給陣列的 對等差分(symmetric difference) (△ or ⊕)陣列。
給出兩個集合 (如集合 A = {1, 2, 3} 和集合 B = {2, 3, 4}), 而數學術語 "對等差分" 的集合就是指由所有隻在兩個集合其中之一的元素組成的集合(A △ B = C = {1, 4})。 對於傳入的額外集合 (如 D = {2, 3}), 你應該安裝前面原則求前兩個集合的結果與新集合的對等差分集合 (C △ D = {1, 4} △ {2, 3} = {1, 2, 3, 4})。
解答:
function sym(args) {
var temp,pos;
var a=Array.from(arguments);
a=a.reduce(function(prev, curv, index, array){
var a = prev.filter(function(item){
return curv.indexOf(item) < 0;
});
var b = curv.filter(function(item){
return prev.indexOf(item) < 0;
});
return a.concat(b);
});
return a.filter(function(item,index,array){
return array.indexOf(item) == index;
});
}
sym([1, 2, 3], [5, 2, 1, 4]);
3、Exact Change
設計一個收銀程式 checkCashRegister() ,其把購買價格(price)作為第一個引數 , 付款金額 (cash)作為第二個引數, 和收銀機中零錢 (cid) 作為第三個引數。
cid 是一個二維陣列,存著當前可用的找零。
當收銀機中的錢不夠找零時返回字串 "Insufficient Funds"。 如果正好則返回字串 "Closed"。否則, 返回應找回的零錢列表,且由大到小存在二維陣列中。
解答:
function checkCashRegister(price, cash, cid) {
var change;
var base=100;//金額基數
change=(cash-price)*base; //找零
//定義一個函式,用來求零錢和。
var getTotalMoney=function(arr){
var s=arr.reduce(function (preV, currV, currIndex, array){
return preV+currV[1];
},0);
return base*s;
};
var remain = getTotalMoney(cid);
if(remain < change){//餘額不足,沒錢找了
return "Insufficient Funds";
}
var baseDollarObj={
"PENNY":1,
"NICKEL":5,
"DIME":10,
"QUARTER":25,
"ONE":100,
"FIVE":500,
"TEN":1000,
"TWENTY":2000,
"ONE HUNDRED":10000
};
var changeArr=[];
var currLast=0;// 當前面值所剩餘額
var currMoney=0;//當前金錢面額
var currtotal=0;//當前零錢可找總額
for (var i=cid.length-1;i>=0;i--){
//當前面值剩餘金額
currLast=cid[i][1]*base;
if (currLast<=0) {
continue;//當前面值的金額剩餘0,跳過
}
currMoney=baseDollarObj[cid[i][0]];
if(change>currMoney){//如果當前金額面值小於應找錢數
if(change<currLast){
currtotal=currMoney*Math.floor(change/currMoney);
}else{
currtotal=currLast;
}
change-=currtotal; //取完之後從應找餘額中減去(張數x面值)
changeArr.push([cid[i][0],currtotal/base]);
}
}
if(change>0){
//找不開的面值
return "Insufficient Funds";
}else if(change===0&&((cash-price)*base==remain)){
//如果零錢數等於應找數額並且可找出來
return "Closed";
}else{
return changeArr;
}
}
checkCashRegister(19.50, 20.00, [["PENNY", 0.50], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]);
4、Inventory Update
依照一個存著新進貨物的二維陣列,更新存著現有庫存(在 arr1 中)的二維陣列。 如果貨物已存在則更新數量 。如果沒有對應貨物則把其加入到陣列中,更新最新的數量。返回當前的庫存陣列,且按貨物名稱的字母順序排列。
解答:
function updateInventory(arr1, arr2) {
// All inventory must be accounted for or you're fired!
arr2=arr2.filter(function(v){
var res=true;
for(var i=0;i<arr1.length;i++){
if(v[1]===arr1[i][1]){
arr1[i][0]=arr1[i][0]+v[0];
res= false;
break;
}
}
return res;
});
arr1=arr1.concat(arr2);
arr1.sort(function(a,b){
return a[1].charCodeAt(0)-b[1].charCodeAt(0);
});
return arr1;
}
// Example inventory lists
var curInv = [
[21, "Bowling Ball"],
[2, "Dirty Sock"],
[1, "Hair Pin"],
[5, "Microphone"]
];
var newInv = [
[2, "Hair Pin"],
[3, "Half-Eaten Apple"],
[67, "Bowling Ball"],
[7, "Toothpaste"]
];
updateInventory(curInv, newInv);
5、No repeats please
把一個字串中的字元重新排列生成新的字串,返回新生成的字串裡沒有連續重複字元的字串個數.連續重複只以單個字元為準。
例如, aab 應該返回 2 因為它總共有6中排列 (aab, aab, aba, aba, baa, baa), 但是隻有兩個 (aba and aba)沒有連續重複的字元 (在本例中是 a)。
思路:
全排列recoper函式:對於每一個輸入的str,我們把它分為兩部分,第一部分為字串的第一個字母,定義為left,第二部分為剩餘的字串,定義為rest。返回str的全排列陣列。
遞迴思路:遞迴recoper。
解答:
function permAlone(str) {
var perarr=[];
//建立正則,如果字串全重複,則直接return 0
var reg = /(.)\1+/g;
if (str.match(reg) !== null && str.match(reg)[0] === str) {
return 0;
}
function recoper(str) {
var arr = [];//存放str的全排列
if (str.length > 1) {
var left = str[0];
var rest = str.slice(1, str.length);
//獲取rest字串的全排列
var perRes = recoper(rest);
var pl = perRes.length,
pil, s;
for (var i = 0; i < pl; i++) {
s = perRes[i];
pil = perRes[i].length;
for (var j = 0; j <=pil; j++) {
var tmp = s.substring(0, j) + left + s.substring(j, pl);
arr.push(tmp);
}
}
} else if (str.length == 1) {
arr = [str];
}
return arr;
}
perarr=recoper(str);
//返回相鄰不重複的數量
return perarr.filter(function(val) {
return !val.match(reg);
}).length;
}
permAlone('aab');
6、Friendly Date Ranges
把常見的日期格式如:YYYY-MM-DD 轉換成一種更易讀的格式。
易讀格式應該是用月份名稱代替月份數字,用序數詞代替數字來表示天 (1st 代替 1)。
記住不要顯示那些可以被推測出來的資訊: 如果一個日期區間裡結束日期與開始日期相差小於一年,則結束日期就不用寫年份了。月份開始和結束日期如果在同一個月,則結束日期月份就不用寫了。另外, 如果開始日期年份是當前年份,且結束日期與開始日期小於一年,則開始日期的年份也不用寫。
解答:
function makeFriendlyDates(arr) {
var dateArr = ["", "1st", "2nd", "3rd", "4th", "5th", "6th", "7th", "8th", "9th", "10th",
"11th", "12th", "13th", "14th", "15th", "16th", "17th", "18th", "19th", "20th",
"21st", "22nd", "23rd", "24th", "25th", "26th", "27th", "28th", "29th", "30th",
"31st"
],
monthArr = ["", "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
],
resarr = [],
startTime = arr[0].replace(/-/g, "/"),
endTime = arr[1].replace(/-/g, "/");
var newa = new Date(startTime);
var newb = new Date(endTime);
//判斷日期區間是否合理,不合理,直接返回。
if (newa.getTime() > newb.getTime()) {
return;
}
//判斷是否相差小於一年,true為相差小於一年。
var caldate = function() {
newa.setFullYear(newa.getFullYear() + 1);
if (newa.getTime() <= newb) {
return true;
} else {
return false;
}
};
var a = arr[0].replace(/-0?/g, " ").split(" "),
b = arr[1].replace(/-0?/g, " ").split(" "),
nowYear = new Date().getFullYear();
var str1 = monthArr[a[1]] + " " + dateArr[a[2]],
str2 = dateArr[b[2]];
var morethanoneyear = caldate();
if (!morethanoneyear) {
if (a[0] != nowYear) {
//開始日期年份不是當前年份
str1 = str1 + ", " + a[0];
}
if ((a[1] === b[1]) && (a[2] === b[2])) {
//同年同月同日
str2 = "";
} else if (!((a[1] === b[1]) && (parseInt(a[2]) < parseInt(b[2])))) {
str2 = monthArr[b[1]] + " " + str2;
}
} else {
//相差超過一年
str1 = str1 + ", " + a[0];
str2 = monthArr[b[1]] + " " + str2 + ", " + b[0];
}
if (str2 !== "") {
resarr.push(str1, str2);
} else {
resarr.push(str1);
}
return resarr;
}
makeFriendlyDates(["2017-01-02", "2017-01-05"])
7、Make a Person
用下面給定的方法構造一個物件。方法有 getFirstName(), getLastName(),getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast)。所有有引數的方法只接受一個字串引數。所有的方法只與實體物件互動。
解答:
var Person = function(firstAndLast) {
var firstAndLastarr=firstAndLast.split(" "), firstName=firstAndLastarr[0],
lastName=firstAndLastarr[1];
this.getFirstName=function(){
return firstName;
};
this.getLastName=function(){
return lastName;
};
this.getFullName=function(){
firstAndLastarr[0]=firstName;
firstAndLastarr[1]=lastName;
return firstAndLastarr.join(" ");
};
this.setFirstName=function(first){
firstName=first;
};
this.setLastName=function(last){
lastName=last;
};
this.setFullName=function(firstAndLast){
firstAndLastarr=firstAndLast.split(" ");
firstName=firstAndLastarr[0];
lastName=firstAndLastarr[1];
};
};
var bob = new Person('Bob Ross');
bob.getFirstName();
8、Map the Debris
返回一個陣列,其內容是把原陣列中對應元素的平均海拔轉換成其對應的軌道週期。
原陣列中會包含格式化的物件內容,像這樣 {name: 'name', avgAlt: avgAlt}
。
解答:
function orbitalPeriod(arr) {
var GM = 398600.4418;
var earthRadius = 6367.4447;
for(var i=0;i<arr.length;i++){
var R=arr[i].avgAlt+earthRadius;
var T=R*2*Math.PI*Math.sqrt((R/GM));
delete arr[i].avgAlt;
arr[i].orbitalPeriod=Math.round(T);
}
return arr;
}
orbitalPeriod([{name : "sputnik", avgAlt : 35873.5553}]);
9、Pairwise
有一個能力陣列[7,9,11,13,15],按照最佳組合值為20來計算,只有7+13和9+11兩種組合。而7在陣列的索引為0,13在陣列的索引為3,9在陣列的索引為1,11在陣列的索引為2。
所以我們說函式:pairwise([7,9,11,13,15],20) 的返回值應該是0+3+1+2的和,即6。
第一種解答:
function pairwise(arr, arg) {
var a = arr.reduce(function(prev, currv, index, array) {
var l = array.length;
for (var i = index + 1; i < l; i++) {
if (array[index] + array[i] === arg) {
arr[index] = "false";
arr[i] = "false";
return prev + i + index;
}
}
return prev;
}, 0);
return a;
}
pairwise([1,4,2,3,0,5], 7);
第二種解答:
function pairwise(arr, arg) {
var l=arr.length,res=0;
for(var i=0;i<l;i++){
for(var j=i+1;j<l;j++){
if(arr[i]+arr[j]===arg){
res=res+i+j;
arr[i]="false";
arr[j]="false";
}
}
}
return res;
}
pairwise([1,4,2,3,0,5], 7);