Intermediate Algorithm Scripting (50 hours)中級算法腳本練習

1.Sum All Numbers in a Range,兩個數之間所有數加起來

sumAll([1, 4]) 應該返回一個數字。
sumAll([1, 4]) 應該返回 10。
sumAll([4, 1]) 應該返回 10。

function sumAll(arr) {
  arr.sort(function(a,b){
    return a-b;
  });
  var max=arr[1];
  var min=arr[0];
  var num=max-min+1;
  return (min+max)*num/2;
}
sumAll([1, 4]);

2.Diff Two Arrays,比較,返回差異值組成的數組。

[1, 2, 3, 5], [1, 2, 3, 4, 5] 應該返回 [4]。
(做複雜了…)

  var newArr = [];
  var num1=arr1.length;
  var num2=arr2.length;
  var sameArr=[];
  for(i=0;i<num1;i++){
    for(j=0;j<num2;j++){
      if(arr1[i]==arr2[j]){
        sameArr.push(arr1[i]);
      }
    }
  }
  上面找出了相同的~
  下面找不同的~

  for(i=0;i<num1;i++){
    if(arr2.indexOf(arr1[i])==-1){
      newArr.push(arr1[i]);
    }
  }
  for(i=0;i<num2;i++){
    if(arr1.indexOf(arr2[i])==-1){
      newArr.push(arr2[i]);
    }
  }
  return newArr;
}

3.Roman Numeral Converter隨機數字轉化爲羅馬數字

(數字和字符串不能相乘,else if,前面判斷了==4,後面直接<9,不要4< x<9要出錯)
convert(1006) 應該返回 “MVI”。
convert(1023) 應該返回 “MXXIII”。
convert(2014) 應該返回 “MMXIV”。
convert(3999) 應該返回 “MMMCMXCIX”。

  var a=0;
  var b=0;
  var c=0;
  var d=0;

  var y=num.toString();   
var newN=y.split("");//數字分開成數組['3','6']
  var num1=newN.length;
   if(num1==1){
    d=num;
  }else if(num1==2){
    c=parseInt(newN[0]);
    d=parseInt(newN[1]);
  }else if(num1==3){
    b=parseInt(newN[0]);
    c=parseInt(newN[1]);
    d=parseInt(newN[2]);
  }else if(num1==4){
    a=parseInt(newN[0]);
    b=parseInt(newN[1]);
    c=parseInt(newN[2]);
    d=parseInt(newN[3]);
  }
  var rea="";
  var reb="";
  var rec="";
  var red="";
  for(i=1;i<=a;i++){
    rea=rea+"M";
  }

  if(b<4){
 for(i=1;i<=b;i++){
    reb=reb+"C";
  }
  }else if(b==4){
    reb="CD";
  }else if(b<9){
    reb="D";
    for(i=1;i<=b-5;i++){
    reb=reb+"C";
  }
  }else if(b==9){
    reb="CM";
  }

    if(c<4){
    for(i=1;i<=c;i++){
    rec=rec+"X";
  }
  }else if(c==4){
    rec="XL";
  }else if(c<9){
    rec="L";
    for(i=1;i<=c-5;i++){
      rec=rec+"X";
    }
  }else if(c==9){
    rec="XC";
  }
    if(d<4){
    for(i=1;i<=d;i++){
    red=red+"I";
  }
  }else if(d==4){
    red="IV";
  }else if(d<9){
        red="V";
    for(i=1;i<=d-5;i++){
      red=red+"I";}
  }else if(d==9){
    red="IX";
  } 
 var result=rea+reb+rec+red;
 return result;
}

4.Where art thou

寫一個 function,它遍歷一個對象數組(第一個參數)並返回一個包含相匹配的屬性-值對(第二個參數)的所有對象的數組。如果返回的數組中包含 source 對象的屬性-值對,那麼此對象的每一個屬性-值對都必須存在於 collection 的對象中。
- where([{ first: “Romeo”, last: “Montague” }, { first: “Mercutio”, last: null }, { first: “Tybalt”, last: “Capulet” }], { last: “Capulet” }) 應該返回 [{ first: “Tybalt”, last: “Capulet” }]。
- where([{ “a”: 1 }, { “a”: 1 }, { “a”: 1, “b”: 2 }], { “a”: 1 }) 應該返回 [{ “a”: 1 }, { “a”: 1 }, { “a”: 1, “b”: 2 }]。

