Use this to learn the idea, then write your own version.
1package main2 3import (4 . "fmt"5 "io"6 "strings"7)8 910func cf55D(in io.Reader, out io.Writer) {11 gcd := func(a, b int) int {12 for a != 0 {13 a, b = b%a, a14 }15 return b16 }17 lcms := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 18, 20, 21, 24, 28, 30, 35, 36, 40, 42, 45, 56, 60, 63, 70, 72, 84, 90, 105, 120, 126, 140, 168, 180, 210, 252, 280, 315, 360, 420, 504, 630, 840, 1260, 2520}18 idx := [2521]int{}19 for i, v := range lcms {20 idx[v] = i21 }22 lcmRes := [len(lcms)][10]int{}23 for i, v := range lcms {24 lcmRes[i][0] = i25 lcmRes[i][1] = i26 for d := 2; d < 10; d++ {27 lcmRes[i][d] = idx[v*d/gcd(v, d)]28 }29 }30 31 var T int32 var low, high string33 for Fscan(in, &T); T > 0; T-- {34 Fscan(in, &low, &high)35 n := len(high)36 low = strings.Repeat("0", n-len(low)) + low37 memo := make([][len(lcms)][2520]int, n)38 for i := range memo {39 for j := range memo[i] {40 for k := range memo[i][j] {41 memo[i][j][k] = -142 }43 }44 }45 var f func(int, int, int, bool, bool) int46 f = func(i, j, rem int, limitLow, limitHigh bool) (res int) {47 if i == n {48 if rem%lcms[j] > 0 {49 return 050 }51 return 152 }53 if !limitLow && !limitHigh {54 p := &memo[i][j][rem]55 if *p >= 0 {56 return *p57 }58 defer func() { *p = res }()59 }60 61 lo := 062 if limitLow {63 lo = int(low[i] - '0')64 }65 hi := 966 if limitHigh {67 hi = int(high[i] - '0')68 }69 70 for d := lo; d <= hi; d++ {71 res += f(i+1, lcmRes[j][d], (rem*10+d)%2520, limitLow && d == lo, limitHigh && d == hi)72 }73 return74 }75 Fprintln(out, f(0, 0, 0, true, true))76 }77}78 7980