質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.59%

JSで、3の倍数の和を求める

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 7,259

sugi_sw

score 14

 前提・実現したいこと

「1から100までの間で、3の倍数の数だけを足した合計値を表示してください。」

つい最近JSを勉強し始めたばかりのHTML/CSSコーダーです。
とても簡素なif文とfor文の課題が出て、自分であれこれ調べてみて答えは見つけたのですが、
日本語で理解しようとすると自信が無いので、簡単な解説をしていただきたいです。

 完成したソースコード

// 1~100までの3の倍数の和
    let sum = 1;
    for (let j = 0; j < 100; j++) {
        if (j % 3 === 0) {
            sum += j;
        }
    }
    console.log(sum);

 自分なりのあやふやな解釈(日本語としてはおかしいです)

    let sum = 1;                    //sumは1から始まるよ
    for (let i = 0; i < 100; i++) { //1~100までの基本的な繰り返し文だよ
        if (i % 3 === 0) {          //ただし、もしその数字が3で割り切れる(倍数)ならば
            sum += i;               // sumはそれまでのsumと新たな「3で割り切れる数字」を足していくよ
        }
    }
    console.log(sum);               // 最終的(100まで)なsumの値だよ

 分からないこと

見てわかるとおりですが、日本語としては理解できません…。
なんとかスッキリ納得できるような解説をいただければモヤモヤが晴れてつぎのステップに進めると思います。
「forの中にifを入れ子にする」、for XXX {if YYY}のあたりがしっくりこないのです。
お手すきでどなたかご回答いただけると幸いです。
宜しくおねがいします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+5

その前にツッコミ

let sum = 1; //sumは1から始まるよ

1から始まっちゃダメです。
3で割り切れる数を全部足した結果が3で割り切れなくなっちゃうでしょ?

