import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

public class Euler368 {
    static final int kStateCount = 20;
    static final MathContext mc = new MathContext(100, RoundingMode.HALF_UP);

    static int stateIndex(int digit, int runLen) {
        return digit * 2 + (runLen - 1);
    }

    static boolean hasThreeEqualConsecutive(long n) {
        String s = Long.toString(n);
        for (int i = 0; i < s.length() - 2; i++) {
            if (s.charAt(i) == s.charAt(i + 1) && s.charAt(i) == s.charAt(i + 2)) {
                return true;
            }
        }
        return false;
    }

    static class Transition {
        int digit;
        int to;

        Transition(int digit, int to) {
            this.digit = digit;
            this.to = to;
        }
    }

    static List<List<Transition>> buildAutomaton() {
        List<List<Transition>> trans = new ArrayList<>();
        for (int i = 0; i < kStateCount; i++)
            trans.add(new ArrayList<>());

        for (int d = 0; d <= 9; d++) {
            for (int r = 1; r <= 2; r++) {
                int s = stateIndex(d, r);
                for (int x = 0; x <= 9; x++) {
                    if (x == d) {
                        if (r == 2)
                            continue;
                        trans.get(s).add(new Transition(x, stateIndex(d, 2)));
                    } else {
                        trans.get(s).add(new Transition(x, stateIndex(x, 1)));
                    }
                }
            }
        }
        return trans;
    }

    static BigDecimal[][] solveMoments(List<List<Transition>> trans, int maxM) {
        BigDecimal[][] h = new BigDecimal[kStateCount][maxM + 1];
        for (int i = 0; i < kStateCount; i++) {
            for (int j = 0; j <= maxM; j++)
                h[i][j] = BigDecimal.ZERO;
        }

        long[][] binom = new long[maxM + 1][maxM + 1];
        for (int n = 0; n <= maxM; n++) {
            binom[n][0] = 1;
            binom[n][n] = 1;
            for (int k = 1; k < n; k++) {
                binom[n][k] = binom[n - 1][k - 1] + binom[n - 1][k];
            }
        }

        BigDecimal[][] digitPow = new BigDecimal[10][32];
        for (int d = 0; d <= 9; d++) {
            digitPow[d][0] = BigDecimal.ONE;
            for (int p = 1; p < 32; p++) {
                digitPow[d][p] = digitPow[d][p - 1].multiply(BigDecimal.valueOf(d), mc);
            }
        }

        BigDecimal c10 = BigDecimal.TEN;

        for (int m = 0; m <= maxM; m++) {
            BigDecimal c = BigDecimal.ONE.divide(c10.pow(m + 1, mc), mc);

            BigDecimal[][] a = new BigDecimal[kStateCount][kStateCount + 1];
            for (int i = 0; i < kStateCount; i++) {
                for (int j = 0; j <= kStateCount; j++)
                    a[i][j] = BigDecimal.ZERO;
            }

            for (int s = 0; s < kStateCount; s++) {
                a[s][s] = BigDecimal.ONE;
                for (Transition t : trans.get(s)) {
                    a[s][t.to] = a[s][t.to].subtract(c, mc);
                }

                BigDecimal rhs = (m == 0) ? BigDecimal.ONE : BigDecimal.ZERO;
                for (Transition t : trans.get(s)) {
                    for (int u = 0; u < m; u++) {
                        BigDecimal term = c.multiply(BigDecimal.valueOf(binom[m][u]), mc)
                                .multiply(digitPow[t.digit][m - u], mc)
                                .multiply(h[t.to][u], mc);
                        rhs = rhs.add(term, mc);
                    }
                }
                a[s][kStateCount] = rhs;
            }

            for (int col = 0; col < kStateCount; col++) {
                int pivot = col;
                for (int r = col + 1; r < kStateCount; r++) {
                    if (a[r][col].abs().compareTo(a[pivot][col].abs()) > 0) {
                        pivot = r;
                    }
                }

                BigDecimal[] temp = a[col];
                a[col] = a[pivot];
                a[pivot] = temp;

                BigDecimal pv = a[col][col];
                for (int j = col; j <= kStateCount; j++) {
                    a[col][j] = a[col][j].divide(pv, mc);
                }

                BigDecimal epsilon = new BigDecimal("1e-80");
                for (int r = 0; r < kStateCount; r++) {
                    if (r == col)
                        continue;
                    BigDecimal factor = a[r][col];
                    if (factor.abs().compareTo(epsilon) < 0)
                        continue;
                    for (int j = col; j <= kStateCount; j++) {
                        a[r][j] = a[r][j].subtract(factor.multiply(a[col][j], mc), mc);
                    }
                }
            }

            for (int s = 0; s < kStateCount; s++) {
                h[s][m] = a[s][kStateCount];
            }
        }
        return h;
    }

    static BigDecimal estimateSeriesValue(BigDecimal[][] h, int maxM, int prefixDigits) {
        long low = 1;
        long highSmall = 1;
        for (int i = 0; i < prefixDigits - 1; i++)
            highSmall *= 10;
        long highPrefix = highSmall * 10;

        BigDecimal total = BigDecimal.ZERO;

        for (long n = low; n < highSmall; n++) {
            if (!hasThreeEqualConsecutive(n)) {
                total = total.add(BigDecimal.ONE.divide(BigDecimal.valueOf(n), mc), mc);
            }
        }

        for (long p = highSmall; p < highPrefix; p++) {
            if (hasThreeEqualConsecutive(p))
                continue;

            int last = (int) (p % 10);
            int prev = (int) ((p / 10) % 10);
            int run = (last == prev) ? 2 : 1;
            int s = stateIndex(last, run);

            BigDecimal invP = BigDecimal.ONE.divide(BigDecimal.valueOf(p), mc);
            BigDecimal invPower = invP;
            BigDecimal contrib = BigDecimal.ZERO;
            int sign = 1;

            for (int m = 0; m <= maxM; m++) {
                BigDecimal term = h[s][m].multiply(invPower, mc);
                if (sign > 0)
                    contrib = contrib.add(term, mc);
                else
                    contrib = contrib.subtract(term, mc);
                invPower = invPower.multiply(invP, mc);
                sign = -sign;
            }
            total = total.add(contrib, mc);
        }
        return total;
    }

    static String solve() {
        List<List<Transition>> trans = buildAutomaton();
        int maxM = 16;
        BigDecimal[][] h = solveMoments(trans, maxM);
        BigDecimal val = estimateSeriesValue(h, maxM, 3);
        return String.format(java.util.Locale.US, "%.10f", val.setScale(10, RoundingMode.HALF_UP).doubleValue());
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
