🌊

2024 JavaScript - 每日刷題任務

2024/10/01に公開

JavaScript
Codewars

はじめに

在 codewars 的每日刷題,題目主要會跟著 六角學院 - 2024 JavaScript 工程師養成直播班 的每日刷題題目走, 有空的話再自己多刷幾題。
其他還有 ↓


Since 2024-09-30

Day 1:Even or Odd

Even or Odd | #8kyu

Even or Odd - 偶數或奇數
目前個人等級:8 kyu

Description: 建立一個 function,使用一個整數做為參數,如果參數為偶數回傳 "Even" 如果為奇數回傳 "Odd"


我的解法

function evenOrOdd(number) {
  return number % 2 === 0 ? 'Even' : 'Odd';
}

反饋與思考


最優解

Do I get a bonus?

Do I get a bonus? | #8kyu

Do I get a bonus? - 我會有獎金嗎?
目前個人等級:8 kyu

Description:建立一個 function,
你有兩個參數:salary 為整數、bonus 為布林值,
如果布林值為真,你可以得到 10 倍的獎金。
反之你只能得到原本的薪水。
回傳請帶上金額符號 "£"


我的解法

function bonusTime(salary, bonus) {   
    if (bonus === true) {
        return `£${salary * 10}`;
    } else {
        return `£${salary}`;
    }
}

反饋與思考

  • 如果只有是跟不是,可以改寫:
function bonusTime(salary,bonus){
    return bonus === true ?  `£${salary * 10}` : `£${salary}`;
}

最優解

同上

Beginner Series 2 Clock

Beginner Series 2 Clock | #8kyu

Beginner Series 2 Clock - 初學者系列2 時鐘
目前個人等級:8 kyu

Description:寫一個函數,用毫秒顯示時、分、秒。例如:m=1, s=1, result = 61000
輸入條件:
0 <= h <= 23
0 <= m <= 59
0 <= s <= 59


我的解法

function past(h, m, s){
    if( 0 <= h <=23 , 0 <= m <= 59, 0 <= s <= 59){
      return h*3600000 + m*60000 + s*1000;
    }else{
      return '請重新輸入';
    }
}

反饋與思考

  • 算時間好難…
  • 又重新看了一下 if 的寫法
  • 又重新看了一下流程圖拆解的方法

最優解 (不對呀?沒有驗證呀?)

function past(h, m, s){
  return ((h*3600)+(m*60)+s)*1000;
}

Sum of positive

Sum of positive | #8kyu

Sum of positive - 加總陣列中的正數
目前個人等級:8 kyu

Description:你有一個陣列數字,請回傳加總所有正數的總額


我的解法

function positiveSum(arr) {
  let sum = 0;
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] > 0) {
      sum += arr[i];
      }
  }
  return sum;
}

反饋與思考

  • 之後復習完 for 迴圈之後再回來重做一次

最優解

除了 for 迴圈,也可以用 reduce()

Day 2 : Basic Mathematical Operations

Basic Mathematical Operations | #8kyu

Basic Mathematical Operations -
依條件運算並且輸出運算結果及過程
目前個人等級:8 kyu

Description:建立一個執行基本數學運算的函數。


我的解法

function basicOp(operation, value1, value2){
  let result = 0;
  switch (operation){
      case '+':
      result = value1 + value2;
      break;
      case '-':
      result = value1 - value2;
      break;
      case '*':
      result = value1 * value2;
      break;
      case '/':
      result = value1 / value2;
      break;
  }
  return result;
}

反饋與思考

  • 在本週刷題裡面剛好也有一樣的題目,剛好又可以再練習一次 switch 的用法。

最優解

switch 是最優解

Day 3 : Thinkful - Logic Drills: Traffic light

Thinkful - Logic Drills: Traffic light | #8kyu

Thinkful - Logic Drills: Traffic light -
邏輯練習:紅綠燈
目前個人等級:8 kyu

Description:
請寫一個函數依照 綠色 => 黃色 => 紅色的順序來改變紅綠燈
使用字串表示目前紅綠燈狀態,並回傳變更後的紅綠燈字串


