ONLY DO WHAT ONLY YOU CAN DO

こけたら立ちなはれ 立ったら歩きなはれ

VBScript で Project Euler Problem 4

左右どちらから読んでも同じ値になる数を回文数という. 2桁の数の積で表される回文数のうち, 最大のものは 9009 = 91 × 99 である.

では, 3桁の数の積で表される回文数のうち最大のものを求めよ.

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 99.

Find the largest palindrome made from the product of two 3-digit numbers.

「3桁の数の積」ということだが、999 から 100 まで計算する必要もないだろうと...

Option Explicit
 
Private cnt: cnt = 0
Private max: max = 0
 
Call main
 
WScript.Echo "CNT = " & cnt
WScript.Echo "MAX = " & max
 
Private Sub main()
    Dim i
    For i = 999 To 900 Step -1
        Dim j
        For j = 999 To 900 Step -1
            cnt = cnt + 1
 
            Dim n: n = i * j
            Dim s: s = CStr(n)
            If s = StrReverse(s) Then
                If max < n Then
                    WScript.Echo CStr(i) & " * " & CStr(j) & " = " & s
                    max = n
                End If
            End If
        Next
    Next
End Sub
D:\Project Euler\Problem 004>cscript //nologo 001.vbs
993 * 913 = 906609
CNT = 10000
MAX = 906609

993 * 913 と、913 * 993 の2回計算してしまうので、同じ数の組み合わせを省略

Option Explicit
 
Private cnt: cnt = 0
Private max: max = 0
 
Call main
 
WScript.Echo "CNT = " & cnt
WScript.Echo "MAX = " & max
 
Private Sub main()
    Dim i
    For i = 999 To 900 Step -1
        Dim j
        For j = i To 900 Step -1
            cnt = cnt + 1
 
            Dim n: n = i * j
            Dim s: s = CStr(n)
            If s = StrReverse(s) Then
                If max < n Then
                    WScript.Echo CStr(i) & " * " & CStr(j) & " = " & s
                    max = n
                End If
            End If
        Next
    Next
End Sub
D:\Project Euler\Problem 004>cscript //nologo 002.vbs
993 * 913 = 906609
CNT = 5050
MAX = 906609

最大値以下なら、回文数かどうかのチェックは不要

Option Explicit
 
Private cnt: cnt = 0
Private max: max = 0
 
Call main
 
WScript.Echo "CNT = " & cnt
WScript.Echo "MAX = " & max
 
Private Sub main()
    Dim i
    For i = 999 To 900 Step -1
        Dim j
        For j = i To 900 Step -1
            Dim n: n = i * j
            If n < max Then Exit For
             
            cnt = cnt + 1

            Dim s: s = CStr(n)
            If s = StrReverse(s) Then
                If max < n Then
                    WScript.Echo CStr(i) & " * " & CStr(j) & " = " & s
                    max = n
                End If
            End If
        Next
    Next
End Sub
D:\Project Euler\Problem 004>cscript //nologo 003.vbs
993 * 913 = 906609
CNT = 2291
MAX = 906609

たとえば、現在の最大値が i=993, j=913 の場合、 i≦913 の場合を計算しても仕方ないので

Option Explicit
 
Private cnt: cnt = 0
Private max: max = 0
 
Call main
 
WScript.Echo "CNT = " & cnt
WScript.Echo "MAX = " & max
 
Private Sub main()
    Dim m: m = 0
    Dim i
    For i = 999 To 900 Step -1
        If i = m Then Exit For
 
        Dim j
        For j = i To 900 Step -1
            Dim n: n = i * j
            If n < max Then Exit For
             
            cnt = cnt + 1

            Dim s: s = CStr(n)
            If s = StrReverse(s) Then
                If max < n Then
                    WScript.Echo CStr(i) & " * " & CStr(j) & " = " & s
                    max = n
                    m = j
                End If
            End If
        Next
    Next
End Sub
D:\Project Euler\Problem 004>cscript //nologo 004.vbs
993 * 913 = 906609
CNT = 2291
MAX = 906609

最初の回文数を取得した時点で終了
(結果として正しい解が得られるし、断然速いが、何故これでOKなのか説明できない...)

Option Explicit
 
Private cnt: cnt = 0
Private max: max = 0
 
Call main
 
WScript.Echo "CNT = " & cnt
WScript.Echo "MAX = " & max
 
Private Sub main()
    Dim i
    For i = 999 To 900 Step -1
        Dim j
        For j = i To 900 Step -1
            cnt = cnt + 1
 
            Dim n: n = i * j
            Dim s: s = CStr(n)
            If s = StrReverse(s) Then
                If max < n Then
                    WScript.Echo CStr(i) & " * " & CStr(j) & " = " & s
                    max = n
                    Exit Sub
                End If
            End If
        Next
    Next
End Sub
D:\Project Euler\Problem 004>cscript //nologo 005.vbs
993 * 913 = 906609
CNT = 666
MAX = 906609

2桁の数の積の場合

 99989796959493929190
999801970296039504940593069207910890098910
989702960495069408931092129114901689188820
979603950694099312921591189021892488278730
969504940893129216912090248928883287368640
959405931092159120902589308835874086458550
949306921291189024893088368742864885548460
939207911490218928883587428649855684638370
929108901689248832874086488556846483728280
919009891888278736864585548463837282818190
908910882087308640855084608370828081908100
大きい数から順に、回文数かどうかチェックするなら、
 99
999801
 9998
99 9702
98  
 999897
99  9603
98 9604 
97   
 99989796
99   9504
98  9506 
97    
96    
の順に計算すべきだが、それだと解を得るまでの計算量が多くなる
 999897969594939291
99980197029603950494059306920791089009
98 9604950694089310921291149016 
97  94099312921591189021  
96   921691209024   
95    9025    
94         
93         
92         
91         
何故、これだけの計算で解が得られるのか?
 999897969594939291
99980197029603950494059306920791089009
明日に続く...