function where(collection, source) {
  var arr = [];
  var count=0;
  // What's in a name?
  var keys=Object.keys(source);//返回source的屬性key組成的數組
  for(i=0;i<collection.length;i++){
    for(j=0;j<keys.length;j++){
      if(collection[i].hasOwnProperty(keys[j])===true){
        if(collection[i][keys[j]] == source[keys[j]]){ //後來更正的地方1
          count++;
        }
      }
    }
    if(count==keys.length){
      arr.push(collection[i]);
    }
    count=0;  //後來更正的地方2
  }
  return arr;
}

5.Search and Replace

使用給定的參數對句子執行一次查找和替換,然後返回新句子。
第一個參數是將要對其執行查找和替換的句子。
第二個參數是將被替換掉的單詞(替換前的單詞)。
第三個參數用於替換第二個參數(替換後的單詞)。
注意:替換時保持原單詞的大小寫。例如,如果你想用單詞 “dog” 替換單詞 “Book” ,你應該替換成 “Dog”。

function myReplace(str, before, after) {
  str=str.split(" ");
  var re=/[A-Z]/;
  var x=before.split("");//before首字母
  var y=after.split("");
  if(x[0].match(re)!==null){//before是大寫的,則
    y[0]=y[0].toUpperCase();//after首字母大寫
    after=y.join("");
  }
  for(i=0;i<str.length;i++){
    if(str[i]==before){
      str[i]=after;
    }
  }
  str=str.join(" ");
  return str;
}

6.Pig Latin

Pig Latin 把一個英文單詞的第一個輔音或輔音叢(consonant cluster)移到詞尾,然後加上後綴 “ay”。
如果單詞以元音開始,你只需要在詞尾添加 “way” 就可以了。
translate(“glove”) 應該返回 “oveglay”。
translate(“algorithm”) 應該返回 “algorithmway”。

  var newstr=str.split("");
  var yuan=["a","e","i","o","u"];//元音組
  var fu="";//輔音組
  var remain="";//剩下的
  for(i=0;i<str.length;i++){
    if(yuan.indexOf(newstr[i])!==-1){
      fu=str.substr(0,i);
      remain=str.substr(i);
      break;
    }
  }
  if(fu===""){
    str=str+"way";
  }else{
    str=remain+fu+"ay";
  }
  return str;
}

7.DNA Pairing

DNA 鏈缺少配對的鹼基。依據每一個鹼基,爲其找到配對的鹼基,然後將結果作爲第二個數組返回。
Base pairs(鹼基對) 是一對 AT 和 CG,爲給定的字母匹配缺失的鹼基。
在每一個數組中將給定的字母作爲第一個鹼基返回。
例如,對於輸入的 GCG,相應地返回 [[“G”, “C”], [“C”,”G”],[“G”, “C”]]

function pair(str) {
  var pairs=[];
  var newStr=str.split("");
  for(i=0;i<newStr.length;i++){
    if(newStr[i]=="G"){
      pairs.push(["G","C"]);
    }
    if(newStr[i]=="C"){
      pairs.push(["C","G"]);
    }
    if(newStr[i]=="A"){
      pairs.push(["A","T"]);
    }
    if(newStr[i]=="T"){
      pairs.push(["T","A"]);
    }
  }
  return pairs;
}

8.Missing letters

從傳遞進來的字母序列中找到缺失的字母並返回它。
如果所有字母都在序列中,返回 undefined。

function fearNotLetter(str) {
  var newStr=str.split("");
  var results=[];
  var missingLetter=undefined;
  for(i=0;i<newStr.length;i++){
    var x=str.charCodeAt(i);//挨着挨着返回數字
    results.push(x);
  }
  for(i=0;i<results.length-1;i++){
    if(results[i+1]-results[i]!==1){
      missingLetter=String.fromCharCode(results[i]+1);
      break;
    }
  }
  return missingLetter;
}

