高級腳本算法挑戰

地址:https://www.w3cschool.cn/codecamp/list?pename=advanced_algorithm_scripting_camp程序員

判斷電話號碼算法挑戰:
若是傳入字符串是一個有效的美國電話號碼,則返回 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) {
    return /^1?\s?(\(\d{3}\)|\d{3})[-|\s]*\d{3}[-|\s]*\d{4}$/.test(str);
    //return /^1? ?(\d{3}|\(\d{3}\))[ -]?\d{3}[ -]?\d{4}$/.test(str);
}
telephoneCheck("555-555-5555");

集合交集算法挑戰:
建立一個函數,接受兩個或多個數組,返回所給數組的 對等差分(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(result,...args) {
    for(let i=0,j=args.length;i<j;i++)
    {
        result = result.filter(a=>args[i].indexOf(a)<0).concat(args[i].filter(a=>result.indexOf(a)<0));
        result = [...new Set(result)];
    }
    return result;
}

sym([1, 2, 3], [5, 2, 1, 4]);

收銀系統算法挑戰:
設計一個收銀程序 checkCashRegister() ,其把購買價格(price)做爲第一個參數 , 付款金額 (cash)做爲第二個參數, 和收銀機中零錢 (cid) 做爲第三個參數.
cid 是一個二維數組,存着當前可用的找零.
當收銀機中的錢不夠找零時返回字符串 "Insufficient Funds". 若是正好則返回字符串 "Closed".
否者, 返回應找回的零錢列表,且由大到小存在二維數組中.數組

function checkCashRegister(price, cash, cid) {
    //排序
    //cid.sort(function(a,b){ return b[1]-a[1]});
    //求和
    let sum = 100 * cid.reduce(function(a,b){ return Array.isArray(a)?a[1]+b[1]:a+b[1];})
    let diff =100 * (cash - price);
    if(sum > diff)
    {
        let result = [];
        let num = 0;
        let initMoney = 100 * cid[8][1];
        let outMoney = 0;
        while(diff>=10000)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 10000;
           diff -= 10000;
           initMoney -=10000;
        }
        if(num>0)
        {
            result.push(["ONE HUNDRED",Number(outMoney/100)]);
        }

        num = 0;
        initMoney = 100 * cid[7][1];
        outMoney = 0;
        while(diff>=2000)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 2000;
           diff -= 2000;
           initMoney -=2000;
        }
        if(num>0)
        {
            result.push(["TWENTY",Number(outMoney/100)]);
        }
        
        num = 0;
        initMoney = 100 * cid[6][1];
        outMoney = 0;
        while(diff>=1000)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 1000;
           diff -= 1000;
           initMoney -=1000;
        }
        if(num>0)
        {
            result.push(["TEN",Number(outMoney/100)]);
        }

        num = 0;
        initMoney = 100 * cid[5][1];
        outMoney = 0;
        while(diff>=500)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 500;
           diff -= 500;
           initMoney -=500;
        }
        if(num>0)
        {
            result.push(["FIVE",Number(outMoney/100)]);
        }
        
        num = 0;
        initMoney = 100 * cid[4][1];
        outMoney = 0;
        while(diff>=100)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 100;
           diff -= 100;
           initMoney -=100;
        }
        if(num>0)
        {
            result.push(["ONE",Number(outMoney/100)]);
        }
        
        num = 0;
        initMoney = 100 * cid[3][1];
        outMoney = 0;
        while(diff>= 25)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 25;
           diff -= 25;
           initMoney -= 25;
        }
        if(num>0)
        {
            result.push(["QUARTER",Number(outMoney/100)]);
        }
        
        num = 0;
        initMoney = 100 * cid[2][1];
        outMoney = 0;
        while(diff>=10)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 10;
           diff -= 10;
           initMoney -= 10;
        }
        if(num>0)
        {
            result.push(["DIME",Number(outMoney/100)]);
        }
        
        num = 0;
        initMoney = 100 * cid[1][1];
        outMoney = 0;
        while(diff>=5)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 5;
           diff -= 5;
           initMoney -= 5;
        }
        if(num>0)
        {
            result.push(["NICKEL",Number(outMoney/100)]);
        }
        
        num = 0;
        initMoney = 100 * cid[0][1];
        outMoney = 0;
        while(diff>=1)
        {
           if(initMoney<=0)
           {
               break;
           }
           num++;
           outMoney += 1;
           diff -= 1;
           initMoney -=1;
        }
        console.log(diff);
        if(num>0)
        {
            result.push(["PENNY",Number(outMoney/100)]);
        }

        if(diff>0)
        {
             return "Insufficient Funds";
        }
        return result;
    }
    else if(sum == diff){
        return "Closed";
    }
    else
    {
        return "Insufficient Funds";
    }
    
}

checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]);

庫存更新算法挑戰:
依照一個存着新進貨物的二維數組,更新存着現有庫存(在 arr1 中)的二維數組. 若是貨物已存在則更新數量 . 若是沒有對應貨物則把其加入到數組中,更新最新的數量. 返回當前的庫存數組,且按貨物名稱的字母順序排列.函數

function updateInventory(arr1, arr2) {
    let result = arr2;
    if(arr2.length == 0)
    {
        return arr1;
    }
    let arr = [];
    arr2.reduce(function(a,b){if(a!=undefined){arr.push(a[1]);}arr.push(b[1]);});
    for(let i = 0 ,j=arr1.length;i<j;i++)
    {
        var index = arr.indexOf(arr1[i][1]);
        if ( index < 0 )
        {
            result.push(arr1[i]);
        }
        else
        {
            
            result = result.slice(0,index).concat([[result.slice(index,index+1)[0][0]+arr1[i][0],result.slice(index,index+1)[0][1]]]).concat(result.slice(index+1,result.length));
        }
    }
    result.sort(function(a,b){return b[1]<a[1]});
    console.log(result);
    return result;
}

// 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);

 排列組合去重算法挑戰:
把一個字符串中的字符從新排列生成新的字符串,返回新生成的字符串裏沒有連續重複字符的字符串個數.連續重複只以單個字符爲準
例如, aab 應該返回 2 由於它總共有6中排列 (aab, aab, aba, aba, baa, baa), 可是隻有兩個 (aba and aba)沒有連續重複的字符 (在本例中是 a).測試

function permAlone(str) {
   let result = [];
   for(let i=0,j=str.length;i<j;i++)
   {
       if(i==0){    
           result.push([str[i]]);
           continue;
       }
       let temp = result.concat();
       result = [];
       for(let i1 = 0,j1 = temp.length; i1 < j1; i1++)
       {
           for(let i2 = 0,j2 = temp[i1].length ; i2<=j2 ;i2++)
           {
                result.push(temp[i1].slice(0,i2).concat([str[i]]).concat(temp[i1].slice(i2,j2)));
           }
       }
   }
   
   let count = 0;
   for(let i = 0,j=result.length;i<j;i++)
   {
       for(let i1=0,j1=result[i].length;i1<j1-1;i1++)
       {
           if(result[i][i1]==result[i][i1+1])
           {
               break;
           }
           else if(i1==j1-2)
           {
               count++;
           }
       }
   }
   
   return count;
}

permAlone('aab');

日期改寫算法挑戰:
讓日期區間更友好!
把常見的日期格式如:YYYY-MM-DD 轉換成一種更易讀的格式。
易讀格式應該是用月份名稱代替月份數字,用序數詞代替數字來表示天 (1st 代替 1).
記住不要顯示那些能夠被推測出來的信息: 若是一個日期區間裏結束日期與開始日期相差小於一年,則結束日期就不用寫年份了。月份開始和結束日期若是在同一個月,則結束日期月份就不用寫了。
另外, 若是開始日期年份是當前年份,且結束日期與開始日期小於一年,則開始日期的年份也不用寫。
例如:
makeFriendlyDates(["2016-07-01", "2016-07-04"]) 應該返回 ["July 1st, 2016","4th"]
makeFriendlyDates(["2016-07-01", "2018-07-04"]) 應該返回 ["July 1st, 2016", "July 4th, 2018"].this

function makeFriendlyDates(arr) {
    let result = [];
    let year;
    let month;
    let day;
    for(let i =0,j=arr.length;i<j;i++)
    {
        if(i==0)
        {
            arr[i].split("-").reduce(function(a,c,i){if(a!=undefined){year=a;} if(i==1){month=c;}else{day=c;}});
            result.push(getMonth(month)+" "+Number(day)+getDay(day)+", "+year);
        }
        else if(i==1)
        {
            let tempYear,tempMonth,tempDay;
            arr[i].split("-").reduce(function(a,c,i){if(a!=undefined){tempYear=a;} if(i==1){tempMonth=c;}else{tempDay=c;}});
            
            let oneYear = new Date(year-1,month,day).getTime() < new Date(tempYear,tempMonth,tempDay).getTime() && new Date(Number(year)+1,month,day).getTime()> new Date(tempYear,tempMonth,tempDay).getTime() ;
            if(tempYear != year && !oneYear )
            {
                result.push(getMonth(tempMonth)+" "+Number(tempDay)+getDay(tempDay)+", "+tempYear);
            }
            else if(tempMonth != month || (tempYear != year && oneYear && tempMonth == month) )
            {
                result.push(getMonth(tempMonth)+" "+Number(tempDay)+getDay(tempDay));
            }
            else if(tempDay != day)
            {
                result.push(Number(tempDay)+getDay(tempDay));
            }
        }
    }
    return result;
}