我的解法

function updateLight(current) {
  switch (current){
      case 'green':
        changeLight = 'yellow';
        return changeLight;
        break;
      case 'yellow':
        changeLight = 'red';
        return changeLight;
        break;
      case 'red':
         changeLight = 'green';
        return changeLight;
        break;
  }
  console.log(changeLight);
}

反饋與思考

  • 可以用 switch 也可以用 if ,最簡單就直接 return 結束 。
return current === 'yellow' ? 'red' : current === 'green' ? 'yellow' : 'green';

最優解

這題也沒有最優解只要邏輯通了都可以,
只是使用 switch 的話,不需要再加一個 changeLight 的變數,
本來也是直接這樣寫,後來怕沒有賦值會無效所以又再加上變數賦值。(想多了ww)

function updateLight(current) {

  switch (current) {
    case 'green':
      return 'yellow';
      break;
    case 'yellow':
      return 'red';
      break;
    case 'red':
      return 'green';
      break;
    default:
      throw 'Error: wrong input';
      break;
  }
}

Day 4 : Remove String Spaces

Remove String Spaces | #8kyu

Remove String Spaces -
清除字串的空白
目前個人等級:8 kyu

Description:
清除字串中的所有空白之後再回傳清除後的資料


我的解法

function noSpace(x){
  return x.trim().replace(/\s+/g,'')
}

反饋與思考

  • 學了一個新方法 😃,本來只會刪除字串左右的空白,
    現在學了刪除中間字串的空白還有正則表達式(regex)

最優解

同上(但不需要刪除字串左右空白)

Day 5 : The Feast of Many Beasts

The Feast of Many Beasts | #8kyu

The Feast of Many Beasts - 野獸們的盛宴
目前個人等級:8 kyu

Description:
野獸們各自帶一盤料理來參加盛宴,但有一個規則:菜餚的開頭與結尾必須跟野獸的名字一樣。


我的解法

function feast(beast, dish) {
  let beastFirstChar = beast.charAt(0);
  let beastLastChar = beast.charAt(beast.length - 1);
  let dishFirstChar = dish.charAt(0);
  let dishLastChar = dish.charAt(dish.length - 1);
  
  return beastFirstChar === dishFirstChar && beastLastChar === dishLastChar ? true : false;
}

反饋與思考

  • 學了一個新的方法 charAt()
  • 但我想的太複雜了XD

最優解

function feast(beast, dish) {
	return beast[0] === dish[0] && beast[beast.length - 1] === dish[dish.length - 1]
}

Day 6 : Reversed Strings

Reversed Strings | #8kyu

Reversed Strings - 反轉字串
目前個人等級:8 kyu

Description:
請將字串反轉後回傳


我的解法

function solution(str){
  return str.split('').reverse().join('');  
}

反饋與思考

  • 學習了新的方法 split, reversejoin

最優解

同上

Beginner Series #4 Cockroach

Beginner Series #4 Cockroach | #8kyu

Beginner Series #4 Cockroach - 題目太噁心我不想翻譯 初學者系列4
目前個人等級:8 kyu

Description:
將公里每小時(km/h)轉換為厘米每秒(cm/s)


我的解法

  • 1公里 = 100,000 厘米
  • 1小時 = 3,600 秒
function cockroachSpeed(s) {
  return parseInt(s*(1/36)*1000);
}

反饋與思考

  • 連題目都看不懂,慘
  • 這裡要用到 math.floor ,將數字取到整數
  • 箭頭函式我看不懂~~~~

最優解

const cockroachSpeed = s => Math.floor(s / 0.036);

Day 7 : String cleaning

date : 2024/10/08

String cleaning | #8kyu

String cleaning - 清掃字串
目前個人等級:7 kyu

Description:
移除文字中的數字後回傳


我的解法

function stringClean(s){
  return s.replace(/\d/g,'');
}

反饋與思考

  • 上次學習了正則表達式,這次又再練習了一次

最優解

同上

Remove exclamation marks

date : 2024/10/08

Remove exclamation marks | #8kyu

