合成数列の和を算出するWindowsバッチ


概要

合成数列の和 Advent Calendar 2018の内容

【ルール】
・入力として正の整数 N を与えたら 4 から始まる 合成数 の数列の 1 番目から N 番目までの合計を出力してください
・N は最大で 100 とします

演習のお題として丁度よかったので
業務でも転用しやすそうなWindowsのバッチで作成しました。

合成数とは

Wikipediaによると、

合成数(ごうせいすう、英: Composite number)は、自然数で、1とその数自身以外の約数を持つ数である。2つ以上の素数の積で表すことのできる自然数と定義してもよい。

とのことです。
素数は知っておりましたが合成数という言葉は初めて聞きました。

要するに素数と1以外の正の整数
正の整数:{1,2,3,4,5,…}
素数:{2,3,5,7,11,…}
合成数:{4,6,8,9,10,…}
※自然数に0を含めるかどうかについては場合によりますが今回は関係ないため記載など省略しています。

内容

  • 実行方法
     1. 下記のコードを任意のファイル名(hoge.bat等)で保存
     2. ダブルクリックもしくはコマンドプロンプト上でNを引数に指定して実行
     2-1. cd [実行ファイル格納パス]
     2-2. [バッチファイル名] XX
       ※XXに数を指定する
hoge.bat
@echo off
setlocal enabledelayedexpansion
set rsl=0
set cnt=0
set i=1

if "a%~1" == "a" (
  set N=100 
  set msg=Input value of N be setting !N! ,if default of no input parameter.  
) else (
  set N=%1
  set msg=Input value of N be setting !N!
)
echo %msg%

:loopWhile_N
  set j=2
  if !i! equ !j! (
    goto ct_loopWhile_i
  )
  rem echo debug i:!i! j:!j! cnt:!cnt! rsl:!rsl! chkval:!chkval! inLoopWhileN
  :loopWhile_i
    set /a "j_2 = !j! * !j! " 
    set /a "chkval = !i! / !j!"
    set /a "chkval = !chkval! * !j!"
    rem echo debug i:!i! j:!j! cnt:!cnt! rsl:!rsl! chkval:!chkval! inLoopWhilei
    if !chkval! equ !i! (
      set /a "rsl = !i! + !rsl!"
      set /a "cnt = !cnt! + 1"
      echo debug i:!i! j:!j! cnt:!cnt! rsl:!rsl!
      goto ct_loopWhile_i
    ) 

    if !i! lss !j_2! (
      goto ct_loopWhile_i
    )
    set /a "j = !j! + 1"
    if !j! lss !i! (
      goto loopWhile_i
    )
  :ct_loopWhile_i
  set /a "i = !i! + 1"
  if !cnt! lss %N% (
    goto loopWhile_N
  )
echo The Sum result of synthetic sequence at %N%th is !rsl!.
endlocal
pause
exit /b

出力例

Microsoft Windows [Version 10.0.17134.407]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Users\********>cd \w

