A positive integer is called heptaphobic if it is not divisible by seven and no number divisible by seven can be produced by swapping two of its digits. Note that leading zeros are not allowed before or after the swap.
For example, 17 and 1305 are heptaphobic, but 14 and 132 are not because 14 and 231 are divisible by seven. Let C(N) count heptaphobic numbers smaller than N. You are given C(100) = 74 and C(10^4) = 3737.
Find C(10^13)
https://projecteuler.net/problem=954
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Heptaphobic_Super_Optimal { internal class Program { static void Main(string[] args) { DateTime s_time = DateTime.Now; long max = 100; // example upper bound long count = CountHeptaphobic(max); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(max + " Heptaphobic count: " + count); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); DateTime e_time = DateTime.Now; Console.WriteLine("Duration " + (e_time - s_time).TotalMinutes + " minutes"); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); } static long CountHeptaphobic(long max) { const int MaxDigits = 18; long[,] pow10Mod7 = new long[MaxDigits + 1, MaxDigits]; for (int len = 1; len <= MaxDigits; len++) { pow10Mod7[len, len - 1] = 1; for (int i = len - 2; i >= 0; i--) pow10Mod7[len, i] = (pow10Mod7[len, i + 1] * 10) % 7; } object lockObj = new object(); long total = 0; Parallel.For(1L, max, () => 0L, (n, state, local) => { if (IsHeptaphobicNumeric(n, pow10Mod7)) local++; return local; }, local => { lock (lockObj) total += local; }); return total; } static bool IsHeptaphobicNumeric(long num, long[,] pow10Mod7) { int[] digits = new int[18]; int len = 0; long tmp = num; while (tmp > 0) { digits[len++] = (int)(tmp % 10); tmp /= 10; } Array.Reverse(digits, 0, len); long mod7 = 0; for (int i = 0; i < len; i++) mod7 = (mod7 + digits[i] * pow10Mod7[len, i]) % 7; if (mod7 == 0) return false; for (int i = 0; i < len; i++) { for (int j = i + 1; j < len; j++) { if (i == 0 && digits[j] == 0) continue; long delta = ((digits[i] - digits[j]) * (pow10Mod7[len, j] - pow10Mod7[len, i])) % 7; long newMod = (mod7 + delta + 7) % 7; if (newMod == 0) return false; } } return true; } } } |