Remove exclamation marks - 清除驚嘆號
目前個人等級:7 kyu

Description:
移除文字中的驚嘆號後回傳


我的解法

function removeExclamationMarks(s) {
  return s.replace(/!/g, '');
}

反饋與思考

  • 學會了怎麼使用這個網站
  • 最優解寫的比較嚴謹一點,包含了大小寫問題

最優解

function removeExclamationMarks(s) {
  return s.replace(/!/gi, '');
}

Day 8 : Is the string uppercase?

date : 2024/10/09

Is the string uppercase? | #8kyu

Is the string uppercase? - 這字串是大寫嗎?
目前個人等級:7 kyu

Description:
判斷字串是不是全部都是大寫


我的解法

String.prototype.isUpperCase = function() {
  return this.toString() === this.toUpperCase();
};

反饋與思考

  • 超綱了超綱了…

最優解

同上

Day 9 : Stringy Strings

date : 2024/10/10

Stringy Strings | #8kyu

Stringy Strings - 細弦字串
目前個人等級:7 kyu

Description:
寫一個函數輸入 size 會回傳 size 長度由 10 組成的字串,必須要從 1 開始.


我的解法

沒有,我解不出來

  1. 題解使用 for 迴圈
  2. 先給 result 一個空值,
    用取餘數的方式判斷要給 1 還是 0

反饋與思考

  • 超綱了超綱了…

最優解

function stringy(size) {

  let result = "";
  
  for(let i = 0; i < size; i++) {
    result += (i % 2 === 0) ? "1" : "0";
  }
  
  return result;
}

Rot13

date : 2024/10/10

Rot13 | #5kyu

Rot13 - 字母加密
目前個人等級:7 kyu

Description:
寫一個 ROT13 的字母加密,將每個字母替換為其後 13 位的字母。例 A 變為 N


我的想法/解法

  • JS 組員推薦做完本週字串刷題可以來試試這題。
  1. 我先將 message 轉換為陣列
  2. 用 for 迴圈去配對 message 的 index
    判斷是不是英文字母 /a-zA-Z/g ? 如果是才運算 : 回傳符號

反饋與思考

  • 這裡會用到 ASCII
  • 以及使用 charCodeAt()fromCharCode() 方法

最優解

function rot13(str) {
    return str.replace(/[A-Za-z]/g, function(char) {
        const start = char <= 'Z' ? 65 : 97; // 判斷是大寫還是小寫
        return String.fromCharCode(((char.charCodeAt(0) - start + 13) % 26) + start);
    });
}
console.log(rot13("HELLO")); // "URYYB"
console.log(rot13("URYYB")); // "HELLO"

Day 10 : Jaden Casing Strings

date : 2024/10/11

Jaden Casing Strings | #8kyu

Jaden Casing Strings - 首字大寫

Description:
將句子中的每個單字字首改為大寫。


我的解法

  1. 將句子用空白的方式拆成陣列
  2. 抓出單字的字首改為大寫
  3. 轉回句子字串
String.prototype.toJadenCase = function () {
  return this.split(' ').map(word => {
    return word.charAt(0).toUpperCase()+ word.slice(1);
  }).join(' ');
};

反饋與思考

  • String.prototype.toJadenCase = function () 第二次遇到這個,是指為 String 原型對象添加方法,所有字串都可以使用這個方法。跟 String.toJadenCase 是不一樣的意思
  • .map 可以創建一個新陣列,不會對原陣列做變動
  • word => 遍歷陣列裡的每個單字
  • .charAt(index) 取得字串中特定索引的值,例如:text.charAt(0) apple 的話就會取 a

最優解

同上

Day 11 : Training JS #8: Conditional statement--switch

date : 2024/10/14

Training JS #8: Conditional statement--switch | #8kyu

Training JS #8: Conditional statement--switch - Switch 語法練習

Description:
在 JavaScript 中,可以使用 switch 取代多個 if


我的解法

Tip: 可以使用 default 減少工作量

function howManydays(month){
  let days;
  switch (month){
    case 2:
      days = 28;
      break;
    case 4:
    case 6:
    case 9:
    case 11:
      days = 30;
      break;
    default:
      days = 31;
  }
   return days;
}