C:\w>hoge.bat 100
Input value of N be setting 100
debug i:4 j:2 cnt:1 rsl:4
debug i:6 j:2 cnt:2 rsl:10
debug i:8 j:2 cnt:3 rsl:18
debug i:9 j:3 cnt:4 rsl:27
debug i:10 j:2 cnt:5 rsl:37
debug i:12 j:2 cnt:6 rsl:49
debug i:14 j:2 cnt:7 rsl:63
debug i:15 j:3 cnt:8 rsl:78
debug i:16 j:2 cnt:9 rsl:94
debug i:18 j:2 cnt:10 rsl:112
debug i:20 j:2 cnt:11 rsl:132
debug i:21 j:3 cnt:12 rsl:153
debug i:22 j:2 cnt:13 rsl:175
debug i:24 j:2 cnt:14 rsl:199
debug i:25 j:5 cnt:15 rsl:224
debug i:26 j:2 cnt:16 rsl:250
debug i:27 j:3 cnt:17 rsl:277
debug i:28 j:2 cnt:18 rsl:305
debug i:30 j:2 cnt:19 rsl:335
debug i:32 j:2 cnt:20 rsl:367
debug i:33 j:3 cnt:21 rsl:400
debug i:34 j:2 cnt:22 rsl:434
debug i:35 j:5 cnt:23 rsl:469
debug i:36 j:2 cnt:24 rsl:505
debug i:38 j:2 cnt:25 rsl:543
debug i:39 j:3 cnt:26 rsl:582
debug i:40 j:2 cnt:27 rsl:622
debug i:42 j:2 cnt:28 rsl:664
debug i:44 j:2 cnt:29 rsl:708
debug i:45 j:3 cnt:30 rsl:753
debug i:46 j:2 cnt:31 rsl:799
debug i:48 j:2 cnt:32 rsl:847
debug i:49 j:7 cnt:33 rsl:896
debug i:50 j:2 cnt:34 rsl:946
debug i:51 j:3 cnt:35 rsl:997
debug i:52 j:2 cnt:36 rsl:1049
debug i:54 j:2 cnt:37 rsl:1103
debug i:55 j:5 cnt:38 rsl:1158
debug i:56 j:2 cnt:39 rsl:1214
debug i:57 j:3 cnt:40 rsl:1271
debug i:58 j:2 cnt:41 rsl:1329
debug i:60 j:2 cnt:42 rsl:1389
debug i:62 j:2 cnt:43 rsl:1451
debug i:63 j:3 cnt:44 rsl:1514
debug i:64 j:2 cnt:45 rsl:1578
debug i:65 j:5 cnt:46 rsl:1643
debug i:66 j:2 cnt:47 rsl:1709
debug i:68 j:2 cnt:48 rsl:1777
debug i:69 j:3 cnt:49 rsl:1846
debug i:70 j:2 cnt:50 rsl:1916
debug i:72 j:2 cnt:51 rsl:1988
debug i:74 j:2 cnt:52 rsl:2062
debug i:75 j:3 cnt:53 rsl:2137
debug i:76 j:2 cnt:54 rsl:2213
debug i:77 j:7 cnt:55 rsl:2290
debug i:78 j:2 cnt:56 rsl:2368
debug i:80 j:2 cnt:57 rsl:2448
debug i:81 j:3 cnt:58 rsl:2529
debug i:82 j:2 cnt:59 rsl:2611
debug i:84 j:2 cnt:60 rsl:2695
debug i:85 j:5 cnt:61 rsl:2780
debug i:86 j:2 cnt:62 rsl:2866
debug i:87 j:3 cnt:63 rsl:2953
debug i:88 j:2 cnt:64 rsl:3041
debug i:90 j:2 cnt:65 rsl:3131
debug i:91 j:7 cnt:66 rsl:3222
debug i:92 j:2 cnt:67 rsl:3314
debug i:93 j:3 cnt:68 rsl:3407
debug i:94 j:2 cnt:69 rsl:3501
debug i:95 j:5 cnt:70 rsl:3596
debug i:96 j:2 cnt:71 rsl:3692
debug i:98 j:2 cnt:72 rsl:3790
debug i:99 j:3 cnt:73 rsl:3889
debug i:100 j:2 cnt:74 rsl:3989
debug i:102 j:2 cnt:75 rsl:4091
debug i:104 j:2 cnt:76 rsl:4195
debug i:105 j:3 cnt:77 rsl:4300
debug i:106 j:2 cnt:78 rsl:4406
debug i:108 j:2 cnt:79 rsl:4514
debug i:110 j:2 cnt:80 rsl:4624
debug i:111 j:3 cnt:81 rsl:4735
debug i:112 j:2 cnt:82 rsl:4847
debug i:114 j:2 cnt:83 rsl:4961
debug i:115 j:5 cnt:84 rsl:5076
debug i:116 j:2 cnt:85 rsl:5192
debug i:117 j:3 cnt:86 rsl:5309
debug i:118 j:2 cnt:87 rsl:5427
debug i:119 j:7 cnt:88 rsl:5546
debug i:120 j:2 cnt:89 rsl:5666
debug i:121 j:11 cnt:90 rsl:5787
debug i:122 j:2 cnt:91 rsl:5909
debug i:123 j:3 cnt:92 rsl:6032
debug i:124 j:2 cnt:93 rsl:6156
debug i:125 j:5 cnt:94 rsl:6281
debug i:126 j:2 cnt:95 rsl:6407
debug i:128 j:2 cnt:96 rsl:6535
debug i:129 j:3 cnt:97 rsl:6664
debug i:130 j:2 cnt:98 rsl:6794
debug i:132 j:2 cnt:99 rsl:6926
debug i:133 j:7 cnt:100 rsl:7059
The Sum result of synthetic sequence at 100th is 7059.
続行するには何かキーを押してください . . .

課題

  • N=100でも3秒ほどかかりより効率的に処理したい(下記の判定で少し早くなった)
  • 合成数の判断時にj^2までみて合成数でない場合に最小公約数の2以降合成数が現れないのでその内容を実装する(j^2がNを超えた段階でそれ以降合成数になりえるjが出てこない特性を踏まえて反映済み)
  • Windowsのバッチの仕様なのかcontinueやwhileがなく、gotoでゴリ押ししている。より効率的に処理したい
  • 30分くらいでできると見積もっていたにもかかわらず3時間ほどかかりより早く書けるようになりたい