function getMonth(month)
{
    switch (month) {
        case '01':
            return  "January"
            break;
        case '02':
            return  "February"
            break;
        case '03':
            return  "March"
            break;
        case '04':
            return  "April"
            break;
        case '05':
            return  "May"
            break;
        case '06':
            return  "June"
            break;
        case '07':
            return  "July"
            break;
        case '08':
            return  "August"
            break;
        case '09':
            return  "September"
            break;
        case '10':
            return  "October"
            break;
        case '11':
            return  "November"
            break;
        case '12':
            return  "December"
            break;
        default:
            return "";
    }
}

function getDay(day)
{
    switch (day) {
        case '01':
        case '21':
        case '31':
            return  "st"
            break;
        case '02':
        case '22':
            return  "nd"
            break;
        case '03':
        case '23':
            return  "rd"
            break;
        default:
            return "th";
    }
}
makeFriendlyDates(['2016-07-01', '2016-07-04']);

 類及對象構建算法挑戰:
用下面給定的方法構造一個對象.
方法有 getFirstName(), getLastName(), getFullName(), setFirstName(first), setLastName(last), and setFullName(firstAndLast).
全部有參數的方法只接受一個字符串參數.
全部的方法只與實體對象交互.spa

var Person = function(firstAndLast) {
    this.getFirstName= function(){ return firstAndLast.split(" ")[0]} ,
    this.getLastName=function(){return firstAndLast.split(" ")[1]} ,
    this.getFullName= function(){ return firstAndLast;} ,
    this.setFirstName= function(first){ firstAndLast=first+" "+firstAndLast.split(" ")[1]; } ,
    this.setLastName= function(last){firstAndLast=firstAndLast.split(" ")[0]+" "+last; } ,
    this.setFullName=function(full){    
        firstAndLast=full;
    } 
};

var bob = new Person('Bob Ross');
bob.getFullName();

軌道週期算法挑戰

返回一個數組,其內容是把原數組中對應元素的平均海拔轉換成其對應的軌道週期.設計

原數組中會包含格式化的對象內容,像這樣 {name: 'name', avgAlt: avgAlt}.code

至於軌道週期怎麼求,戳這裏 on wikipedia (不想看英文的話能夠自行搜索以軌道高度計算軌道週期的公式).

求得的值應該是一個與其最接近的整數,軌道是以地球爲基準的.

地球半徑是 6367.4447 kilometers, 地球的GM值是 398600.4418, 圓周率爲Math.PI

function orbitalPeriod(arr) {
    var GM = 398600.4418;
    var earthRadius = 6367.4447;
    var newArr = [];
    for(var i in arr){
        period = Math.round(2 * Math.PI * Math.pow(Math.pow((earthRadius + arr[i].avgAlt), 3)/GM , 0.5));
        newArr.push({name : arr[i].name , orbitalPeriod : period});
    }
    return newArr;
}

orbitalPeriod([{name : "sputnik", avgAlt : 35873.5553}]);

數據組合求值算法挑戰:
找到你的另外一半

都說優秀的程序員擅長面向對象編程,但卻常常找不到另外一半,這是爲何呢?由於你老是把本身侷限成爲一個程序員,沒有打開本身的思惟。

這是一個社羣的時代啊,在這裏你應該找到與你有相同價值觀但又互補的另外一半。

譬如:你編程能力強,估值11分,若是以20分爲最佳情侶來計算,你應該找一個設計能力強,估值爲9分的女生。

那麼當你遇到一個設計能力爲9分的女生,千萬別猶豫,大膽去表白。千萬別覺得後面的瓜比前面的甜哦。

舉個例子:有一個能力數組[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。

咱們能夠經過表格來更直觀地查看數組中索引和值的關係:

Index 0 1 2 3 4
Value 7 9 11 13 15

任務:幫右邊的pairwise函數實現上面的功能。

function pairwise(arr, arg) {
    var newArr = [];
    for (var i = 0; i < arr.length; i++) {
        var arrObj = {};
        arrObj.num = i;
        arrObj.value = arr[i];
        newArr.push(arrObj);
    }
    var count = 0;
    var arrLength = newArr.length;
    for (var j = 0; j < arrLength; j++) {
        for (var k = j + 1; k < arrLength; k++) {
            if (Number(newArr[j].value) + Number(newArr[k].value) == arg) {
                count  = count + newArr[j].num + newArr[k].num;
                // console.log(count);
                newArr.splice(k,1);
                arrLength--;
                newArr.splice(j,1);
                arrLength--;
                j--;
                k-=2;
                break;
            }
        }
    }
    return count;
}

pairwise([1,4,2,3,0,5], 7);
相關文章
相關標籤/搜索