反饋與思考

  • 一開始寫成了下面的方式,宣告了 days 應該要在完成判斷後(case)賦予 days 值。所以原本寫的方式會造成 undefined
case 2:
  console.log(28);
  break;
  • 以為 case 只能一次用一個,後來才發現原來可以一次好幾個 case
    like:
case 4:
case 6:
case 9:
case 11:
  days = 30;
break;

最優解

同上

Day 12 : Will you make it?

date : 2024/10/17

Will you make it? | #8kyu

Will you make it? - 辦得到嗎?

Description:
您和朋友在遠離家鄉的地方露營,但當您要回去時,您發現燃料快用完了,而最近的加油站卻在 50 英里之外!您知道,您的汽車平均每加侖行駛約 25 英里。剩下 2 加侖。
寫一個函數計算是不是能夠到加油站加油,可以的話回傳 true ,不行的話為 false


我的解法

  • mpg x 剩餘的加侖數如果大於到加油站的英里的話,就可以成功到達
    // mpg = 25;
    // mpg*fuleLeft
    // mpg * fuleLeft >= distanceToPump ? true : false
const zeroFuel = (distanceToPump, mpg, fuelLeft) => {
  return mpg * fuelLeft >= distanceToPump ? true : false ;
};

反饋與思考

  • 結果一開始不小心把 mpg = 25 寫了進去就跳錯誤了,不應該再賦值一次。
  • 看了別人的可以不寫後面 ? true : false ;

最優解

const zeroFuel = (distanceToPump, mpg, fuelLeft) => mpg * fuelLeft >= distanceToPump;

Day 13 : I love you, a little , a lot, passionately ... not at all

date : 2024/10/18

I love you, a little , a lot, passionately ... not at all | #8kyu

I love you, a little , a lot, passionately ... not at all - Switch 語法練習

Description:
青春期,少女們總是會撕花瓣並且說:

  1. "I love you"
  2. "a little"
  3. "a lot"
  4. "passionately"
  5. "madly"
  6. "not at all"
    如果花瓣超過 6 瓣就會回到第一項 "I love you",而 8 就會到 "a little",如此循環。

我的解法

我的想法是這樣的:

  • 先建立一個陣列放置這些話
  • 需要跑 for 迴圈嗎 ? (X)
  • 直接 nbPetals = petals[nbPetals -1] ? 來抓陣列裡面的值
function howMuchILoveYou(nbPetals) {
  let petals = [
    'I love you',
    'a little',
    'a lot',
    'passionately',
    'madly',
    'not at all'
  ];
  return petals[(nbPetals -1)% petals.length];
}
}

反饋與思考

  • 但是數超過了要怎麼回來 ?
  • 我最後想不透該怎麼辦,求助了 GPT ,
    我的思路前面是對的,但是取餘數這件事,實在不是平常會想的到XD
    但不得不說確實很好的解決了超過 6 的這個問題。

最優解

同上

Day 14 : Rock Paper Scissors!

date : 2024/10/17

Rock Paper Scissors! | #8kyu

Rock Paper Scissors! - 剪刀石頭布

Description:
來玩剪刀石頭布吧~


我的解法

  • 跟第二週主線任務第十題一樣的題目
  • 先設一個條件為平手
  • 再設 player 1 贏的所有條件
  • 最後剩下的都是 player 2 贏了
const rps = (p1, p2) => {
  if (p1 === p2){
    return "Draw!";
  }else if (
  (p1 === "scissors" && p2 === "paper") ||
    (p1 === "rock" && p2 === "scissors") ||
    (p1 === "paper" && p2 === "rock")
  ) {
    return "Player 1 won!";
  }else {
   return "Player 2 won!"
  }
}

反饋與思考

  • 被學習時候的短短條件式侷限了思考,沒想到裡面是可以再塞很多東西的~
  • 有看到別人使用物件來放剪刀、石頭跟布
  • 最後的 return rules[p1] === p2 問了 GPT 是指依據 p1 的選擇來查找 rules 裡面的值來判斷 p2 是不是輸了。

