A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:
1/2 = 0.5 1/3 = 0.(3) 1/4 = 0.25 1/5 = 0.2 1/6 = 0.1(6) 1/7 = 0.(142857) 1/8 = 0.125 1/9 = 0.(1) 1/10 = 0.1 Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.
Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.
using Common.Math;
using System;
namespace ProjectEuler_26
{
internal class Program
{
public static void Main(string[] args)
{
Tuple result = new Tuple(0, 0);
// start by getting primes up to 1000
var primes = Eratosthenes.GetPrimes(1000);
// loop backwards
for (int i = primes.Length - 1; i >= 0; i--)
{
int count;
// we know that the most a cyclical decimal will repeat is d-1
if ((count = GetCyclicalCount(primes[i])) == primes[i] - 1)
{
result = new Tuple(count, primes[i]);
break;
}
}
Console.WriteLine($"The value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part is {result.Item2} with {result.Item1} numbers in the cycle.");
}
private static int GetCyclicalCount(int prime)
{
int period = 1;
// using Fermat's Little Theorim you can get the count of numbers in the cycle referred to as a period
// Fermat's Little Theorim is defined as a^p=a%p
// where a is the number base and p is a prime of that number base
// this means that the count of cyclical numbers is the first modular power where the period test is not 1
while (ModularPow(10, period, prime) != 1)
{
period++;
}
return period;
}
private static int ModularPow(int @base, int exponent, int modulus)
{
if (modulus == 1) return 0;
int result = 1;
for (int i = 1; i <= exponent; i++)
{
result = (result * @base) % modulus;
}
return result;
}
}
}
using Common.Math;
using System;
using System.Collections.Generic;
namespace ProjectEuler_24
{
internal class Program
{
private static void Main(string[] args)
{
List permNumbers = new List { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int[] answer = new int[10];
// the number of permutations remaining is 1 less than the number we are
// looking for because the first perumation is our starting point
int permutationsRemaining = 999999;
int answerIdx = 0;
for (int i = 1; i < 10; i++)
{
// because the most permutations possible is described as n!
// we want to figure out how many times we have to go through,
// this gives us the first number
int factorialVal = (10 - i).Factorial();
int x = permutationsRemaining / factorialVal;
// now we need to calculate how many permutations remain after
// we set the first number to continue narrowing down our calculation
permutationsRemaining = permutationsRemaining % factorialVal;
// set the answer then increment the index
answer[answerIdx++] = permNumbers[x];
// can't use the number again, remove it
permNumbers.RemoveAt(x);
// make sure we haven't already calculated the permuation value
// we're trying to get
if (permutationsRemaining == 0)
{
break;
}
}
Console.WriteLine($"The 1000000th lexicographic permutation is: {string.Join("", answer)}");
}
}
}
Factorial Code
public static int Factorial(this int num)
{
if (num < 0)
{
return 0;
}
int result = 1;
for (int i = 1; i <= num; i++)
{
result *= i;
}
return result;
}
using Common.Math;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ProjectEuler_23
{
internal class Program
{
private const int HighestNumNotAbundantSum = 28123;
private static bool IsAbundant(int i)
{
int[] factors = i.GetFactors().Distinct().ToArray();
int sum = factors.Sum() - i;
return sum > i;
}
private static void Main(string[] args)
{
int sum = 0;
bool[] isAbundantSum = new bool[HighestNumNotAbundantSum + 1];
List abundantNumbers = new List();
//12 is the lowest abundant number
for (int i = 12; i < HighestNumNotAbundantSum - 12; i++)
{
if (IsAbundant(i))
{
abundantNumbers.Add(i);
for (int x = 0; x < abundantNumbers.Count; x++)
{
int abundantSum = i + abundantNumbers[x];
if (abundantSum <= HighestNumNotAbundantSum)
{
isAbundantSum[abundantSum] = true;
}
}
}
}
for (int i = 1; i < isAbundantSum.Length; i++)
{
if (!isAbundantSum[i])
{
sum += i;
}
}
Console.WriteLine($"Sum of all numbers than can't be the sum of two abundant numbers: {sum}");
}
}
}
MathExtensions.cs
using System.Collections.Generic;
using System.Linq;
namespace Common.Math
{
public static class MathExtensions
{
public static int[] GetFactors(this int num)
{
List factors = new List { 1, num };
int root = (int)System.Math.Sqrt(num);
for (int i = 2; i <= root; i++)
{
if (num % i == 0)
{
factors.Add(i);
factors.Add(num / i);
}
}
return factors.OrderBy(x => x).ToArray();
}
}
}
public class GoogleAuthenticatorService<TUser> : TotpSecurityStampBasedTokenProvider<TUser> where TUser : class
{
private static readonly DateTime UNIX_EPOCH = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public override Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<TUser> manager, TUser user)
{
return manager.GetTwoFactorEnabledAsync(user);
}
public string GenerateSecret()
{
byte[] buffer = new byte[9];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(buffer);
}
return Convert.ToBase64String(buffer).Substring(0, 10).Replace('/', '0').Replace('+', '1');
}
public string GetCode(string secret, long counter)
{
return GeneratePassword(secret, counter);
}
public string GetCode(string secret)
{
return GetCode(secret, GetCurrentCounter());
}
public long GetCurrentCounter()
{
return GetCurrentCounter(DateTime.UtcNow, UNIX_EPOCH, 30);
}
public bool IsValid(string secret, string code, int checkAdjacentIntervals = 1)
{
if (code == GetCode(secret))
return true;
for (int i = 1; i <= checkAdjacentIntervals; i++)
{
if (code == GetCode(secret, GetCurrentCounter() + i))
return true;
if (code == GetCode(secret, GetCurrentCounter() - i))
return true;
}
return false;
}
public override async Task<bool> ValidateAsync(string purpose, string token, UserManager<TUser> manager, TUser user)
{
return IsValid(await manager.GetSecurityStampAsync(user), token);
}
private string GeneratePassword(string secret, long iterationNumber, int digits = 6)
{
byte[] counter = BitConverter.GetBytes(iterationNumber);
if (BitConverter.IsLittleEndian)
Array.Reverse(counter);
byte[] key = Encoding.ASCII.GetBytes(secret);
byte[] hash;
using (HMACSHA1 hmac = new HMACSHA1(key))
{
hash = hmac.ComputeHash(counter);
}
int offset = hash[hash.Length - 1] & 0xf;
int binary =
((hash[offset] & 0x7f) << 24)
| ((hash[offset + 1] & 0xff) << 16)
| ((hash[offset + 2] & 0xff) << 8)
| (hash[offset + 3] & 0xff);
int password = binary % (int)Math.Pow(10, digits);
return password.ToString(new string('0', digits));
}
private long GetCurrentCounter(DateTime now, DateTime epoch, int timeStep)
{
return (long)(now - epoch).TotalSeconds / timeStep;
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(typeof(IConfigurationRoot), Configuration);
// Add framework services.
services.AddApplicationInsightsTelemetry(Configuration);
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AuthDbContext>()
.AddTokenProvider<GoogleAuthenticatorService<ApplicationUser>>("Google");
services.AddMvc();
services.Configure<IdentityOptions>(options =>
{
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10);
options.Lockout.MaxFailedAccessAttempts = 10;
});
services.Configure<CookieAuthenticationOptions>(options =>
{
options.LoginPath = new PathString("/Admin/Login");
});
}
[AllowAnonymous, HttpPost, ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel loginModel, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(loginModel.Username, loginModel.Password, false, true);
if (result.Succeeded)
{
return RedirectToLocal(returnUrl);
}
else if (result.RequiresTwoFactor)
{
return View("TwoAuth");
}
else if (result.IsLockedOut)
{
return View("Login");
}
}
loginModel.Password = null;
return View(loginModel);
}
[AllowAnonymous]
public async Task<IActionResult> TwoAuth(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user == null)
{
return View("Login");
}
return View();
}
[AllowAnonymous, ValidateAntiForgeryToken, HttpPost]
public async Task<IActionResult> TwoAuth(string code, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
if (user != null)
{
var result = await _signInManager.TwoFactorSignInAsync("Google", code, false, false);
if (result.Succeeded)
{
return RedirectToLocal(returnUrl);
}
else if (result.IsLockedOut)
{
return View("Login");
}
}
return View();
}
Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n). If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers.
For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace ProjectEuler_21
{
internal class Program
{
private static int[] GetFactors(int num)
{
List factors = new List { 1, num };
int root = (int)Math.Sqrt(num);
for (int i = 2; i <= root; i++)
{
if (num % i == 0)
{
factors.Add(i);
factors.Add(num / i);
}
}
return factors.Distinct().OrderBy(i => i).ToArray();
}
private static int GetFactorsSum(int num)
{
int[] factors = GetFactors(num);
int sum = 0;
// don't include the actual num in the sum
for (int i = 0; i < factors.Length - 1; i++)
{
sum += factors[i];
}
return sum;
}
private static void Main(string[] args)
{
Dictionary cache = new Dictionary();
List amicableNumbers = new List();
int amicableCount = 0;
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 9999; i > 0; i--)
{
int factorSum = 0;
if (!cache.ContainsKey(i))
{
factorSum = GetFactorsSum(i);
cache[i] = factorSum;
}
else
{
factorSum = cache[i];
}
if (!cache.ContainsKey(factorSum))
{
cache[factorSum] = GetFactorsSum(factorSum);
}
if (cache[factorSum] == i && i != factorSum)
{
amicableCount++;
amicableNumbers.Add(i);
amicableNumbers.Add(factorSum);
}
}
sw.Stop();
amicableNumbers = amicableNumbers.Distinct().OrderBy(i => i).ToList();
Console.WriteLine("Number of amicable numbers under 10000: {0}\r\nSum of amicable numbers: {2}\r\nAmicable Numbers: {3}\r\nElapsed time: {1} ms", amicableCount, sw.ElapsedMilliseconds, amicableNumbers.Sum(), string.Join(", ", amicableNumbers));
}
}
}