今回は paiza の「複数形への変換」の問題に挑戦!
これまでの学習を活かして解いていく!
🧩 問題概要
英単語を与えられたルールに従って 複数形に変換 するプログラムを作る問題。
📘 複数形変換ルール
〇 条件:変換内容
① 末尾が s, sh, ch, o, x:es をつける
② 末尾が f または fe:それを削除して ves をつける:
③ 末尾が y かつその前が母音でない:y を削除して ies をつける
④ 上記以外:s をつける
🎯 入力
N
a_1
a_2
...
a_N
-
N:単語の数(1〜10) - a_i`:変換対象の英単語(小文字のみ、長さ2〜20)
🎯 出力
- 各単語をルールに従って複数形に変換し、1行ずつ出力。
入力例:
7
box
photo
axis
dish
church
leaf
knife
出力例:
boxes
photoes
axises
dishes
churches
leaves
knives
✅OK例:
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const N = Number(lines[0]);
const a = lines.slice(1);
for (let i = 0; i < N; i++) {
const word = a[i];
const end = word.length - 1;
if (word[end] === 's'
|| word[end] === 'o'
|| word[end] === 'x'
|| word.slice(end-1) === 'ch'
|| word.slice(end-1) === 'sh') {
console.log(word + 'es');
}
else if (word[end] === 'f' || word.slice(end-1) === 'fe') {
if (word[end] === 'f') console.log(word.slice(0, end) + 'ves');
else console.log(word.slice(0, end-1) + 'ves');
}
else if (word[end] === 'y') {
if (word[end-1] !== 'a'
&& word[end-1] !== 'i'
&& word[end-1] !== 'u'
&& word[end-1] !== 'e'
&& word[end-1] !== 'o') {
console.log(word.slice(0, end) + 'ies');
} else {
console.log (word + 's');
}
}
else {
console.log(word + 's');
}
}
});
🧭 コードの流れ
- 入力を読み取る準備
-
readlineモジュールを使って、標準入力(コンソール)からデータを受け取る設定をする。 - 入力された行を
lines配列に順番に追加。
-
- 全入力を受け取ったら処理開始
-
rl.on('close', ...)の中で、配列linesに入った内容を処理。
-
- 入力内容の整理
- 1行目 → 単語数
Nに変換。 - 2行目以降 → 複数形に変換する単語リスト
aに格納。
- 1行目 → 単語数
- 単語ごとの処理
-
for文で1単語ずつ取り出し、末尾文字(end)を取得。
-
- ルールに従って末尾を判定
① 末尾が s, o, x, ch, sh → es をつける
② 末尾が f, fe → それを削って ves をつける
③ 末尾が y かつ直前が母音以外 → y を削って ies をつける
④ 上記以外 → s をつける - 結果を出力
各単語の複数形をconsole.log()で表示。
✅OK例 2:
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const N = Number(lines[0]);
const words = lines.slice(1);
const esEndings = ['s', 'o', 'x'];
const esDoubleEndings = ['ch', 'sh'];
const vowels = ['a', 'i', 'u', 'e', 'o'];
for (let i = 0; i < N; i++) {
const word = words[i];
const end = word.length - 1;
// --- ① 「es」をつけるパターン ---
if (esEndings.includes(word[end]) || esDoubleEndings.includes(word.slice(end - 1))) {
console.log(word + 'es');
}
// --- ② 「ves」をつけるパターン ---
else if (word[end] === 'f' || word.slice(end - 1) === 'fe') {
if (word[end] === 'f') console.log(word.slice(0, end) + 'ves');
else console.log(word.slice(0, end - 1) + 'ves');
}
// --- ③ 「y」で終わるパターン ---
else if (word[end] === 'y') {
if (!vowels.includes(word[end - 1])) {
console.log(word.slice(0, end) + 'ies');
} else {
console.log(word + 's');
}
}
// --- ④ それ以外 ---
else {
console.log(word + 's');
}
}
});
🔍 コードの流れ
- 入力処理
- 1行目で単語数
Nを取得。 - 2行目以降の単語群を
words配列に格納。
- 1行目で単語数
- 判定準備
-
esEndings:末尾が1文字で s, o, x の場合。 -
esDoubleEndings:末尾が2文字で ch, sh の場合。 -
vowels:母音リスト(yルールの判定用)。
-
- 各単語に対して判定ルール適用
① 「es」パターン
・末尾が s, o, x, ch, sh のとき → es をつける。
② 「ves」パターン
・末尾が f → f を除いて ves。
・末尾が fe → fe を除いて ves。
③ 「y」パターン
・末尾が y かつその直前が母音以外 → y を除いて ies。
・母音の後に y がある場合は s。
④ その他
・単純に s をつける。 - 出力
💡関数化
const rl = require('readline').createInterface({ input: process.stdin });
const lines = [];
rl.on('line', (input) => lines.push(input));
rl.on('close', () => {
const N = Number(lines[0]);
const words = lines.slice(1);
const esEndings = ['s', 'o', 'x'];
const esDoubleEndings = ['ch', 'sh'];
const vowels = ['a', 'i', 'u', 'e', 'o'];
const pluralize = (word) => {
const end = word.length - 1;
if (esEndings.includes(word[end]) || esDoubleEndings.includes(word.slice(end - 1))) {
return word + 'es';
}
if (word[end] === 'f') {
return word.slice(0, end) + 'ves';
}
if (word.slice(end - 1) === 'fe') {
return word.slice(0, end - 1) + 'ves';
}
if (word[end] === 'y') {
return vowels.includes(word[end - 1])
? word + 's'
: word.slice(0, end) + 'ies';
}
return word + 's';
};
words.forEach(word => console.log(pluralize(word)));
});
📝まとめ
文字列の末尾を条件で判定し、slice() で加工して末尾に文字を付け足す。