最優解

const rps = (p1, p2) => {
  if (p1 === p2) return "Draw!";
  const rules = {
    rock: "scissors",
    paper: "rock",
    scissors: "paper"
    };
  return rules[p1] === p2 
  ? "Player 1 won!" 
  : "Player 2 won!";
};

Day 15 : Get the Middle Character

date : 2024/10/18

Get the Middle Character | #7kyu

Get the Middle Character - 取得中間的字元

Description:
你的工作是回傳單字的中間字元,如果單字長為奇數,則回傳中間字元;如果單字長為偶數,則回傳中間兩個字元。


我的解法

  • 先將 s 轉成陣列 => 計算陣列長度 => 如果為奇數取中間,為偶數取中間兩位,可能要用到取餘數計算奇偶
  • 抓出 s.length 長度,% 2 取餘數,if 為 0 則擷取中間兩個字符
  • 用 .slice(start,end) 來擷取字符
  • 使用 .substr(start,length) 來擷取字符
function getMiddle(s)
{
  return s.length % 2 === 0 
    ? s.substr((s.length/2) -1, 2) 
    : s.substr(s.length/2 , 1);
}

反饋與思考

  • 好玩
  • 一開始想轉成陣列想複雜了,後來想到有直接擷取字串的方法
  • 因為之前用過 .slice ,一開始就想說使用這個,結果為了取2位跟1位卡很久,找資料過程中才發現也有 .substr 更簡單容易一點。

最優解

function getMiddle(s)
{
  return s.substr(Math.ceil(s.length / 2 - 1), s.length % 2 === 0 ? 2 : 1);
};

Day 16 : Total amount of points

date : 2024/10/21

Total amount of points | #8kyu

Total amount of points - 總分數

Description:
每場比賽都是由 x:y 的字串來表示,x 是我們球隊的得分,y 是對方得分。
比賽的積分如下計算:
if x > y 3 points (win)
if x < y 0 points (loss)
if x = y 1 points (tie)
請編寫一個函數並返回我們在錦標賽中的得分
TIP: 錦標賽打 10 場


我的解法

  • 我一開始是先想說要建立一個陣列(空陣列?)
  • 後來想說之前有加總陣列的寫法,把作業翻出來看使用了 for + if 來查看陣列是否有大於 0 後加總。
function positiveSum(arr) {
  let sum = 0;
  for (let i = 0; i < arr.length; i++){
    if(arr[i]>0){
      sum += arr[i];
    }
  }
  return sum;
}
  • 但是這個寫法只有一個值(例如 x),那我的 y 怎麼辦…最後將我寫到一半的 code 問了 GPT
function points(games) {
 
  let teamPoints = 0
 
  for (let x = 0 ; x > 9 ; x ++){
    if (x > y){
      return teamPoints += 3;
    }else if(x = y) {
      return teamPoints += 1;
    }else {
      return teamPoints += 0;
    }
  }
  return teamPoints;
}
  • GPT 推薦使用 forEach 但因為還沒學到 forEach ,也有說明如果使用 for 迴圈的寫法:
function totalPoints(games) {
  let total = 0;

  for (let i = 0; i < games.length; i++) {
    const [x, y] = games[i].split(":").map(Number);
    if (x > y) {
      total += 3; // Win
    } else if (x === y) {
      total += 1; // Draw
    }
    // No points for a loss
  }

  return total;
}

反饋與思考

  • 學了 forEachfor 迴圈的差異
  • 又寫了 x = y 這種鬼,總是會忘記 = 是賦值
  • 這裡不應該使用 return ,因為 return 有使函數結束的特性,而這裡應該要累加分數,而不能提前結束函數。
  • map() 有學過了,但總是不知道怎麼去使用他,這裡先粗暴的記憶:跟陣列有關就找 .map()

最優解

function getMiddle(s)
{
  return s.substr(Math.ceil(s.length / 2 - 1), s.length % 2 === 0 ? 2 : 1);
};

Day 17 : Categorize New Member

date : 2024/10/29