9.Sorted Union

unite([1, 3, 2], [5, 2, 1, 4], [2, 1]) 應該返回 [1, 3, 2, 5, 4]。
unite([1, 3, 2], [1, [5]], [2, [4]]) 應該返回 [1, 3, 2, [5], [4]]。

function unite(arr) {
  //因爲arr的數量不定,所以要用到arguments
  var arr1=arguments[0];
  for(i=0;i<arguments.length-1;i++){
    for(j=0;j<arguments[i+1].length;j++){
      if(arr1.indexOf(arguments[i+1][j])==-1){
        arr1.push(arguments[i+1][j]);
      }
    }
  } 
  return arr1;
}

10.Spinal Tap Case

將字符串轉換爲 spinal case。Spinal case 是 all-lowercase-words-joined-by-dashes 這種形式的,也就是以連字符連接所有小寫單詞。
spinalCase(“thisIsSpinalTap”) 應該返回 “this-is-spinal-tap”。
spinalCase(“The_Andy_Griffith_Show”) 應該返回 “the-andy-griffith-show”。

function spinalCase(str) {
  // "It's such a fine line between stupid, and clever."
  // --David St. Hubbins
  //通過大寫字母或者空格區分單詞
  //找到了後轉小寫再連起來;
  var newstr=str.split("");
  var re=/[A-Za-z]/g;//通過判斷空格或其他符號,將其變成"-"
  var rex=/[A-Z]/g;
  var count=1;
  for(i=0;i<newstr.length;i++){
    if(newstr[i].match(re)===null){
      newstr[i]="-";
      count++;
    } 
  }
  if(count===1){
    for(j=0;j<newstr.length;j++){
      if(newstr[j].match(rex)!==null){
        newstr.splice(j,0,"-");//這一句爲什麼bao無限循環?
        j++;//這一句賊關鍵!因爲splice會增加或者減少數組的長度,所有j應該跟着變纔對
      }
    }
  }
  str=newstr.join("").toLowerCase();
  return str;
}

11.Sum All Odd Fibonacci Numbers

給一個正整數num,返回小於或等於num的斐波納契奇數之和。
斐波納契數列中的前幾個數字是 1、1、2、3、5 和 8,隨後的每一個數字都是前兩個數字之和。
例如,sumFibs(4)應該返回 5,因爲斐波納契數列中所有小於4的奇數是 1、1、3。

function sumFibs(num) {
  var arr=[];
  if(num==1){
   arr=[1];}
   else if(num>=2){
   arr=[1,1];
   for(i=2;i<num;i++){//得到小於或等於num的斐波納契數組
       arr[i]=arr[i-1]+arr[i-2];
       if(arr[i]>num){//陷入崩潰,因爲數組太大,內存不夠,加入break,判斷最大的值小於num
         arr.pop();
         break;
       }
     }
   }
  //得到他們的奇數:
  function Evennum(x){//過濾函數
    if(x%2!==0){
      return x;
    }
  }
  for(i=0;i<arr.length;i++){
    arr=arr.filter(Evennum);
  }

   arr=arr.reduce(function(a,b){//奇數之和
     return a+b;
   });
  return arr;
}

12.Sum All Primes

求小於等於給定數值的質數之和。
只有 1 和它本身兩個約數的數叫質數。例如,2 是質數,因爲它只能被 1 和 2 整除。1 不是質數,因爲它只能被自身整除。
給定的數不一定是質數。
sumPrimes(977) 應該返回 73156。

function sumPrimes(num) {
  //首先是如何判斷質數:不能被質數整除即爲質數
  //然後把質數用數組包起來,再用reduce加起來就行了
  var arr=[2];
  var count=0;
  for(i=3;i<=num;i++){
    for(j=0;j<arr.length;j++){
          if(i%arr[j]===0){
            count++;
    }
  }
    if(count===0){
      arr.push(i);
    }
    count=0;//沒算一次,count要清零
  }
  arr=arr.reduce(function(a,b){//和加起來
                 return a+b;
                 });
  return arr;
}

13.Smallest Common Multiple