for (let i = 0; i < 100; i++) { //1~100までの基本的な繰り返し文だよ

for文の1度目のループは初期値で回るので1ではなく0スタートになります。
また;で区切られた2つ目の式は継続条件なので99でストップします。
つまり、1〜100を精査して欲しいのに、0〜99を精査しているので誤りです。

そしていつの間にか添字がjからiに変身していませんか?

上記のツッコミどころを解消するとこうなります。

let sum = 0;
for (let i = 0; i <= 100; i++) {
  if (i % 3 === 0) {
    sum += i;
  }
}
console.log(sum);

見てわかるとおりですが、日本語としては理解できません…。

見れば分かりますが、
JavaScriptのコードは日本語でも英語でも数式でもありません。
機械への変換を目的として、英語と数式の用語を拝借して作った独自の言語です。
見て辛いのは至極当然で、慣れるしかありません。

プログラミング言語の本質は楽譜に近いかもしれませんね。
音楽が楽譜の左から右へ時間軸に沿って進行していくように、
機械はプログラミング言語を上から読み取って下に流れていきながら実行していきます。

楽譜にはA箇所からB箇所に戻って演奏を再開する符号があるように、
JavaScriptにもforやifという実行する箇所を制御するルールがあります。
覚えるしかないので覚えて慣れてください。

for

JavaScriptのforはループを表します。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/for

書式はfor (1式; 2式; 3式) {繰り返し}で構成され、
機械は2式の箇所が真である限り無限に「繰り返し」部分を実行します。
1式は初期設定、3式はループ毎に実行される式です。

{}の中身は全て終わったら次のループに入ります。

if

JavaScriptのifは条件分岐を表します。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/if...else

if (条件) {文}
条件が真の時だけ、文が実行されます。


おまけ: 3の倍数ってことはさ…

プログラミングの答えは一つだけではありません。
3の倍数の合計ってことは、[1, 2, 3, 4 ... 100]を精査していくんじゃなくて、
[3, 6, 9 ... 99]を足しても良いわけですよね。

let sum = 0;
for (let i = 3; i <= 100; i = i + 3) {
  sum += i;
}
console.log(sum);

これも立派な答えになります。
この辺はパズルなので本を読んでみたりしながら、あれこれ組み合わせて実行してみて楽しんでくださいね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/27 19:50

    ★sumは最終的に求める合計値なので1から始まっちゃダメでしたね、問題文を見て勘違いしてしまいました。

    ★「1から100まで」という日本語に当てはめると、
    let i = 1; i <= 100;
    になりますよね?
    let i = 0; i <100;
    これを日本語に直すと「0から99まで」で、今回は3で割るので結果に違いはありませんが
    よく気をつけるようにします。

    ★書式はfor (1式; 2式; 3式) {繰り返し}で構成され、
    forの中にifが入れ子になるのを和訳しようとするのが難しくて困りましたが、
    これはこういう式なんだ、というふうに覚えてしまった方がよさそうですね…。

    ★最後のifを使わない式は、確かにifいらないじゃん!となりました。
    ついつい覚えたての形で考えすぎて頭が固くなってしまいますね。
    もともと数学や論理的思考は得意ではないので苦労しそうですが、今後も頑張って勉強していこうと思います。ありがとうございました。

    キャンセル

  • 2018/11/29 13:53

    > forの中にifが入れ子になるのを和訳しようとするのが難しくて困りましたが、
    小説風に書くのであれば、こんな感じですね
    「魔法でiという名前の妖精を100体呼び出して命令した。番号が3の倍数の妖精だけ残れ」
    このようにJavaScriptの{}は「段落で区切った長文」や「命令形の発言」と解釈すると理解が早いかと思います。

    この辺の事情は日本語の文章も、JavaScriptのコードも同じなので、
    forやif文の{}を長い行数でダラダラ書きまくるとそれを読む人(後日改良したい自分や同僚)が死にます。
    もし長いエンジニア人生で沢山コードを書きたいのであれば「リーダブルコード」という書籍を読めば人間の文章とコードを行ったり来たりしながら理解しやすくなるのでオススメです。

    キャンセル

+2

申し訳ないのですが現在ついている日本語のコメント説明で分からないのが分かりません。
「しっくりこない」って非常に曖昧な表現です。
というか現在ついている説明文はほぼそのままでそれ以上かみ砕くのが難しいくらい簡素で明確なコメントです。
質問者さんがどう解釈しているのかもあわせて提示された方がいいかもしれません。

無理に言葉になおして解釈しようとするよりデータの流れを追ったほうがいいかもしれません。
デバッグしてみてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/27 19:43

    確かに、無理に言葉になおして解釈しようとするのが良くないのかもしれませんね…
    英単語つかうくせに英文法通じないし、そもそも日本人である自分が使いたいのに日本語にしようというのが無理な話だったかもしれません。
    とくに違和感があったのは「forの中にifを入れ子にする」の概念?の部分だったのですが、
    もうそういうものとして丸覚えしたほうがいいのでしょうね…。
    デバッグの件、教えていただいてありがとうございました。流れを追うっていうのはヒントになるかもしれないです。

    キャンセル

  • 2018/11/27 20:00

    既に回答にあるように日本語でも英語でもないので。仕様を理解して仕様通りに使うだけです。
    的確に使えるかどうかは実際に使ってデバッグして使いこなすしかありません。
    自転車と似てるかもしれませんね。例えば親とかからなんとなく教わって何回も試行錯誤して乗れるようになるので。それは説明書で片付くものではなく「全身でバランスをとる」「ペダルは足でこぐ」「ハンドルで行きたい方向を定める」といった「仕様」をやっていくうちに体に覚えさせるものですし。
    たまに質問出ますが日本語の文章で理解しようとしている人の大半は成長が遅いです。
    英語を覚えるのも同じですね。頭で日本語で翻訳して、それに対する返事を日本語で作って英語で翻訳して発声するって毎回やってたら会話成り立ちません。

    キャンセル

+2

プログラムがちょっと間違ってますが、それを含めてwhileで説明したほうがいいのでwhileで書いたときの説明をします

// 1~100までの3の倍数の和
let sum = 0;                        // 合計を足していく変数を定義します
let j = 1;                          // jを1とします
while(j <= 100) {                   // jが100以下のときは{}で囲われている処理をします
    if (j % 3 === 0) {                // jを3で割ったときのあまりが0のとき(いわゆる3の倍数のときは{}の処理をします
        sum += j;                       // sumにjを足します
    }                                 // ifの}が来たので条件による処理分岐終わり
    j = j + 1;                        // jにj + 1した値を入れます
}                                   // }が来たのでwhileのところに戻ります
console.log(sum);                   // sumを表示します

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/27 19:44

    Whileは次の章で覚えるみたいです、ありがとうございます。
    コメントアウトで流れを追って説明していただくのは初心者的にはとてもありがたいです。
    どんどん使えるタグ?が増えていくといろんな解き方ができそうですね。
    ご回答ありがとうございました!

    キャンセル

0

Rubyですと

puts [*0..100].select{|item| item % 3 == 0 }.inject(:+)
#=>1683


となります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.59%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る