Categorize New Member | #7kyu

Categorize New Member - 分類成員

Description:
槌球俱樂部分別有:高級會員及公開會員,請幫會員分類
要成為高級會員,必須年滿 55 歲並且差點大於 7 。
輸入成員年齡及差點,請回傳 'Open' 或 'Senior'


我的解法

  • 輸入為一個陣列 [age,handicap]
  • 條件:age > 55 && handicap > 7
  • 先用 .forEach 遍歷每個陣列 想複雜了
  • 用 .map() 判斷之後回傳一個新陣列
function openOrSenior(data){
  return data.map(([age,handicap]) => {
    if (age >= 55 && handicap > 7){
      return 'Senior';
    }else{
      return 'Open';
    }
  });
}

反饋與思考

  • 還不是很熟箭頭函數,等一下來補一下課程影片
  • 還不是非常熟練可以直接寫成三元

最優解

function openOrSenior(data){
  return data.map(([age, handicap]) => (age > 54 && handicap > 7) ? 'Senior' : 'Open');
}

Day 18 : Testing 1-2-3

date : 2024/10/29

Testing 1-2-3 | #7kyu

Testing 1-2-3 - 測試1-2-3

Description:
寫一個函數給字串一個數字編號列表 (ol>li)
n: string 別忘記冒號跟空格


我的解法

  • return array.map(("1: a") => )
  • 使用 .map() 來組成新陣列
  • 要怎麼列出順序數字?for 迴圈?那就使用 .forEach 來 ++
    • ↑又想多了,直接把陣列的 index +1 就可以了
  • ${i}: ${x}
  • .join("") 組回字串
var number=function(array){
  return array.map((item,index) =>`${index +1}: ${item}`);
}

反饋與思考

  • 都想複雜了~不過邏輯來說是可行的問題是組不起來,實際執行能力還要再加強
  • map 還不夠熟練

最優解

const number = array => array.map((n, i) => `${i + 1}: ${n}`);

Day 19 : Filter the number

date : 2024/11/05

Filter the number | #7kyu

Filter the number - 過濾數字

Description:
數字跟文字混在一起了,請將數字從字串中取出並回傳


我的解法

  • 先把字串轉成陣列 .split('')
    let array = value.split('');
    console.log(array);
    
  • 使用 filter 取出數字陣列
    這邊我就卡關了,要怎麼辨認數字型態一開始卡在 typeof ,完全忘了可以用使用 NaN (Not-a-Number) 來抓出數字
    let array = value.split('').filter(function(item){
      return !isNaN(item) && item !== ' '   
    });
    console.log(array);
    
  • filter 可以直接查找字串嗎? 不行
  • 再轉回數字 parseInt() 要先將陣列轉回字串 .join()
  • 最後才將字串轉成數字型態回傳 parseInt()
    let array = parseInt(value.split('').filter(function(item){
      return !isNaN(item) && item !== ' ' 
    }).join(''));
    console.log(array);
    

反饋與思考

  • 這題居然寫一半…我以為我寫完了,剛好又練習一次 filter
  • 其實這題沒有一定要用 filter 寫,轉成陣列再轉回來就複雜了,被題目誤導ww
  • 基礎很重要呀…這裡使用 isNaN() 來檢查是不是數字
    number.isNaN('abc'); //false
    number.isNaN(NaN); //true
    

最優解

function filterString(value) {
 return parseInt(value.replace(/\D/g, ''));
}

.replace 是替換的方法,這裡很聰明直接把字元轉成空白

Day 22 : List Filtering

date : 2024/11/05

List Filtering | #7kyu

List Filtering - 清單過濾

Description:
寫一個函數將列表中非數字過濾,並回傳一個只有數字的新列表


我的解法

  • 發現對 return 還是不太熟
    function filter_list(l) {
      return l.filter(item => typeof item === "number");
    }
    

反饋與思考

  • 已經先在群組看到這題是練習 filter(),所以缺少了一些摸索思考題目

最優解

function filter_list(l) {
  return l.filter(function(v) {return typeof v == 'number'})
}

最後に

Discussion