找出能被兩個給定參數和它們之間的連續數字整除的最小公倍數。
範圍是兩個數字構成的數組,兩個數字不一定按數字順序排序。
例如對 1 和 3 —— 找出能被 1 和 3 和它們之間所有數字整除的最小公倍數。
smallestCommons([5, 1]) 應該返回 60。
smallestCommons([1, 13]) 應該返回 360360。

function smallestCommons(arr) {
  //兩個數字間的所有數都必須被整除,因此第一步是排序,然後把所有整數表達出來;
  //然後挨着判斷就行了..不過會infinite loop,內存佔用太大了這樣
  //改進:求質數之積,再用挨着判斷剩下的。然後再最後相乘。
 arr.sort(function(a,b){//排序
   return a-b;
 });
 //所有整數:
  var maxnum=arr[1];
  var minnum=arr[0];
  var result1=[];//中間存放
  var result=[];//結果
  var result2=[];//質數
  var result3=0;
  var count1=0;
  //所有整數arrPrimes[]
  for(i=1;i<maxnum-minnum;i++){
    arr.splice(i,0,minnum+i);
  }
  //其中的質數
  var arrPrimes=[2];
  var count2=0;
  for(i=3;i<=maxnum;i++){
    for(j=0;j<arrPrimes.length;j++){
      if(i%arrPrimes[j]===0){
        count2++;
      }
    }
    if(count2===0){
      arrPrimes.push(i);
    }
    count2=0;
  }
  result2=arrPrimes;
   //剩下的非素數數組
  for(i=0;i<arr.length;i++){
     if(arrPrimes.indexOf(arr[i])!==-1){
       arr.splice(i,1);
       //刪除了一個總長度-1
       i--;
     }
   }//得到arr=[1,4,6,8...]非素數 result2=arrPrimes=[2,3,5,7...]素數組
  //除去非素數中的素數因數
  for(i=0;i<arrPrimes.length;i++){
    for(j=0;j<arr.length;j++){
      if(arr[j] % arrPrimes[i]===0){//取餘
        arr[j]=arr[j]/arrPrimes[i];
       // result1.push(arrPrimes[i]);//加入一個因式
      }
    }
  } //過後arr=[1,2,1,4,3,1,2] 

  //非素數組挨着判斷
    var Sum=arr.reduce(function(a,b){
    return a*b;
  });
  for(i=1;i<=Sum;i++){
    for(j=0;j<arr.length;j++){
      if(i%arr[j]!==0){//如果arr中有數無法被i整除
        count1++;
      }
    }
    if(count1===0){
      result3=i;
      break;
    }
    count1=0;
  } 
  result2.push(result3);
  result=result2.reduce(function(a,b){
    return a*b;
  });
  return result;
}

14.Drop it

讓我們來丟棄數組(arr)的元素,從左邊開始,直到回調函數return true就停止。
第二個參數,func,是一個函數。用來測試數組的第一個元素,如果返回fasle,就從數組中拋出該元素(注意:此時數組已被改變),繼續測試數組的第一個元素,如果返回fasle,繼續拋出,直到返回true。
最後返回數組的剩餘部分,如果沒有剩餘,就返回一個空數組。
drop([1, 2, 3, 9, 2], function(n) {return n > 2;}) 應該返回 [3, 9, 2]。
drop([0, 1, 0, 1], function(n) {return n === 1;}) 應該返回 [1, 0, 1]。

function drop(arr, func) {
  // Drop them elements
  var newArr=[];
  var test=0;

  for(i=0;i<arr.length;i++){
    newArr[0]=arr[i];//成功了的
    //console.log(newArr[0]);
    if(newArr.filter(func)[0] ===undefined){//"" 和null都不行?
      arr.shift(); //shift會改變arr的總長度
      i--;//這個剛開始忘了
      console.log(arr);//如果不滿足func,則從arr刪去
    }else{
      break;
    }
  }
return arr;
}

15.Steamroller

對嵌套的數組進行扁平化處理。你必須考慮到不同層級的嵌套。
Array.isArray()用到
steamroller([1, [], [3, [[4]]]]) 應該返回 [1, 3, 4]。
steamroller([1, {}, [3, [[4]]]]) 應該返回 [1, {}, 3, 4]。

