🏅

社内でTypeScript大会しました(競プロ)

2024/08/21に公開

はじめに

皆さんは普段、コーディングをするときにCopilotを使っているでしょうか?
私はがっつり使ってます。
「どういったコードを書きたいか」をコメントするだけでコードの自動生成をしてくれたり、次に書くべきコードの提案を受けることができるので、非常に便利ですよね。

一方で、自分で考えてコードを書く機会が減るため、「自分でプログラミングを書けなくなるのでは?」という懸念があります...

自分で考えてコードを書く機会を作ることと、他の人がどんなコードを書いているのか勉強のために社内でTypeScript大会を開催しました。学びがありましたし、結構盛り上がって楽しかったです!

本記事では、そのときに出題した問題を紹介したいと思います。皆さんも力試しにどうぞ!

ルール説明

  • TypeScriptを使って問題を解きます
  • 制限時間は特にありませんが、コーディングのスピードも意識しましょう
  • 変数名は適当でいいです
  • 組み込みオブジェクトやインスタンスメソッドなど、色々駆使してください
  • だんだん難しくなってきます
  • 生成AIに頼らず、分からなければMDNなどで調べましょう

https://developer.mozilla.org/ja/docs/Web

第一問

問題

次の配列から、3で割った余りが1の数を取り出し、それらの数の平均を小数点第二位まで求めてください。(小数第三位を四捨五入)

const numbers: number[] = [11, 52, 34, 4, 25, 36, 77, 48, 1]; //コピーして使ってください
答え(console.log()で出力した結果と比べてください)

34.33

コード例
const filteredNumbers = numbers.filter(num => num % 4 === 1);

const average = filteredNumbers
  .reduce((sum, num) => sum + num, 0)
  / filteredNumbers.length;

console.log(average.toFixed(2));

第二問

問題

次のオブジェクト配列から、priceが1000以上のアイテムのnameを取り出し、それらを大文字に変換してカンマ区切りの文字列を生成してください。

interface Product {
  name: string;
  price: number;
} 
const products: Product[] = [ 
  { name: 'Laptop', price: 1500 },
  { name: 'Phone', price: 700 },
  { name: 'Tablet', price: 800 },
  { name: 'Monitor', price: 1200 },
  { name: 'Keyboard', price: 100 } 
];
答え

"LAPTOP,MONITOR"

コード例
const result = products 
  .filter(product => product.price >= 1000) 
  .map(product => product.name.toUpperCase())
  .join(',');

console.log(result);

第三問

問題

次の2次元配列から奇数のみを抽出して二乗し、それらの合計を求めてください。

const matrix: number[][] = [
  [4, 8, 5],
  [7, 2, 9],
  [1, 6, 3]
];
答え

165

コード例
const sum = matrix.flat()
  .filter(num => num % 2 !== 0)
  .map(num => num ** 2);
  .reduce((acc, num) => acc + num, 0);

console.log(sum);

第四問

問題

次の社員のデータから、在籍日数(今日 ー joinDate(入社日))を計算し、歴の長い方から並び替えてください。

const data = [
  { id: 1, name: "ドラえもん", joinDate: "2012-07-01" },
  { id: 2, name: "しずかちゃん", joinDate: "2019-03-18" },
  { id: 3, name: "ジャイアン", joinDate: "2023-01-01" },
  { id: 4, name: "スネ夫", joinDate: "2011-04-01" },
  { id: 5, name: "のび太", joinDate: "2018-10-01" },
];

出力内容↓

[
  { “名前”: "???", “在籍日数”: "???" },
  { “名前”: "???", “在籍日数”: "???" },
  { “名前”: "???", “在籍日数”: "???" },
  { “名前”: "???", “在籍日数”: "???" },
  { “名前”: "???", “在籍日数”: "???" }
];
答え

※本記事の投稿日(2024/8/21)を今日とした時の日数で計算してます。

[
  {
    "名前": "スネ夫",
    "在籍日数": 4892
  },
  {
    "名前": "ドラえもん",
    "在籍日数": 4435
  },
  {
    "名前": "のび太",
    "在籍日数": 2152
  },
  {
    "名前": "しずかちゃん",
    "在籍日数": 1984
  },
  {
    "名前": "ジャイアン",
    "在籍日数": 599
  }
]
コード例
const today = new Date();

const sortedByJoinDateDesc = data
  .sort((a, b) => new Date(a.joinDate).getTime() - new Date(b.joinDate).getTime());

const result = sortedByJoinDateDesc.map(person => {
  const joinDate = new Date(person.joinDate);
  const daysWorked = Math
    .ceil((today.getTime() - joinDate.getTime()) / (1000 * 60 * 60 * 24));
  return {
      "名前": person.name,
      "在籍日数": daysWorked
  };
});

console.log(JSON.stringify(result, null, 2));

さいごに

お疲れ様でした!皆さんは何問答えられたでしょうか?
AIツールを活用するのも良いですが、やはり自分の手でコードを書く経験はとても大切だと思います。
最後まで読んでいただき、ありがとうございました。

NCDCエンジニアブログ

Discussion