function steamroller(arr) {
  var length=0;
  var newArr=[];
  for(i=0;i<arr.length;i++){
    if(Array.isArray(arr[i])===false){//不是array
      newArr.push(arr[i]);
    }else{//如果是arr
      if(arr[i]!=="[]"){//且不是空[];
         length=arr[i].length;//i的增加值,放在for之前,防着因爲i++而改變。
        for(j=0;j<length;j++){
        arr.splice(i,0,arr[i][j]);//去掉一層[];,但解決不了[]中有兩個及多個的元素問題
        i++;//裏面元素按順序加到arr中
      }
        i=i-length;
        arr.splice(i+length,1);//把[]中的多個元素拿出來加入到arr中,並刪除原array[]。
     }
      if(Array.isArray(arr[i])===true){//如果去掉一層[]還是array,再進行一次這樣的運算,讓i--;
        i--;
      }
    }
  }
  return arr;
}

16.Binary Agents

傳入二進制字符串,翻譯成英語句子並返回。
二進制字符串是以空格分隔的。binaryAgent(“01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111”) 應該返回 “Aren’t bonfires fun!?”

function binaryAgent(str) {
  //二進制轉十進制parseInt()
  //然後String.fromCharCode(65,66,67);"ABC".charCodeAt(0) // returns 65這樣
  str=str.split(" ");
  for(i=0;i<str.length;i++){
    str[i]=parseInt(str[i],2);
  }
  for(i=0;i<str.length;i++){
    str[i]=String.fromCharCode(str[i]);
  }
  str=str.join("");
  return str;
}

17.Everything Be True

完善編輯器中的every函數,如果集合(collection)中的所有對象都存在對應的屬性(pre),並且屬性(pre)對應的值爲真。函數返回ture。反之,返回false。
every([{“user”: “Tinky-Winky”, “sex”: “male”}, {“user”: “Dipsy”, “sex”: “male”}, {“user”: “Laa-Laa”, “sex”: “female”}, {“user”: “Po”, “sex”: “female”}], “sex”) 應該返回 true。
every([{“user”: “Tinky-Winky”, “sex”: “male”}, {“user”: “Dipsy”}, {“user”: “Laa-Laa”, “sex”: “female”}, {“user”: “Po”, “sex”: “female”}], “sex”) 應該返回 false。

function every(collection, pre) {
  // Is everyone being true?
  //把collectioin的所有屬性找出來成爲一個array,然後再判斷pre是否存在,值是否爲false;
  var count=0;//計數用
  for(i=0;i<collection.length;i++){
    var keys=Object.keys(collection[i]);//每一項中的屬性數組
    if(keys.indexOf(pre)!==-1){//如果屬性存在並且值不爲Boolean的false
      if(Boolean(collection[i][pre])){
        count++;
      }
    }
}
  if(count==collection.length){//數組的每一個元素都有pre屬性
    return true;
  }else{
    return false;
  }
}

18.Arguments Optional :用到閉包

創建一個計算兩個參數之和的 function。如果只有一個參數,則返回一個 function,該 function 請求一個參數然後返回求和的結果。
例如,add(2, 3) 應該返回 5,而 add(2) 應該返回一個 function。
調用這個有一個參數的返回的 function,返回求和的結果:
var sumTwoAnd = add(2);
sumTwoAnd(3) 返回 5。
如果兩個參數都不是有效的數字,則返回 undefined。

function isNumber(x){//判斷是否是數字
  return typeof x === 'number';
}
function add() {
  if(arguments.length==2 && isNumber(arguments[0]) && isNumber(arguments[1])){//如果有兩個參數,且都是數字
    return arguments[0]+arguments[1];
  }else if(arguments.length==1 && isNumber(arguments[0])){//如果只有一個參數且爲數字
    var add1=arguments[0];//add1爲只存在一個的參數
    return function(){//閉包
      if(isNumber(arguments[0])){  //如果是數字    
      return add1+arguments[0];  //在不同的function裏面arguments會改變,此處變成了第二個括號裏的東西()
   }
  };
 }
}
發佈了27 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章