├── tools ├── deploy.cmd ├── lib │ ├── booc.exe │ ├── booi.exe │ ├── booish.exe │ ├── Boo.Lang.dll │ ├── Boo.Lang.CodeDom.dll │ ├── Boo.Lang.Parser.dll │ ├── Boo.Lang.Useful.dll │ ├── Boo.Lang.Compiler.dll │ ├── Boo.Lang.Extensions.dll │ ├── Boo.Lang.Interpreter.dll │ ├── Boo.Lang.PatternMatching.dll │ ├── booc.exe.config │ ├── booi.exe.config │ └── booish.exe.config ├── util │ ├── msbuild35.exe │ ├── ilmerge │ │ └── ILMerge.exe │ └── msbuild │ │ ├── GitSharp.dll │ │ ├── GitSharp.Core.dll │ │ ├── Tamir.SharpSSH.dll │ │ ├── Ionic.Zip.Reduced.dll │ │ ├── Simple.Tools.MsBuild.dll │ │ ├── ICSharpCode.SharpZipLib.dll │ │ ├── MSBuild.Community.Tasks.dll │ │ └── Simple.Tools.MsBuild.Targets ├── build.cmd ├── src │ ├── BooRunner │ │ ├── Tools │ │ │ ├── IntX │ │ │ │ ├── Utils │ │ │ │ │ ├── FhtMultiplicationException.cs │ │ │ │ │ └── Enums.cs │ │ │ │ ├── StringConverters │ │ │ │ │ ├── IStringConverter.cs │ │ │ │ │ ├── StringConvertManager.cs │ │ │ │ │ ├── ClassicStringConverter.cs │ │ │ │ │ └── Pow2StringConverter.cs │ │ │ │ ├── Parsers │ │ │ │ │ ├── IParser.cs │ │ │ │ │ ├── ParseManager.cs │ │ │ │ │ ├── ClassicParser.cs │ │ │ │ │ └── Pow2Parser.cs │ │ │ │ ├── Bits.cs │ │ │ │ ├── DigitConverter.cs │ │ │ │ ├── Multipliers │ │ │ │ │ ├── IMultiplier.cs │ │ │ │ │ ├── MultiplyManager.cs │ │ │ │ │ ├── ClassicMultiplier.cs │ │ │ │ │ └── MultiplierBase.cs │ │ │ │ ├── Settings │ │ │ │ │ └── IntXSettings.cs │ │ │ │ ├── Dividers │ │ │ │ │ ├── DivideManager.cs │ │ │ │ │ └── IDivider.cs │ │ │ │ └── OpHelpers │ │ │ │ │ └── StrRepHelper.cs │ │ │ └── Heap.cs │ │ ├── Program.cs │ │ ├── Options.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── BooEulerCompiler.cs │ │ ├── OneRunner.cs │ │ ├── ManyRunner.cs │ │ ├── TimeoutRunner.cs │ │ └── RunnerResult.cs │ └── BooEulerTools.sln └── build.xml ├── 100.boo ├── boot.exe ├── Boo.Lang.dll ├── Boo.Lang.Parser.dll ├── Boo.Lang.Compiler.dll ├── Boo.Lang.Extensions.dll ├── .gitignore ├── 003.boo ├── 007.boo ├── 016.boo ├── 097.boo ├── README.textile ├── 006.boo ├── 010.boo ├── 002.boo ├── 071.boo ├── 019.boo ├── 001.boo ├── 048.boo ├── 020.boo ├── 055.boo ├── 015.boo ├── 131.boo ├── 030.boo ├── 086.boo ├── 057.boo ├── 005.boo ├── 069.boo ├── 072.boo ├── 056.boo ├── LICENSE ├── 004.boo ├── 173.boo ├── 063.boo ├── 094.boo ├── 034.boo ├── 204.boo ├── 021.boo ├── 117.boo ├── 087.boo ├── 044.boo ├── 235.boo ├── 073.boo ├── 026.boo ├── 114.boo ├── 009.boo ├── 120.boo ├── 038.boo ├── 124.boo ├── 014.boo ├── 023.boo ├── 047.boo ├── 024.boo ├── 197.boo ├── 085.boo ├── 179.boo ├── 183.boo ├── 123.boo ├── 231.boo ├── 076.boo ├── 012.boo ├── 174.boo ├── 029.boo ├── 191.boo ├── 028.boo ├── 046.boo ├── 112.boo ├── 187.boo ├── 052.boo ├── 115.boo ├── 036.boo ├── 053.boo ├── 132.boo ├── 017.boo ├── 027.boo ├── 116.boo ├── 045.boo ├── 077.boo ├── 064.boo ├── 119.boo ├── 188.boo ├── 065.boo ├── 091.boo ├── 109.boo ├── 032.boo ├── 203.boo ├── 037.boo ├── 074.boo ├── 031.boo ├── 062.boo ├── 035.boo ├── 214.boo ├── 135.boo ├── 025.boo ├── 130.boo ├── 126.boo ├── 121.boo ├── 049.boo ├── 159.boo ├── 134.boo ├── 125.boo ├── 164.boo ├── 079.boo ├── 113.boo ├── 138.boo ├── 129.boo ├── 205.boo ├── 018.boo ├── 033.boo ├── 207.boo ├── 040.boo ├── 043.boo ├── 050.boo ├── 078.boo ├── 070.boo ├── 243.boo ├── 041.boo ├── 088.boo ├── 075.boo ├── 111.boo ├── 122.boo ├── 090.boo ├── 039.boo ├── 206.boo ├── 058.boo ├── 104.boo ├── 092.boo ├── 127.boo ├── 162.boo ├── 158.boo ├── 008.boo ├── 080.boo ├── 106.boo ├── 066.boo ├── 118.boo ├── 095.boo ├── 051.boo ├── 101.boo ├── 084.boo ├── 103.boo ├── 068.boo ├── 011.boo ├── 061.boo ├── 093.boo ├── 060.boo ├── 108.boo ├── 110.boo └── 145.boo /tools/deploy.cmd: -------------------------------------------------------------------------------- 1 | call build deploy -------------------------------------------------------------------------------- /100.boo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/100.boo -------------------------------------------------------------------------------- /boot.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/boot.exe -------------------------------------------------------------------------------- /Boo.Lang.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/Boo.Lang.dll -------------------------------------------------------------------------------- /tools/lib/booc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/booc.exe -------------------------------------------------------------------------------- /tools/lib/booi.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/booi.exe -------------------------------------------------------------------------------- /Boo.Lang.Parser.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/Boo.Lang.Parser.dll -------------------------------------------------------------------------------- /tools/lib/booish.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/booish.exe -------------------------------------------------------------------------------- /Boo.Lang.Compiler.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/Boo.Lang.Compiler.dll -------------------------------------------------------------------------------- /Boo.Lang.Extensions.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/Boo.Lang.Extensions.dll -------------------------------------------------------------------------------- /tools/lib/Boo.Lang.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/Boo.Lang.dll -------------------------------------------------------------------------------- /tools/util/msbuild35.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/msbuild35.exe -------------------------------------------------------------------------------- /tools/lib/Boo.Lang.CodeDom.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/Boo.Lang.CodeDom.dll -------------------------------------------------------------------------------- /tools/lib/Boo.Lang.Parser.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/Boo.Lang.Parser.dll -------------------------------------------------------------------------------- /tools/lib/Boo.Lang.Useful.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/Boo.Lang.Useful.dll -------------------------------------------------------------------------------- /tools/util/ilmerge/ILMerge.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/ilmerge/ILMerge.exe -------------------------------------------------------------------------------- /tools/lib/Boo.Lang.Compiler.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/Boo.Lang.Compiler.dll -------------------------------------------------------------------------------- /tools/lib/Boo.Lang.Extensions.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/Boo.Lang.Extensions.dll -------------------------------------------------------------------------------- /tools/util/msbuild/GitSharp.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/msbuild/GitSharp.dll -------------------------------------------------------------------------------- /tools/lib/Boo.Lang.Interpreter.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/Boo.Lang.Interpreter.dll -------------------------------------------------------------------------------- /tools/lib/Boo.Lang.PatternMatching.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/lib/Boo.Lang.PatternMatching.dll -------------------------------------------------------------------------------- /tools/util/msbuild/GitSharp.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/msbuild/GitSharp.Core.dll -------------------------------------------------------------------------------- /tools/util/msbuild/Tamir.SharpSSH.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/msbuild/Tamir.SharpSSH.dll -------------------------------------------------------------------------------- /tools/util/msbuild/Ionic.Zip.Reduced.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/msbuild/Ionic.Zip.Reduced.dll -------------------------------------------------------------------------------- /tools/util/msbuild/Simple.Tools.MsBuild.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/msbuild/Simple.Tools.MsBuild.dll -------------------------------------------------------------------------------- /tools/util/msbuild/ICSharpCode.SharpZipLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/msbuild/ICSharpCode.SharpZipLib.dll -------------------------------------------------------------------------------- /tools/util/msbuild/MSBuild.Community.Tasks.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/juanplopes/euler/HEAD/tools/util/msbuild/MSBuild.Community.Tasks.dll -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | *.suo 4 | *.user 5 | *.log 6 | 7 | *.cache 8 | *.sln.cache 9 | TestResult.xml 10 | src/GlobalInfo.cs 11 | 12 | build/ 13 | pkg/ 14 | 15 | TestResults/ 16 | 17 | *.userprefs 18 | *.pidb 19 | *.resources 20 | -------------------------------------------------------------------------------- /003.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Trivial integer factorization using Sieve of Eratosthenes. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | answer = PrimeNumbers().Factorize(600851475143).Max() 8 | 9 | print answer 10 | assert answer == 6857 -------------------------------------------------------------------------------- /007.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Trivial prime discovery. Internally using Sieve of Eratosthenes. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | answer = PrimeNumbers(10**6).Skip(10000).First() 8 | 9 | print answer 10 | assert answer == 104743 -------------------------------------------------------------------------------- /016.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Ad-hoc. Using BigInteger. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | n = BigInteger(2).Pow(1000) 8 | 9 | answer = 0 10 | while(n > 0): 11 | answer += n%10 12 | n/=10 13 | 14 | print answer 15 | assert answer == 1366 -------------------------------------------------------------------------------- /097.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Solving big power using "modpow". 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | answer as BigInteger = (28433 * BigInteger(2).Pow(7830457, 10000000000) + 1) % 10000000000 8 | 9 | print answer 10 | assert answer == 8739992577 11 | -------------------------------------------------------------------------------- /tools/lib/booc.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tools/lib/booi.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tools/lib/booish.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | Prerequisite: have mono installed. 2 | 3 | h1. To run any example, just call: 4 | 5 | @./boot.exe NNN.boo@ [where NNN is the problem number] 6 | 7 | eg. @./boot.exe 015.boo@ 8 | 9 | h1. To run all examples at once, just call: 10 | 11 | @./boot.exe *.boo@ 12 | -------------------------------------------------------------------------------- /006.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Trivial solution. Using some LINQ, magic, but still trivial. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | sqr = {x as int|x*x} 8 | answer = sqr(range(1, 101).Sum()) - range(1, 101).Sum(sqr) 9 | 10 | print answer 11 | assert answer == 25164150 -------------------------------------------------------------------------------- /010.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Enumerate all primes upto 2000000 using Sieve of Eratosthenes. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | answer = PrimeNumbers(2*1000000).Cache.Select({x|Convert.ToInt64(x)}).Sum() 8 | 9 | print answer 10 | assert answer == 142913828922 11 | -------------------------------------------------------------------------------- /tools/build.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set BUILD_TARGET=%~1 4 | if "%BUILD_TARGET%"=="" set /p BUILD_TARGET="Build Target: " 5 | if not "%BUILD_TARGET%"=="" set BUILD_TARGET="/target:%BUILD_TARGET%" 6 | util\msbuild35 build.xml %BUILD_TARGET% %2 %3 %4 %5 %6 %7 %8 %9 7 | endlocal 8 | if errorlevel 1 pause 9 | -------------------------------------------------------------------------------- /002.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Creates infinite fibonacci lazy list, using generator. 3 | Then filters it using LINQ 4 | */ 5 | import System.Linq.Enumerable 6 | 7 | def fibs(): 8 | a,b=(0,1) 9 | while(true): 10 | a,b=(a+b,a) 11 | yield a 12 | 13 | answer = fibs().Where({x|x%2==0}).TakeWhile({x|x<=4*10**6}).Sum() 14 | 15 | print answer 16 | assert answer == 4613732 -------------------------------------------------------------------------------- /071.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Trivial solution. Approaches 2/5 to 3/7 by adding both numberator and 3 | denominator until the former reaches the maximum. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | an,ad = (2,5) 9 | bn,bd = (3,7) 10 | 11 | while ad+bd<=10**6: 12 | an,ad = (an+bn, ad+bd) 13 | 14 | answer = an 15 | print answer 16 | assert answer == 428570 -------------------------------------------------------------------------------- /019.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force using .Net date handling. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | def dates(): 8 | dt = DateTime(1901, 01, 01) 9 | while dt.Year <= 2000: 10 | yield dt 11 | dt = dt.AddDays(1) 12 | 13 | answer = dates().Count({d|d.DayOfWeek == DayOfWeek.Sunday and d.Day == 1}) 14 | print answer 15 | assert answer == 171 -------------------------------------------------------------------------------- /001.boo: -------------------------------------------------------------------------------- 1 | /* 2 | There are 1000/3 multiples of 3 below 1000. 3 | 4 | Their sum is 5 | (3+6+9+...+996+999) = 6 | (1+2+3+...332+333)*3 = 7 | (333*334/2)*3 8 | */ 9 | import System.Linq.Enumerable 10 | 11 | def T(n as int, k as int): 12 | m = n/k 13 | return m*(m+1)/2*k 14 | 15 | answer = T(999, 3) + T(999, 5) - T(999, 15) 16 | 17 | print answer 18 | assert answer == 233168 19 | -------------------------------------------------------------------------------- /048.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Use "powmod" principle. 3 | 4 | E.g.: (2^32)%100 == ((2^16)%100 * (2^16)%100) %100 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | answer as BigInteger = 0 10 | mod as BigInteger = 10000000000 11 | 12 | for i as long in range(1, 1001): 13 | answer += BigInteger(i).Pow(i, mod) 14 | answer %= mod 15 | 16 | print answer 17 | assert answer == 9110846700 -------------------------------------------------------------------------------- /020.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force, using BigInteger. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | def factorial(n as int) as int*: 8 | one = BigInteger(1L) 9 | for i in range(1,n+1): 10 | one = one * i 11 | while one > 0: 12 | yield cast(int, one % 10) 13 | one /= 10 14 | 15 | 16 | answer = factorial(100).Sum() 17 | print answer 18 | assert answer == 648 -------------------------------------------------------------------------------- /055.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Mostly brute force. Even the reverse is by string reverse. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | reverse = {n|Convert.ToDecimal(string(n.ToString().Reverse().ToArray()))} 8 | 9 | is_lychrel = {n as decimal| range(50).Select({x| n = n + reverse(n)}).All({x| x != reverse(x)})} 10 | 11 | answer = range(10000).Count(is_lychrel) 12 | 13 | assert answer == 249 14 | print answer -------------------------------------------------------------------------------- /tools/util/msbuild/Simple.Tools.MsBuild.Targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /015.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Dynamic Programming. Trivial one. 3 | T(x,0) = 1 4 | T(0,y) = 1 5 | T[x,y] = T(x-1, y) + T(x,y+1) 6 | */ 7 | import System 8 | import System.Linq.Enumerable 9 | 10 | T = matrix(long, 21, 21) 11 | for i in range(21): 12 | T[i,0] = 1 13 | T[0,i] = 1 14 | 15 | for i in range(1,21): 16 | for j in range(1,21): 17 | T[i,j] = T[i-1, j] + T[i, j-1] 18 | 19 | answer = T[20,20] 20 | 21 | print answer 22 | assert answer == 137846528820 -------------------------------------------------------------------------------- /131.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Check for prime numbers in sequence http://oeis.org/A003215 3 | 4 | More info at http://mathworld.wolfram.com/CubanPrime.html 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | primes = PrimeNumbers(10**6) 10 | 11 | def A003215(L as int): 12 | a = 1L 13 | for i in range(L): 14 | a += 6*i 15 | if a >= L: break 16 | yield a 17 | 18 | answer = A003215(10**6).Count(primes.IsPrime) 19 | print answer 20 | assert answer == 173 -------------------------------------------------------------------------------- /030.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force, caching n^5. Ignore one-digit numbers. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | D = range(10).Select({x as int|Math.Pow(x, 5)}).ToArray() 8 | 9 | def can_be_written_in_weird_way(n as int): 10 | sum = 0 11 | d = n 12 | while(d>0): 13 | sum += D[d%10] 14 | d/=10 15 | return sum==n 16 | 17 | answer = range(10,200000).Where(can_be_written_in_weird_way).Sum() 18 | 19 | print answer 20 | assert answer == 443839 -------------------------------------------------------------------------------- /086.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Based on http://oeis.org/A143714 3 | 4 | Just summing up all values in this sequence 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | c = 0 10 | for m in range(3, int.MaxValue): 11 | if c > 10**6: 12 | answer = m-1 13 | break 14 | for ab in range(3, 2*m): 15 | s = Math.Sqrt(ab*ab + m*m) 16 | if s == cast(int, s): 17 | c += Math.Min(ab, m+1) - cast(int, (ab+1)/2) 18 | 19 | print answer 20 | assert answer == 1818 -------------------------------------------------------------------------------- /057.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Just follow the rule to create all the fractions. n is the numerator (without 3 | the 1 +) d is the denominator. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | def num_digits(n as BigInteger): 9 | return n.ToString().Length 10 | 11 | n = BigInteger(1) 12 | d = BigInteger(2) 13 | 14 | answer = 0 15 | for i in range(1000): 16 | if num_digits(n+d) > num_digits(d): 17 | answer+=1 18 | n, d = (d,n+d*2) 19 | 20 | print answer 21 | assert answer == 153 -------------------------------------------------------------------------------- /005.boo: -------------------------------------------------------------------------------- 1 | /* 2 | The lowest integer that contains all the factors is defined by the product of 3 | all Lowest Common Multiplers (LCM) of all the factors. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | def gcd(a as long, b as long): 9 | while(b): a, b = (b, a%b) 10 | return a; 11 | 12 | def lcm(a as long, b as long): 13 | return a*b/gcd(a,b) 14 | 15 | answer as long = 1 16 | for i in range(1, 21): 17 | answer = lcm(answer, i) 18 | 19 | print answer 20 | assert answer == 232792560 -------------------------------------------------------------------------------- /069.boo: -------------------------------------------------------------------------------- 1 | /* 2 | The minimum possible totient, relative to a number n is composed by the product 3 | of the smallest possibile non-repeated primes. So, it's just a matter of 4 | multiplying them until it reaches 10**6. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | primes = PrimeNumbers() 10 | 11 | #to minimize totient, must have all smaller primes 12 | 13 | answer = 1 14 | for i in primes: 15 | if (answer*i > 10**6): break 16 | answer *= i 17 | 18 | print answer 19 | assert answer == 510510 -------------------------------------------------------------------------------- /072.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Precalculate all the phi values using a sieve algorithm. Mostly Eratosthenes, 3 | but multiplying it by the phi factor (1-1/p) for each prime that composes the 4 | number. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | L = 10**6+1 10 | T = range(L).ToList() 11 | for n in range(2, L): 12 | if T[n] == n: 13 | for k in range(n, L, n): 14 | T[k] *= 1.0 - 1.0/n; 15 | 16 | answer = -1L 17 | for i in T: 18 | answer += i 19 | 20 | print answer 21 | assert answer == 303963552391 -------------------------------------------------------------------------------- /056.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force with BigInteger. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | def digit_sum(a as BigInteger): 8 | sum = 0 9 | while(a>0): 10 | sum += a%10 11 | a/=10 12 | return sum 13 | 14 | def all_numbers(): 15 | #esoteric constraints, you may try without them 16 | for a in range(90,100): 17 | for b in range(90,100): 18 | yield BigInteger(a).Pow(b) 19 | 20 | answer = all_numbers().Max(digit_sum) 21 | 22 | print answer 23 | assert answer == 972 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2011 Juan Lopes 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. -------------------------------------------------------------------------------- /004.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Define is_palindrome predicate, by decomposing and recomposing reverselly. 3 | Then solve the rest by brute force. 4 | */ 5 | import System.Linq.Enumerable 6 | 7 | def is_palindrome(n as int): 8 | a = 0 9 | while(n>0): 10 | a = a*10+ n%10 11 | n/=10 12 | if (a==n): return true 13 | return false 14 | 15 | numbers = [a*b for a in range(100, 1000) for b in range(a, 1000)] 16 | 17 | answer = numbers.Cast[of int]().Distinct().Where(is_palindrome).Max() 18 | 19 | print answer 20 | assert answer == 906609 -------------------------------------------------------------------------------- /173.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force solution. 3 | 4 | Tries all pairs of squares that are either (even, even) or (odd, odd) to mantain 5 | aspect symmetry. 6 | 7 | Treats j backwars to make easy to prune out of range values, because i*i-j*j 8 | grows inverselly in terms of j. 9 | */ 10 | import System 11 | import System.Linq.Enumerable 12 | 13 | answer = 0 14 | for i as long in range(2, 3*10**5): 15 | for j as long in range(i-2, 0, -2): 16 | if i*i - j*j > 10**6: break 17 | answer+=1 18 | 19 | print answer 20 | assert answer == 1572729 -------------------------------------------------------------------------------- /063.boo: -------------------------------------------------------------------------------- 1 | /* 2 | The base may be 1-digit, so it's possible to raise it to n and the result have 3 | n digits. Try the raises and see how many results are n-digit. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | 9 | def count(a as BigInteger): 10 | c = 0 11 | while(a>0): 12 | c+=1 13 | a/=10 14 | return c 15 | 16 | answer = 0 17 | for a as BigInteger in range(1,10): 18 | for b in range(30): 19 | if count(a.Pow(b)) == b: 20 | answer+=1 21 | 22 | print answer 23 | assert answer == 49 -------------------------------------------------------------------------------- /094.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Reference 3 | from: http://oeis.org/A103974 4 | to: http://oeis.org/A120893 5 | 6 | Says that: 7 | a(n)=2*{2*a(n-1) + (-1)^n} - a(n-2) ; a(0)=1,a(1)=1. 8 | 9 | Just create the program to generate the sequence 10 | */ 11 | import System 12 | import System.Linq.Enumerable 13 | 14 | answer = 0L 15 | p, q = 1, 1 16 | for i in range(int.MaxValue): 17 | p,q= 4*p + 2*Math.Pow(-1, i) - q, p 18 | a = p 19 | b = a + Math.Pow(-1, i) 20 | if 2*a+b > 10**9: break 21 | answer += 2*a+b 22 | 23 | print answer 24 | assert answer == 518408346 -------------------------------------------------------------------------------- /034.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force. Try every number. Factorial for 0..9 is cached. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | facts = (1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880) 8 | 9 | def terms(a as int): 10 | while a>0: 11 | yield a%10 12 | a/=10 13 | 14 | 15 | def factorial_sum(a as int): 16 | return terms(a).Select({n|facts[n]}).Sum() 17 | 18 | def have_property(a as int): 19 | return a == factorial_sum(a) 20 | 21 | answer = range(3, 100000).Where(have_property).Sum() 22 | 23 | print answer 24 | assert answer == 40730 -------------------------------------------------------------------------------- /204.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force. 3 | 4 | Try all the multiplications of the allowed primes and count them. 5 | */ 6 | import System 7 | import System.Collections.Generic 8 | import System.Linq.Enumerable 9 | 10 | L = 1000000000 11 | P = PrimeNumbers().Until(100).ToArray() 12 | PM = P.Select({x|L/x}).ToArray() 13 | 14 | def backtrack(a as int, d as int) as int: 15 | res = 0 16 | for i in range(d, P.Length): 17 | if a <= PM[i]: 18 | res += 1 + backtrack(a*P[i], i) 19 | return res 20 | 21 | answer = backtrack(1, 0)+1 22 | 23 | print answer 24 | assert answer == 2944730 25 | -------------------------------------------------------------------------------- /021.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Uses a sieve algorithm to sum all divisors for each number. 3 | For example. For number 2, it jumps 4, 6, 8, etc, adding 2 to divisors sum. 4 | And so on. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | D = array(int, 10000) 10 | 11 | for i in range(1, 5000): 12 | for j in range(i*2, 10000, i): 13 | D[j] += i 14 | 15 | def d(i as int): 16 | if (i<0 or i>=10000): return -1 17 | return D[i] 18 | 19 | sum = 0 20 | for a in range(2,10000): 21 | b = d(a) 22 | if a==d(b) and a != b: 23 | sum+=a 24 | 25 | answer = sum 26 | print answer 27 | assert answer == 31626 -------------------------------------------------------------------------------- /117.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Dynamic programming solution: 3 | 4 | To calculate T[n], the number of solutions for n units, we try to insert blocks 5 | varying from length (j) 1 to 5, as 1 being an artificial block of color black. 6 | If we put a block of length 2, we solve the problem then for T[n-2]. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | L = 51 12 | T = array(long, L) 13 | 14 | for i in range(2): T[i] = 1 15 | 16 | for i in range(2, L): 17 | for j in range(1, 5): 18 | if (i-j >= 0): 19 | T[i] += T[i-j] 20 | 21 | answer = T[L-1] 22 | 23 | print answer 24 | assert answer == 100808458960497 -------------------------------------------------------------------------------- /087.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Basically brute force. Try all primes and use an array to keep track of what 3 | sums were already created. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | primes = PrimeNumbers() 9 | T = array(bool, 5*10**7) 10 | 11 | answer = 0 12 | for a in primes: 13 | n1 = a*a 14 | if n1 > 5*10**7: break 15 | for b in primes: 16 | n2 = n1+b*b*b 17 | if n2 > 5*10**7: break 18 | for c in primes: 19 | n = n2 + c*c*c*c 20 | if n>=5*10**7: break 21 | if not T[n]: answer+=1 22 | T[n] = true 23 | 24 | 25 | print answer 26 | assert answer == 1097343 -------------------------------------------------------------------------------- /044.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generate all pentagonal numbers upto 2500 and store in a hashtable. Then verify 3 | all pairs whose sum and difference are also pentagonal (using the hashtable). 4 | Get the minimum absolute value. 5 | */ 6 | import System 7 | import System.Collections.Generic 8 | import System.Linq.Enumerable 9 | 10 | def p(n as int): 11 | n++ 12 | return n*(3*n-1)/2 13 | 14 | P = HashSet[of int](range(2500).Select(p).ToArray()) 15 | 16 | pairs = [Math.Abs(j-k) 17 | for j in P 18 | for k in P 19 | if P.Contains(k-j) and P.Contains(j+k)] 20 | 21 | answer = pairs.Min() 22 | 23 | print answer 24 | assert answer == 5482660 -------------------------------------------------------------------------------- /235.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Binary search. Try values of r between 1 and 1.0025 adjusting it to make 3 | sequence sum the required value. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | def calc(r as double): 9 | a = 900 10 | b = 1.0 11 | s = 0.0 12 | for k in range(5000): 13 | a -= 3 14 | s += a*b 15 | b *= r 16 | return s 17 | 18 | a,b=1.0,1.0025 19 | 20 | while b-a>0.0000000000000005: 21 | m=(a+b)/2 22 | v = calc(m) 23 | if v>-600000000000: 24 | a = m 25 | else: 26 | b = m 27 | answer = Math.Round(a, 12) 28 | print answer 29 | assert answer == 1.002322108633 30 | -------------------------------------------------------------------------------- /073.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Recursive solution that generates all the value and verifies if it's part of the 3 | solution. 4 | 5 | e.g. count(1/3,1/2) finds the "center" to be 2/5 and counts how many fractions 6 | there are for (1/3,2/5) and (2/5,1/2) plus 2/5 itself. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | def count(an as int, ad as int, bn as int, bd as int, m as int) as int: 12 | tn, td = (an+bn, ad+bd) 13 | if td > m: return 0 14 | 15 | ra = count(an, ad, tn, td, m) 16 | rb = count(tn, td, bn, bd, m) 17 | 18 | return 1 + ra + rb 19 | 20 | answer = count(1,3,1,2,12000) 21 | print answer 22 | assert answer == 7295372 -------------------------------------------------------------------------------- /026.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Solves by doing successive divisions method and finding the recurring cycle when 3 | the remaining is 0 or 1. 4 | 5 | Tests only primes (that doesn't have fixed part in dizim). 6 | */ 7 | import System 8 | import System.Linq.Enumerable 9 | 10 | primes = PrimeNumbers() 11 | 12 | def rec(d as int): 13 | r = 1 14 | c = 0 15 | while(true): 16 | while(r max): 26 | max = r 27 | answer = i 28 | 29 | print answer 30 | assert answer == 983 -------------------------------------------------------------------------------- /114.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Dynamic programming solution: 3 | 4 | To calculate T[n], the number of solutions for n units, we will try to put "j" 5 | consecutive blocks starting at the position "k". And then solve the problem for 6 | T[n-j-k-1]. -1 because two groups of blocks must have one space between. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | T = array(long, 51) 12 | 13 | for i in range(0,3): T[i] = 1 14 | 15 | for i in range(3, 51): 16 | T[i] = i - 1 17 | for j in range(3, i): 18 | for k in range(0, i-j): 19 | T[i] += T[i-j-k-1] 20 | 21 | answer = T[50] 22 | 23 | print answer 24 | assert answer == 16475640049 -------------------------------------------------------------------------------- /009.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Given: 3 | a**2 + b**2 == c**2 and 4 | a+b+c == 1 5 | 6 | Then: 7 | b = (10**6 - 2000*a) / (2000 - 2.0*a) 8 | c = Math.Sqrt(a**2+b**2) 9 | 10 | So, it's just a matter of enumerating "a" and finding the first pair of integer 11 | values for "b" and "c" that makes a valid triangle. 12 | */ 13 | import System 14 | import System.Linq.Enumerable 15 | 16 | a=0.0;b=0.0;c=0.0 17 | for i in range(int.MaxValue): 18 | a = i 19 | b = (10**6 - 2000*a) / (2000 - 2.0*a) 20 | c = Math.Sqrt(a**2+b**2) 21 | if b == cast(int, b) and c == cast(int, c) and a < b and b < c: 22 | break 23 | 24 | answer = a*b*c 25 | 26 | print answer 27 | assert answer == 31875000 -------------------------------------------------------------------------------- /120.boo: -------------------------------------------------------------------------------- 1 | /* 2 | When n is even: 3 | 4 | (a-1)^n == ((a-1)^2)^n/2 == (a^2-2a+1) === -2a+1 mod a^2 5 | (a+1)^n == ((a+1)^2)^n/2 == (a^2+2a+1) === 2a+1 mod a^2 6 | 7 | (a-1)^n + (a+1)^n === 2 mod a^2 8 | 9 | When n is odd: 10 | 11 | The same, but multiplying by (a-1) and (a+1) factors, respectively. 12 | 13 | Which results in 2*a*n % (a*a) 14 | 15 | The least odd value for n that doestn't result in value greater than a*a is the 16 | last odd value before a/2, that is (a-1)/2. 17 | */ 18 | import System 19 | import System.Linq.Enumerable 20 | 21 | answer = 0 22 | for a in range(3, 1001): 23 | n = (a-1)/2 24 | answer += 2*a*n 25 | print answer 26 | assert answer == 333082500 -------------------------------------------------------------------------------- /038.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force. Not gotchas. Just being brute. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | def is_pandigital(a as string): 8 | if a.Length != 9: return false 9 | digits = array(int, 10) 10 | for c in a: 11 | digits[cast(int, c) - cast(int, char('0'))]++ 12 | return digits.Skip(1).All({x|x==1}) and digits[0] == 0 13 | 14 | answer = 0 15 | for i in range(1, 10000): 16 | sum as string = '' 17 | for j in range(1, 100): 18 | sum += (i*j).ToString() 19 | if sum.Length > 9: break 20 | if is_pandigital(sum): answer = Math.Max(answer, int.Parse(sum)) 21 | 22 | print answer 23 | assert answer == 932718654 -------------------------------------------------------------------------------- /124.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Runs through all of primes until the limit, making a sieve to discover all 3 | values of rad. Since each prime is only counted once, there is no special logic 4 | to do. 5 | 6 | Then, it's just a matter of ordering the list and finding the E(k). 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | primes = PrimeNumbers(10**6) 12 | L = 10**5+1 13 | 14 | rad = array(int, L) 15 | for i in range(L): rad[i] = 1 16 | 17 | for i in primes.Until(L): 18 | for j in range(i, L, i): 19 | rad[j] *= i 20 | 21 | def E(k): 22 | return range(L).OrderBy({x as int|rad[x]}).Skip(k).First() 23 | 24 | answer = E(10000) 25 | print answer 26 | assert answer == 21417 -------------------------------------------------------------------------------- /014.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Calculates sequence size using recurrence and memoization. 3 | Then checks for the greater. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | T = array(int, 1000000) 9 | def seq(n as long) as long: 10 | if n 0: return T[n] 11 | if (n==0): return 1 12 | if (n==1): return 0 13 | if (n&1): d = seq(n*3+1) + 1 14 | else: d = seq(n/2) + 1 15 | if n max_value: 24 | max_value = temp 25 | answer = i 26 | 27 | print answer 28 | assert answer == 837799 -------------------------------------------------------------------------------- /023.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Test all possible sum of two abundant numbers and store the results. 3 | Sum the numbers that doesn't have any results associated. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | n = 21000 9 | F = array(int, n) 10 | 11 | for i in range(1, n/2): 12 | for j in range(i*2, n, i): 13 | F[j] += i 14 | 15 | A = range(n).Where({x as int|F[x] > x}).ToArray() 16 | C = array(bool, n) 17 | 18 | for i in range(A.Length): 19 | for j in range(i+1): 20 | if (A[i]+A[j] >= C.Length): break 21 | C[A[i]+A[j]] = true 22 | 23 | answer = 0 24 | for i in range(n): 25 | if not C[i]: answer+=i 26 | 27 | print answer 28 | assert answer == 4179871 -------------------------------------------------------------------------------- /047.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Cheat: store in K[i] the number of prime factors of each number i 3 | 4 | Get the first of a sequence with exactly 4 prime factors. They'll be distinct. 5 | 6 | Trust me. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | import System.Collections.Generic 11 | 12 | primes = PrimeNumbers() 13 | K = array(int, 134043+4) 14 | 15 | for p in primes.Until(K.Length/2): 16 | for i in range(p*2, K.Length, p): 17 | K[i]+=1 18 | 19 | answer=0 20 | while(true): 21 | answer+=1 22 | a,b,c,d = range(answer, answer+4).Select({x as int|K[x]}).ToArray() 23 | if (a==4 and b==4 and c==4 and d==4): 24 | break 25 | 26 | print answer 27 | assert answer == 134043 -------------------------------------------------------------------------------- /024.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Uses factoradic to create the kth permutation of size n. 3 | Creates it as an array then mounts the number. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | def kth_permutation(n as int, k as int): 9 | data = array(int, n) 10 | for j in range(1, n+1): 11 | data[n-j] = (k % j) 12 | k /= j 13 | 14 | data[n-1] = 0 15 | for i in range(n-2, -1): 16 | for j in range(i+1, n): 17 | if data[j] >= data[i]: data[j] += 1 18 | return data 19 | 20 | answer as uint = 0 #because of long bug 21 | for i in kth_permutation(10, 999999): 22 | answer = answer * 10 + i 23 | 24 | print answer 25 | assert answer == 2783915460 -------------------------------------------------------------------------------- /197.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Don't really know how to explain that, but somehow this function turns that, 3 | for every value greater than a limit that I didn't care to know, this statement 4 | holds: 5 | 6 | Un == Un+2 7 | 8 | So, it's just a matter of calculating a function to find these two values and 9 | assume that U10^12 and U10^12+1 will be these two. 10 | */ 11 | import System 12 | import System.Linq.Enumerable 13 | 14 | def f(x as double): 15 | return Math.Floor(2.0**(30.403243784-x*x))/1000000000.0 16 | 17 | a,b,c = -1.0,-2.0,-3.0 18 | 19 | while true: 20 | a,b,c = f(a), a, b 21 | if a==c: 22 | answer = a+b 23 | break 24 | 25 | print answer 26 | assert answer == 1.710637717 27 | 28 | -------------------------------------------------------------------------------- /085.boo: -------------------------------------------------------------------------------- 1 | /* 2 | The number of rectangles in a NxM rectangle is defined by 3 | sum(1..N) * sum(1..M) 4 | 5 | Cache those sums and for each possible rectangle, find the one who has the min 6 | absolute difference to 2*10**6. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | T = array(long, 2000) 12 | T[0] = 0 13 | for i in range(1, 2000): 14 | T[i] = T[i-1] + i 15 | 16 | 17 | min = 2*10**6 18 | for i in range(2000): 19 | for j in range(2000): 20 | if T[i]*T[j] > 2*10**6+min: break 21 | 22 | x = Math.Abs(T[i]*T[j]-2*10**6) 23 | if x < min: 24 | min = x 25 | answer = i*j 26 | 27 | 28 | print answer 29 | assert answer == 2772 -------------------------------------------------------------------------------- /179.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Simple sieve to sum all the divisors for each value. Only computes divisors 3 | up to sqrt(L), because of the pairity of the divisors, sums in pairs, except for 4 | squares, that only counts once. 5 | 6 | Then the answer is found by searching for all computed values that meets the 7 | criteria. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | L = 10**7 13 | D = array(short, L) 14 | 15 | D[1] = 1 16 | for i in range(2,cast(int, Math.Sqrt(L))): 17 | D[i*i] += 1 18 | for j in range(i*i+i, L, i): 19 | D[j] += 2 20 | 21 | answer = 0 22 | for i in range(1,L): 23 | if (D[i] == D[i-1]): 24 | answer+=1 25 | 26 | print answer 27 | assert answer == 986262 -------------------------------------------------------------------------------- /183.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Seems the maximum value for K is round(N/e) (natural constant). 3 | 4 | So it's just a matter of determining if N/K is terminating. 5 | 6 | We check that verifying if the reduced form of k (taking of factors 2 and 5) is 7 | divisible by the numerator. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | def reduce(k as int): 13 | while true: 14 | if not k%2: k/=2 15 | elif not k%5: k/=5 16 | else: break 17 | return k 18 | 19 | 20 | def D(N as int): 21 | k = cast(int, Math.Round(N/Math.E)) 22 | 23 | return (N if N % reduce(k) else -N) 24 | 25 | 26 | answer = range(5, 10001).Sum(D) 27 | print answer 28 | assert answer == 48861552 29 | -------------------------------------------------------------------------------- /123.boo: -------------------------------------------------------------------------------- 1 | /* 2 | When n is even: 3 | 4 | (a-1)^n == ((a-1)^2)^n/2 == (a^2-2a+1) === -2a+1 mod a^2 5 | (a+1)^n == ((a+1)^2)^n/2 == (a^2+2a+1) === 2a+1 mod a^2 6 | 7 | (a-1)^n + (a+1)^n === 2 mod a^2 8 | 9 | When n is odd: 10 | 11 | The same, but multiplying by (a-1) and (a+1) factors, respectively. 12 | 13 | Which results in 2*a*n % (a^2) 14 | 15 | Then, it's just to test it for all odd primes above the known answer. 16 | */ 17 | import System 18 | import System.Linq.Enumerable 19 | 20 | primes = PrimeNumbers(10**6).Cache.ToList() 21 | 22 | for n in range(7039, primes.Count, 2): 23 | p = primes[n-1] cast long 24 | if 2*n*p > 10**10: 25 | answer = n 26 | break; 27 | 28 | print answer 29 | assert answer == 21035 -------------------------------------------------------------------------------- /231.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Fill primes sum using dynamic programing. Just: 3 | 4 | If you know S[n] = k, you know also that 5 | S[n*p] = k+p 6 | 7 | Then you just need to sum the values. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | P = PrimeNumbers(20000000).Cache.ToArray() 13 | S = array(int, 20000001) 14 | 15 | def fill(v as long, s as int, k as int): 16 | S[v] = s 17 | for i in range(k, P.Length): 18 | if v*P[i] > 20000000: break 19 | fill(v*P[i], s+P[i], i) 20 | 21 | fill(1, 0, 0) 22 | answer = 0L 23 | for i in range(15000001, 20000001): 24 | answer += S[i] 25 | for i in range(1, 5000001): 26 | answer -= S[i] 27 | 28 | print answer 29 | assert answer == 7526965179680L 30 | -------------------------------------------------------------------------------- /076.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Classic integer partition recurrence. Uses memoization. 3 | ' 4 | p(n,m) means in how many ways can we partition "n" using at most the factor "m". 5 | 6 | The "-1" is because the trivial solution "n = n" doesn't count as solution for 7 | this problem. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | T = matrix(int, 101, 101) 13 | for i in range(101): 14 | T[1, i] = 1 15 | 16 | def p(n as int, m as int) as int: 17 | if (n<0): return 0 18 | if (n==0): return 1 19 | if (T[n,m]!=0): return T[n,m] 20 | 21 | for i in range(1, m+1): 22 | T[n,m] = T[n,m] + p(n-i, i) 23 | 24 | return T[n,m] 25 | 26 | answer = p(100, 100) - 1 27 | print answer 28 | assert answer == 190569291 -------------------------------------------------------------------------------- /012.boo: -------------------------------------------------------------------------------- 1 | /* 2 | It is known that if a number can be primary decomposed as 3 | n1^k1 * n2^k2 * ... * nq^kq 4 | it has (k1+1)*(k2+1)*...*(kq+1) divisors. 5 | 6 | This solution uses this property to find the number of divisors. 7 | Then brute force. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | primes = PrimeNumbers() 13 | def divisors_count(n as int): 14 | factors = primes.Factorize(n).GroupBy({x|(x)}) 15 | r = 1 16 | for g in factors: 17 | r *= g.Count() + 1 18 | return r 19 | 20 | triangles = range(1, int.MaxValue).Select({n as int|n*(n+1)/2}) 21 | has_five_hundred = {n as int|divisors_count(n) > 500} 22 | answer = triangles.First(has_five_hundred) 23 | 24 | print answer 25 | assert answer == 76576500 -------------------------------------------------------------------------------- /174.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force solution. 3 | 4 | Tries all pairs of squares that are either (even, even) or (odd, odd) to mantain 5 | aspect symmetry. 6 | 7 | Treats j backwars to make easy to prune out of range values, because i*i-j*j 8 | grows inverselly in terms of j. 9 | 10 | Increases the results array for every subtraction result. Then counts the ones 11 | that are between 1 and 10. 12 | */ 13 | import System 14 | import System.Linq.Enumerable 15 | 16 | T = array(int, 10**6+1) 17 | 18 | for i as long in range(2, 3*10**5): 19 | for j as long in range(i-2, 0, -2): 20 | v = i*i - j*j 21 | if v > 10**6: break 22 | T[v] += 1 23 | 24 | answer = T.Count({x|x >= 1 and x <= 10}) 25 | print answer 26 | assert answer == 209566 -------------------------------------------------------------------------------- /029.boo: -------------------------------------------------------------------------------- 1 | /* 2 | If a**b != x**y, then b*log(a) != y*log(x). 3 | List all possible values for that count and check the distinct ones. 4 | Although decimal comparison is stronger than double, it's still weak. 5 | Do do this by sorting and checking the consecutive pairs with tolerance. 6 | */ 7 | import System 8 | import System.Linq.Enumerable 9 | 10 | def list(a as int, b as int) as decimal*: 11 | for i in range(2, a+1): 12 | for j in range(2, b+1): 13 | yield j*Math.Log(i) 14 | 15 | numbers = list(100,100).ToList() 16 | numbers.Sort() 17 | 18 | answer = 1 19 | for i in range(1,numbers.Count): 20 | if (Math.Abs(numbers[i] - numbers[i-1]) > 1e-7f): 21 | answer++ 22 | 23 | print answer 24 | assert answer == 9183 -------------------------------------------------------------------------------- /191.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Dynamic Programming over T, where T[a,b,c] is "how many prize strings are there 3 | with 'a' days, 'b' lates and ending in 'c' absents"? 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | T = matrix(int, 31, 2, 3) 9 | 10 | T[0,0,0] = 1 11 | 12 | for i in range(30): 13 | for j in range(2): 14 | for k in range(3): 15 | T[i+1, j, 0] = T[i+1, j, 0] + T[i,j,k] 16 | if j+1 < 2: 17 | T[i+1, j+1, 0] = T[i+1, j+1, 0] + T[i,j,k] 18 | if k+1 < 3: 19 | T[i+1, j, k+1] = T[i+1, j, k+1] + T[i,j,k] 20 | 21 | answer = 0 22 | for i in range(2): 23 | for j in range(3): 24 | answer += T[30, i, j] 25 | print answer 26 | assert answer == 1918080160 27 | -------------------------------------------------------------------------------- /028.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Defines a function T, that mathematically generates all the numbers in the diag. 3 | 4 | eg.: T(1) = 3+5+7+9, T(2) = 13+17+21+25 5 | 6 | It is possible because the first last term of each spiral is always a an odd 7 | square. And the first is always the last term of the last square + a quarter 8 | spiral - 1. 9 | 10 | So, the last is x*x and the first is y*y+x-1. So the total for spiral is twice 11 | the sum of these values. 12 | */ 13 | import System 14 | import System.Linq.Enumerable 15 | 16 | def T(n as long) as long: 17 | if (n==0): return 1 18 | x = 2*n+1 19 | y = x-2 20 | return 2*(x*x+y*y+x-1) 21 | 22 | answer = 0 23 | for i in range(1001/2+1): 24 | answer += T(i) 25 | 26 | print answer 27 | assert answer == 669171001 -------------------------------------------------------------------------------- /046.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Use sieve primality test. Cache numbers that are twice some square (TS). 3 | 4 | To verify if n have the property, try all primes until n, see if any difference 5 | is twice a square (using cached values). 6 | */ 7 | 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | L = 10000 12 | 13 | primes = PrimeNumbers() 14 | 15 | is_int = {n as double| n==cast(int,n)} 16 | is_twice_a_square = {n as int | is_int(Math.Sqrt(n/2.0)) } 17 | TS = range(L).Select(is_twice_a_square).ToArray() 18 | 19 | def isnot_goldbach(n as int): 20 | return not primes.Until(n).Any({p|TS[n-p]}) 21 | 22 | odd_composites = range(3, L, 2).Where({x|not primes.IsPrime(x)}) 23 | answer = odd_composites.First(isnot_goldbach) 24 | 25 | print answer 26 | assert answer == 5777 -------------------------------------------------------------------------------- /112.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Check bounciness by not being increasing nor decreasing. Brute force then. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | def is_it(n as int, f as int): 8 | a = -1 9 | while n: 10 | b = n%10 11 | if a != -1 and f*a > f*b: return false 12 | a = b 13 | n/=10 14 | return true 15 | 16 | def is_inc(n as int): 17 | return is_it(n, 1) 18 | 19 | def is_dec(n as int): 20 | return is_it(n, -1) 21 | 22 | def is_bouncy(n as int): 23 | return not (is_inc(n) or is_dec(n)) 24 | 25 | c = 0 26 | for i in range(1, int.MaxValue): 27 | if is_bouncy(i): c+=1 28 | if (i-c)*100 == i: 29 | answer = i 30 | break 31 | 32 | print answer 33 | assert answer == 1587000 -------------------------------------------------------------------------------- /187.boo: -------------------------------------------------------------------------------- 1 | /* 2 | For each prime up to sqrt(10**8), find via binary search the first prime that, 3 | multipied by the first, is greater than 10**8. Them sum the difference of indexes 4 | to the answer. This is: the number of primes greater thant the current that 5 | multiplied by the current is less thant 10**8. 6 | 7 | Must improve. 8 | */ 9 | import System 10 | import System.Collections.Generic 11 | import System.Linq.Enumerable 12 | 13 | primes = PrimeNumbers(10**8/2).Cache.ToList() 14 | answer = 0 15 | for i in range(primes.Count): 16 | if primes[i] >= 10**4: break 17 | target = 10**8/primes[i] 18 | 19 | j = primes.BinarySearch(target) +1 20 | if j <= 0: j = -j 21 | 22 | answer += j-i 23 | 24 | print answer 25 | assert answer == 17427258 -------------------------------------------------------------------------------- /052.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force. Uses hashset for digits comparisons. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | import System.Collections.Generic 7 | 8 | def digits(a as int): 9 | while a != 0: 10 | yield a % 10 11 | a/=10 12 | 13 | def are_same(a as int, b as int): 14 | return HashSet[of int](digits(a)).SetEquals(digits(b)) 15 | 16 | def has_property(a as int): 17 | return false unless are_same(a, 2*a) 18 | return false unless are_same(2*a, 3*a) 19 | return false unless are_same(3*a, 4*a) 20 | return false unless are_same(4*a, 5*a) 21 | return false unless are_same(5*a, 6*a) 22 | return true 23 | 24 | answer = range(1, int.MaxValue).First(has_property) 25 | 26 | print answer 27 | assert answer == 142857 -------------------------------------------------------------------------------- /115.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Dynamic programming solution (related to 114): 3 | 4 | To calculate T[n], the number of solutions for n units, we will try to put "j" 5 | consecutive blocks starting at the position "k". And then solve the problem for 6 | T[n-j-k-1]. -1 because two groups of blocks must have one space between. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | L = 200 12 | M = 50 13 | T = array(long, L) 14 | 15 | for i in range(0,M): T[i] = 1 16 | 17 | for i in range(M, L): 18 | T[i] = i-M+2 19 | for j in range(M, i): 20 | for k in range(0, i-j): 21 | T[i] += T[i-j-k-1] 22 | 23 | 24 | for i in range(L): 25 | if T[i] > 10**6: 26 | answer = i 27 | break 28 | 29 | print answer 30 | assert answer == 168 -------------------------------------------------------------------------------- /036.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force. Just decompose in both bases and verify if it's equal to it's 3 | reverse. Eliminate even numbers as they can never palindromic (because 0 can 4 | never be the first digit of a binary number). 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | def terms(a as int, base as int): 10 | while a>0: 11 | yield a%base 12 | a/=base 13 | 14 | def is_palindromic(a as int): 15 | if (a&1==0): return false 16 | t2 = terms(a, 2) 17 | if not t2.SequenceEqual(t2.Reverse()): return false 18 | t10 = terms(a, 10) 19 | if not t10.SequenceEqual(t10.Reverse()): return false 20 | return true 21 | 22 | 23 | answer = range(1000000).Where(is_palindromic).Sum() 24 | 25 | print answer 26 | assert answer == 872187 27 | -------------------------------------------------------------------------------- /053.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Uses common combination recurrence: 3 | C(n,k) = C(n-1, k) * n / (n-k) 4 | 5 | Then solves it by dynamic programming. 6 | 7 | To avoid overflow, any result greater than 1 million is set to -1 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | C = matrix(int, 101, 101) 13 | 14 | for i in range(101): 15 | C[i, 0] = 1 16 | C[0, i] = 1 17 | C[i, i] = 1 18 | 19 | answer = 0 20 | for n in range(1,101): 21 | for k in range(1,n): 22 | if (C[n-1, k] != -1): 23 | C[n,k] = C[n-1, k] * n / (n-k) 24 | if (C[n,k] > 10**6): 25 | C[n,k] = -1 26 | answer+=1 27 | else: 28 | C[n,k] = -1 29 | answer+=1 30 | 31 | 32 | 33 | print answer 34 | assert answer == 4075 -------------------------------------------------------------------------------- /132.boo: -------------------------------------------------------------------------------- 1 | /* 2 | R(k) can be writen as: (10^k-1) / (10-1). 3 | 4 | Knowing if R(k) is divisible by some prime p is same as knowing if: 5 | 6 | (10^k-1)/9 mod p == 0 7 | or 8 | (10^k-1) mod (p*9) == 0 9 | 10 | Then, we just calculate this mod using podmod and find the first 40 primes 11 | that matches the condition. 12 | */ 13 | import System 14 | import System.Linq.Enumerable 15 | 16 | primes = PrimeNumbers(100000) 17 | 18 | def pow(a as int, n as int, mod as int): 19 | r, p = (1L, cast(long, a)) 20 | while(n): 21 | if n%2: r=(r*p)%mod 22 | p=(p*p)%mod 23 | n/=2 24 | 25 | return r 26 | 27 | def is_divisible(p as int): 28 | return (pow(10, 1000000000, p*9)-1)%(p*9)==0 29 | 30 | answer = primes.Where(is_divisible).Take(40).Sum() 31 | print answer 32 | assert answer == 843296 33 | -------------------------------------------------------------------------------- /017.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Precalculated sizes for units, tens, hundreds and teens. 3 | Different calculation only for teen values (11~19) 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | U = (0, 3, 3, 5, 4, 4, 3, 5, 5, 4) 9 | T = (0, 6, 6, 8, 8, 7, 7, 9, 8, 8) 10 | D = (0, 3, 6, 6, 5, 5, 5, 7, 6, 6) 11 | C = (0, 10, 10, 12, 11, 11, 10, 12, 12, 11) 12 | 13 | def NS(n as int): 14 | if (n==1000): return 11 15 | 16 | u = U[n%10] 17 | d = D[n/10%10] 18 | c = C[n/100%10] 19 | teen = (n % 100 in range(11, 20)) 20 | 21 | if (teen): 22 | n = c+T[n%10] 23 | if (c and u): n+=3 24 | else: 25 | n = c+d+u 26 | if (c and (u or d)): n+=3 27 | return n 28 | 29 | answer = range(1, 1001).Select(NS).Sum() 30 | 31 | print answer 32 | assert answer == 21124 -------------------------------------------------------------------------------- /027.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Almost brute force. Intelligent only to know that the best values for b are 3 | primes, since prime numbers are coprimes to all numbers before them. 4 | 5 | Also, when n==b, b^2 + ab + b is divisible by b, so there can be at most b 6 | consecutive prime numbers. This allows us to prune all values of b that are 7 | lesser than the current max. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | primes = PrimeNumbers() 13 | 14 | max = 0 15 | for a in range(-1000, 1000): 16 | for b in primes.Until(999): 17 | if b0 and primes.IsPrime(n)}).Count() 19 | if (n>max): 20 | max = n 21 | answer = a*b 22 | 23 | print answer 24 | assert answer == -59231 25 | -------------------------------------------------------------------------------- /116.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Dynamic programming solution (related to 117, solved it first): 3 | 4 | To calculate T[n], the number of solutions for n units, we try to insert blocks 5 | varying from length (j) 1 to 5, as 1 being an artificial block of color black. 6 | If we put a block of length 2, we solve the problem then for T[n-2]. 7 | 8 | Please notice that empty is not a valid solution. So we remove it from every 9 | configuration. 10 | */ 11 | import System 12 | import System.Linq.Enumerable 13 | 14 | answer = 0L 15 | for j in range(2, 5): 16 | T = array(long, 51) 17 | 18 | for i in range(2): T[i] = 1 19 | 20 | for i in range(2, 51): 21 | T[i] = T[i-1] 22 | if (i-j >= 0): 23 | T[i] += T[i-j] 24 | answer += T[50]-1 25 | 26 | print answer 27 | assert answer == 20492570929 -------------------------------------------------------------------------------- /045.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Replace n by triangle index in pentagonal and hexagonal formulae. That is: 3 | 4 | x = n(n+1)/2 (triangle) 5 | x = n(3n+1)/2 (pentagonal) 6 | x = n(2n-1)/2 (hexagonal) 7 | 8 | If for an arbirary value of x we can solve these equations, then we have an 9 | answer. 10 | 11 | So, what we try is to generate a known value of x using a triangle formula and 12 | verifying if it satisfies the pengatonal and hexagonal too. 13 | */ 14 | import System 15 | import System.Linq.Enumerable 16 | 17 | for n as long in range(286,100000): 18 | x = (n**2 + n)/2 19 | p = (0.5 + Math.Sqrt(0.25 + 6*x))/3 20 | h = (1 + Math.Sqrt(1 + 8*x))/4 21 | 22 | if p - cast(int, p) == 0 and h - cast(int, h) == 0: 23 | answer = x 24 | break 25 | 26 | print answer 27 | assert answer == 1533776805 -------------------------------------------------------------------------------- /077.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Classic integer partition recurrence, modified for only using prime numbers. 3 | Uses memoization. 4 | 5 | p(n,m) means in how many ways can we partition "n" using at most the factor "m". 6 | 7 | The only difference to the classic algorithm is that we only consider prime 8 | numbers as being valid factors. 9 | */ 10 | import System 11 | import System.Linq.Enumerable 12 | 13 | primes = PrimeNumbers() 14 | T = matrix(int, 101, 101) 15 | 16 | def sum(n as int, m as int) as int: 17 | if (n<0): return 0 18 | if (n==0): return 1 19 | if (T[n,m]!=0): return T[n,m] 20 | 21 | for i in primes.Until(m): 22 | T[n,m] = T[n,m] + sum(n-i, i) 23 | 24 | return T[n,m] 25 | 26 | answer = range(1,int.MaxValue).First({x as int|sum(x,x) > 5000}) 27 | print answer 28 | assert answer == 71 -------------------------------------------------------------------------------- /064.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Use common algorithm to create continuous fractions. Do it stopping before the 3 | point it starts to repeat. The answer includes the first parameter, so, instead 4 | of testing odds, we are testing the even. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | def CF(n as int): 10 | n1,d1 =(0,1) 11 | sqrtn = Math.Sqrt(n) 12 | while true: 13 | if d1 == 0: break 14 | 15 | nextn = cast(int, (sqrtn + n1) / d1) 16 | yield nextn 17 | 18 | if nextn == cast(int, sqrtn) * 2: break 19 | 20 | n2, d2 = (d1, n1 - d1 * nextn) 21 | n3, d3 = (-d2, (n - d2 ** 2) / n2) 22 | n1, d1 = (n3, d3) 23 | 24 | 25 | answer = range(10001).Count({x as int|CF(x).Count()%2==0}) 26 | print answer 27 | assert answer == 1322 28 | -------------------------------------------------------------------------------- /119.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Constructs all values for function A in an unordered form. Try all possible 3 | powers and check if their results have_property. The upper bounds for d and k 4 | aren't easily proved, but these values (70, 10) can output the 31 first values 5 | for A. 6 | */ 7 | import System 8 | import System.Linq.Enumerable 9 | 10 | def have_property(p as long, d as long): 11 | s = 0 12 | while p > 0: 13 | s += p%10 14 | p /= 10 15 | return s == d 16 | 17 | def A(): 18 | for d in range(2,70): 19 | for k as long in range(2, 10): 20 | p = Math.Pow(d, k) 21 | if p > 10**18: break 22 | if have_property(p, d) and p >= 10: yield p 23 | 24 | list = A().ToList() 25 | list.Sort() 26 | answer = list[29] 27 | print answer 28 | assert answer == 248155780267521 -------------------------------------------------------------------------------- /188.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Euler's theorem says that if a and b are coprimes, a^phi(b) mod b === 1 3 | 4 | 1777 is coprime with 1e8. And phi(1e8) = 4e7 5 | 6 | So, we reduce all exponents executing them from right to left mod 4e7. 7 | 8 | Then, at the end, we just power the base to the resulting exponent mod 1e8. 9 | */ 10 | import System 11 | import System.Linq.Enumerable 12 | 13 | def pow(a as long, n as long, mod as long): 14 | r, p = 1L, a 15 | while(n): 16 | if n%2: r=(r*p)%mod 17 | p=(p*p)%mod 18 | n/=2 19 | 20 | return r 21 | 22 | def hyperpow(a as long, n as long): 23 | exponent = a 24 | for i in range(n-2): 25 | exponent = pow(a, exponent, 40000000) 26 | return pow(a, exponent, 100000000) 27 | 28 | answer = hyperpow(1777, 1855) 29 | print answer 30 | assert answer == 95962097 31 | -------------------------------------------------------------------------------- /065.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Precompute in D all the values for the sequence upto a limit. 3 | 4 | Defines N, a function that returns the kth numerator for the e-continued frac. 5 | 6 | What remains is trivial. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | D = array(int, 102) 12 | D[0] = 2 13 | for i in range(1, 102): 14 | n=i-2 15 | if n%3==0: 16 | D[i] = (n/3)*2+2 17 | else: 18 | D[i] = 1 19 | 20 | def N(k as int) as BigInteger: 21 | n as BigInteger = 0 22 | d as BigInteger = 1 23 | for i in range(k, 0): 24 | n,d= d, d*D[i]+n 25 | return d*2+n 26 | 27 | def digits_of(k as int): 28 | n as BigInteger = N(k) 29 | while n>0: 30 | yield cast(int, n%10) 31 | n/=10 32 | 33 | answer = digits_of(99).Sum() 34 | 35 | print answer 36 | assert answer == 272 -------------------------------------------------------------------------------- /091.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force. Tried all possible coordinates for ax,ay,bx,by. Verify if it is a 3 | right triangle by calculating the length of the sides and trying the three 4 | posible variable with each side length. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | L = 51 10 | answer = 0 11 | for ax in range(0, L): 12 | for ay in range(0, L): 13 | if (ax==0 and ay==0): continue 14 | for bx in range(0, L): 15 | for by in range(0, L): 16 | if bx==0 and by==0 or (ax==bx and ay==by): continue 17 | A = ax*ax+ay*ay 18 | B = bx*bx+by*by 19 | C = (ax-bx)*(ax-bx)+(ay-by)*(ay-by) 20 | if A==B+C or B==A+C or C==A+B: 21 | answer+=1 22 | 23 | answer /= 2 24 | print answer 25 | assert answer == 14234 -------------------------------------------------------------------------------- /109.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute-force all possible combinations, since there are few. 3 | 4 | Just being careful to make the two first shots order-independent and the last 5 | one only uses doubles. 6 | */ 7 | import System 8 | import System.Collections.Generic 9 | import System.Linq.Enumerable 10 | 11 | normal = List[of int]() 12 | ending = List[of int]() 13 | 14 | normal.Add(0) 15 | normal.Add(25) 16 | normal.Add(50) 17 | ending.Add(50) 18 | for i in range(1, 21): 19 | normal.Add(i) 20 | normal.Add(i*2) 21 | normal.Add(i*3) 22 | ending.Add(i*2) 23 | 24 | answer = 0 25 | for i in range(normal.Count): 26 | for j in range(i, normal.Count): 27 | for k in range(ending.Count): 28 | if normal[i] + normal[j] + ending[k] < 100: 29 | answer += 1 30 | print answer 31 | assert answer == 38182 32 | -------------------------------------------------------------------------------- /032.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force throught all possible mutiplications, keeping track of which have 3 | been used (array P). For each of them that results into a pandigital number, 4 | sums into answer. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | def are_pandigital(a as int, b as int, c as int): 10 | digits = array(int, 10) 11 | while(a>0): digits[a%10]+=1;a/=10 12 | while(b>0): digits[b%10]+=1;b/=10 13 | while(c>0): digits[c%10]+=1;c/=10 14 | return digits.Skip(1).All({x|x==1}) and digits[0] == 0 15 | 16 | P = array(bool, 10000) 17 | 18 | answer = 0 19 | for i in range(1,10000): 20 | for j in range(i, 10000): 21 | if i*j < P.Length and not P[i*j] and are_pandigital(i, j, i*j): 22 | answer += i*j 23 | P[i*j] = true 24 | 25 | print answer 26 | assert answer == 45228 -------------------------------------------------------------------------------- /203.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Creates and yields all pascal numbers, then create a distinct list of them. 3 | Filters only who ares square-free, by factorizing and checking if all factors 4 | are distinct. Sum them. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | primes = PrimeNumbers() 10 | 11 | def is_square_free(n as long): 12 | factors = primes.Factorize(n).ToArray() 13 | return factors.Distinct().Count() == factors.Length 14 | 15 | def pascal(L) as long*: 16 | P = matrix(long, L, L) 17 | 18 | for i in range(L): 19 | P[i, 0] = 1 20 | 21 | yield 1L 22 | for i in range(1, L): 23 | for j in range(1, i+1): 24 | yield v = P[i-1,j] + P[i-1, j-1] 25 | P[i,j] = v 26 | 27 | answer = pascal(51).Distinct().Where(is_square_free).Sum() 28 | print answer 29 | assert answer == 34029210557338 -------------------------------------------------------------------------------- /037.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Decompose the number into its decimal digits and verify on the way if all stages 3 | are prime. Do the same to the reverse of the reversed decompositon (got it?). 4 | 5 | Just another brute force, by the way. 6 | */ 7 | import System 8 | import System.Linq.Enumerable 9 | 10 | primes = PrimeNumbers() 11 | 12 | def reverse(a as int): 13 | n = 0 14 | while(a != 0): 15 | n = n*10+a%10 16 | a/=10 17 | return n 18 | 19 | def is_truncatable(a as int): 20 | n = 0 21 | while(a != 0): 22 | n = n*10+a%10 23 | a/=10 24 | if a != 0 and not primes.IsPrime(a): return false 25 | if not primes.IsPrime(reverse(n)): return false 26 | return true 27 | 28 | answer = range(10, int.MaxValue).Where(is_truncatable).Take(11).Sum() 29 | 30 | print answer 31 | assert answer == 748317 -------------------------------------------------------------------------------- /074.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Recursive solution with memoization. Each recursion step constructs the next 3 | number and checks for the solution to it. 4 | 5 | Define the known solutions for problem stated numbers, they're the only stop 6 | cases. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | F = (1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880) 12 | T = array(int, 3*10**6) 13 | T[169] = 3 14 | T[1454] = 3 15 | T[363601] = 3 16 | T[871] = 2 17 | T[45361] = 2 18 | T[872] = 2 19 | T[45362] = 2 20 | 21 | def count(n as int) as int: 22 | if T[n] > 0: return T[n] 23 | d = n 24 | s = 0 25 | while(d>0): 26 | s+=F[d%10] 27 | d/=10 28 | if (s==n): r = 1 29 | else: r = count(s) + 1 30 | T[n] = r 31 | return r 32 | 33 | answer = range(10**6).Where({x as int|count(x)==60}).Count() 34 | print answer 35 | assert answer == 402 -------------------------------------------------------------------------------- /031.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Classic coin change problem. Used classic recurrence. 3 | K(i, j) means "in how many ways can I give a change of 'i' using at most the 4 | coin 'j'?". 5 | 6 | This solutions tries to (1) use the coin "j" and continue using the same coin 7 | K(i - W[j], j) 8 | 9 | or (2) try with a smaller coin: 10 | K(i, j-1) 11 | 12 | The sum of these two alternatives gives the answer for a specific K(i,j) 13 | */ 14 | import System 15 | import System.Linq.Enumerable 16 | 17 | n = 201 18 | W = (1, 2, 5, 10, 20, 50, 100, 200) 19 | K = matrix(int, n, W.Length) 20 | 21 | for i in range(W.Length): K[0, i] = 1 22 | 23 | for i in range(1,n): 24 | for j in range(W.Length): 25 | if (i-W[j] >= 0): K[i,j] = K[i,j] + K[i - W[j], j] 26 | if (j-1>=0): K[i,j] = K[i,j] + K[i, j-1] 27 | 28 | answer = K[200, W.Length-1] 29 | print answer 30 | assert answer == 73682 -------------------------------------------------------------------------------- /062.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generate all cubes of numbers upto a limit. Sort the chars of the string 3 | representation of the cube and call it the key. Store also who was the first 4 | cube that had this key. 5 | 6 | Do it until find a key that is associated to 5 cubes. Call the first cube of 7 | that key the answer. 8 | */ 9 | import System 10 | import System.Collections.Generic 11 | import System.Linq.Enumerable 12 | 13 | firsts = Dictionary[of string, long]() 14 | dic = Dictionary[of string, long]() 15 | 16 | for i as long in range(10000): 17 | cube = i**3 18 | key = string(cube.ToString().OrderBy({x|(x)}).ToArray()) 19 | if dic.ContainsKey(key): 20 | dic[key]+=1 21 | if dic[key] == 5: 22 | answer = firsts[key] 23 | break 24 | else: 25 | firsts[key] = cube 26 | dic[key] = 1 27 | 28 | print answer 29 | assert answer == 127035954683 -------------------------------------------------------------------------------- /035.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Rotate numbers by dividing it by 10 and adding the last number multipled by 3 | the log10 of the original number. 4 | 5 | The prime list is initialized with 1 million, to make fast prime checks. 6 | 7 | All that remains is brute force. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | pow10 = (1, 10**1, 10**2, 10**3, 10**4, 10**5, 10**6, 10**7, 10**8) 13 | primes = PrimeNumbers(1000000) 14 | def rotate(n as int, log as int): 15 | return n/10+pow10[log]*(n%10) 16 | 17 | def rotations(n as int): 18 | log = cast(int, Math.Log10(n)) 19 | d = rotate(n, log) 20 | while(d!=n): 21 | yield d 22 | d = rotate(d, log) 23 | 24 | def is_circular(n as int): 25 | return rotations(n).All(primes.IsPrime) 26 | 27 | answer = range(1000000).Where(primes.IsPrime).Where(is_circular).Count() 28 | 29 | print answer 30 | assert answer == 55 -------------------------------------------------------------------------------- /214.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Precalculate all the phi values using a sieve algorithm. Mostly Eratosthenes, 3 | but multiplying it by the phi factor (1-1/p) for each prime that composes the 4 | number. 5 | 6 | Then calculates the totient chain length by using the recurrence 7 | 8 | S[i] = S[totient(i)] + 1 9 | 10 | Check if the value is prime and sum if the totient chain size is 25. 11 | */ 12 | import System 13 | import System.Linq.Enumerable 14 | 15 | L = 40000001 16 | primes = PrimeNumbers(L) 17 | P = primes.Cache 18 | T = array(int, L) 19 | S = array(int, L) 20 | for i in range(L): 21 | T[i] = i 22 | 23 | for n in P: 24 | for k in range(n, L, n): 25 | T[k] *= 1.0 - 1.0/n; 26 | 27 | answer = 0L 28 | S[1] = 1 29 | for i in range(2, L): 30 | S[i] = S[T[i]] + 1 31 | if primes.IsPrime(i) and S[i] == 25: 32 | answer += i 33 | 34 | print answer 35 | assert answer == 1677366278943 36 | -------------------------------------------------------------------------------- /135.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Given x,y and z are terms of a decreasing arithmetic progression, we can 3 | redefine equation as 4 | 5 | x^2+(x-a)^2+(x-2a)^2=n, 6 | 7 | that can be written as: 8 | 9 | -(x-a)*(x-5a) = n 10 | 11 | For 'n' to stay positive, we need x-a to stay positive and x-5a to stay 12 | negative. Also, x-2a should also be positive. So, x/5 < a < x/2. 13 | 14 | We just loop through all possible values for x and a and count in T every found 15 | solution for every possible n. 16 | */ 17 | import System 18 | import System.Collections.Generic 19 | import System.Linq.Enumerable 20 | 21 | T = array(int, 1000000) 22 | 23 | for x in range(1, 1300000): 24 | a = Math.Floor(x/5.0)+1 25 | while x-2*a > 0: 26 | n = -(x-a)*(x-5*a) 27 | if n>=1000000: break 28 | T[n] += 1 29 | a += 1 30 | 31 | answer = T.Count({x|x==10}) 32 | print answer 33 | assert answer == 4989 34 | -------------------------------------------------------------------------------- /025.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force making bignum add by hand. Using base-10 integer array as storage. 3 | Very silly, but does the job. 4 | 5 | Someone told me that 6 | =CEILING( (1000 - 1 + LOG10(SQRT(5))) / LOG10((1+SQRT(5))/2),1) 7 | does the job faster, but I want to keep this original solution. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | def sum(a as (int), b as (int)) as int*: 13 | flag = 0 14 | for i in range(Math.Max(a.Length, b.Length)): 15 | if i= L: break 20 | for c as long in range(b, L): 21 | k = 2*(a*b+a*c+b*c) 22 | if k >= L: break 23 | kk = 4*(a+b+c-1) 24 | for x in range(L): 25 | n = k + x*kk + 4*x*x 26 | if n >= L: 27 | break 28 | C[n] += 1 29 | 30 | 31 | answer = range(L).First({n|C[n] == 1000}) 32 | print answer 33 | assert answer == 18522 34 | -------------------------------------------------------------------------------- /121.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Calculates all possible take scenarios as a bitmask where 1 represents taking 3 | a blue disc and 0 taking a red disc. 4 | 5 | Then, calculating the exact probability of taking, e.g.: 6 | 7 | 1011 8 | 9 | 1/2 * 2/3 * 1/4 * 1/5 10 | 11 | Then only counts it as a valid probability if the bitcount (i.e. the quantity 12 | of blue discs taken) is greater than the half of total turns. 13 | */ 14 | import System 15 | import System.Linq.Enumerable 16 | 17 | def chance(k as int, n as int): 18 | res = 1.0; 19 | bitc = 0 20 | for i in range(n): 21 | if k & 1: 22 | res *= 1.0/(2+i) 23 | bitc += 1 24 | else: 25 | res *= (1.0+i)/(2+i) 26 | k >>= 1 27 | 28 | return (res if bitc > n/2 else 0); 29 | 30 | 31 | res = 0.0 32 | for i in range(2**15): 33 | res += chance(i, 15) 34 | 35 | answer = cast(int, 1/res) 36 | print answer 37 | assert answer == 2269 38 | -------------------------------------------------------------------------------- /049.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Test each number and it's 3330-based successors if they-re permutation and 3 | prime. If all, hooray, we have an answer. Brute force, I mean. 4 | */ 5 | 6 | import System 7 | import System.Linq.Enumerable 8 | import System.Collections.Generic 9 | 10 | primes = PrimeNumbers() 11 | 12 | def same_digits(a as int, b as int): 13 | digits = array(int, 10) 14 | while(a>0): digits[a%10]++; a/=10 15 | while(b>0): digits[b%10]--; b/=10 16 | return digits.All({x|x==0}) 17 | 18 | def are_permutation(a as int, b as int, c as int): 19 | if not primes.IsPrime(a) or not primes.IsPrime(b) or not primes.IsPrime(c): return false 20 | return same_digits(a,b) and same_digits(b,c) 21 | 22 | for a in range(1000, 10000-2*3330): 23 | if a==1487: continue 24 | b = a + 3330 25 | c = b + 3330 26 | if are_permutation(a, b, c): 27 | answer = ''+a+b+c 28 | break 29 | print answer 30 | assert answer == '296962999629' -------------------------------------------------------------------------------- /159.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Precalculates all Digital Root Sum (D) up to 1.000.000 3 | 4 | Then backtracks all possible increasing factor sequence, checking if its drs 5 | is maximum. Prune the ones that aren't -- they are unable to increase further 6 | values. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | def sum_of_digits(n as int): 12 | s = 0 13 | while n: 14 | s+=n%10 15 | n/=10 16 | return s 17 | 18 | 19 | D = array(int, 10**6) 20 | for i in range(10**6): 21 | if i < 10: 22 | D[i] = i 23 | else: 24 | D[i] = D[sum_of_digits(i)] 25 | 26 | T = D.ToArray() 27 | def backtrack(a as int, n as long, f as int): 28 | if a < T[n] and n != 1: return 29 | 30 | T[n] = a 31 | for i in range(f, 500001): 32 | if n*i >= 1000000: break 33 | backtrack(a+D[i], n*i, i) 34 | 35 | backtrack(0, 1, 2) 36 | 37 | answer = T.Skip(2).Sum() 38 | print answer 39 | assert answer == 14489159 -------------------------------------------------------------------------------- /134.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Given a and b, the problem asks you to solve: 3 | 4 | x*b === a mod m #N is the 10 ^ "number of digits in a" 5 | 6 | e.g., for a,b = (19,23) 7 | 8 | 23x % 100 = 19, find the least positive x 9 | 10 | This equation can be written as: 11 | 12 | 23x - 100y = 19, that can be solved as a diophantine equation, using extended 13 | Euclid algorithm. 14 | */ 15 | import System 16 | import System.Linq.Enumerable 17 | 18 | P = PrimeNumbers(1000010).Cache.ToArray() 19 | 20 | def gcd(a as long, b as long) as (long): 21 | if b==0: return (1L, 0L) 22 | q = a/b 23 | x,y = gcd(b, a-q*b) 24 | return (y, x-q*y) 25 | 26 | def solution(a as long, b as long): 27 | m = 10**cast(int, Math.Log(a)/Math.Log(10)+1) 28 | x,y = gcd(b, m) 29 | return ((((x*a)%m)+m)%m)*b 30 | 31 | answer = 0L 32 | for i in range(2, P.Length-1): 33 | a, b = P[i], P[i+1] 34 | answer += solution(a,b) 35 | 36 | print answer 37 | assert answer == 18613426663617118L 38 | -------------------------------------------------------------------------------- /125.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Defines is_palindrome predicate. 3 | 4 | Then precalculates S[i] as "the sum of all squares from 0 to i" 5 | 6 | Then, for each pair i,j with i+2 <= j, verify if S[j] - S[i] "the sum of all 7 | squares between i+1 and j" is a palindrome. 8 | 9 | Remeber all values already summed in T[v] 10 | */ 11 | import System 12 | import System.Linq.Enumerable 13 | 14 | def is_palindrome(n as int): 15 | a, d = 0, n 16 | while n: 17 | a = a*10 + n%10 18 | n/=10 19 | return a == d 20 | 21 | S = array(long, 10**4) 22 | for i in range(1, 10**4): 23 | S[i] = S[i-1] + i*i 24 | 25 | total = 0L 26 | T = array(bool, 10**8) 27 | for i in range(10**4-2): 28 | for j in range(i+2, 10**4): 29 | v = S[j] - S[i] 30 | if v >=10**8: break 31 | if not T[v] and is_palindrome(v): 32 | T[v] = true 33 | total+=v 34 | 35 | answer = total.ToString() 36 | print answer 37 | assert answer == '2906969179' #long literal bug =/ -------------------------------------------------------------------------------- /164.boo: -------------------------------------------------------------------------------- 1 | /* 2 | We define the recurrence T(n,a,b) as "how many n-digit numbers ending in ab 3 | satisfy the required property". Given we know the answer for any T(n-1,i,a) 4 | (the recurrence assumption), the answer is the sum of every valid value of i 5 | (i.e, i+a+b <= 9) for n-1 digits. Simplified: 6 | 7 | T(0,0,0) = 1 8 | T(1,0,0) = 0 //to ensure no number has leading 0 9 | T(n,a,b) = sum(0<=i<=9, T(n-1,i,a)) 10 | */ 11 | import System 12 | import System.Linq.Enumerable 13 | 14 | T = matrix(long, 21, 10, 10) 15 | 16 | T[0,0,0] = 1 17 | for n in range(1, 21): 18 | for a in range(10): 19 | for b in range(10): 20 | if n==1 and b==0: continue 21 | for i in range(10): 22 | if i+a+b <= 9: 23 | T[n,a,b] = T[n,a,b] + T[n-1, i, a] 24 | 25 | answer = 0L 26 | for a in range(10): 27 | for b in range(10): 28 | answer += T[20, a, b] 29 | 30 | print answer 31 | assert answer == 378158756814587 32 | -------------------------------------------------------------------------------- /079.boo: -------------------------------------------------------------------------------- 1 | /* 2 | We try to generate the shortest password by checking, for every char, if it 3 | already matches the current password. A greed algorithm. If not, we put it where 4 | it belongs: before or after or inside the current one. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | A = (129,160,162,162,168,180,289,290,316,316,318,318,319,319,319,319,362,368,380,389,620,629,680,680,680,689,689,690,710,710,710,716,716,718,719,720,728,729,729,729,729,729,731,736,760,762,762,769,790,890) 10 | 11 | s = A[0].ToString(); 12 | 13 | for i in range(1, A.Length): 14 | s2 = A[i].ToString(); 15 | if s[0]==s2[2]: 16 | s = s2 + s[1:] 17 | elif s[s.Length-1]==s2[0]: 18 | s += s2[:2] 19 | elif s[:2]==s2[1:]: 20 | s = s2[0] + s 21 | elif s[s.Length-2:]==s2[:2]: 22 | s += s2[2] 23 | else: 24 | s = s.Replace(s2[0]+""+s2[2], s2) 25 | 26 | answer = int.Parse(s) 27 | 28 | print answer 29 | assert answer == 73162890 -------------------------------------------------------------------------------- /113.boo: -------------------------------------------------------------------------------- 1 | /* 2 | INC(x,y) means "how many numbers with x digits with last digit equals to y 3 | are increasing?". DEC(x,y) is the inverse. For each length x, there are 10 4 | numbers that are both increasing and decreasing. 5 | 6 | INC(x,y) = sum(INC(x-1, [x..9])) 7 | DEC(x,y) = sum(DEC(x-1, [0..x])) 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | INC = matrix(long, 100, 10) 13 | DEC = matrix(long, 100, 10) 14 | 15 | for i in range(10): 16 | INC[0, i] = 1 17 | DEC[0, i] = 1 18 | 19 | for i in range(1, 100): 20 | for j in range(10): 21 | for k in range(j, 10): INC[i,j] = INC[i,j] + INC[i-1,k] 22 | for k in range(j, 0): DEC[i,j] = DEC[i,j] + DEC[i-1,k] 23 | 24 | answer as decimal = 0 25 | for i in range(100): 26 | for j in range(10): 27 | answer += INC[i, j] + DEC[i, j] 28 | answer -= 10 #both increasing and decreasing in this length 29 | answer -=1 #the limit itself is non-bouncy 30 | 31 | print answer 32 | assert answer == 51161058134250 -------------------------------------------------------------------------------- /138.boo: -------------------------------------------------------------------------------- 1 | /* 2 | The equation: 3 | 4 | sqrt(a^2 - (b/2)^2) = b+-1 5 | 6 | Can be writen as: 7 | 8 | 4a^2 - 5b^2 - 8b - 4 = 0 9 | 10 | Which is a diophantine equation. I use http://www.alpertron.com.ar/QUAD.HTM to 11 | solve. It's solution is: 12 | 13 | X0 = -1, 0 Y1 = 1, 0 14 | 15 | Xn+1 = P Xn + Q Yn + K 16 | Yn+1 = R Xn + S Yn + L 17 | 18 | P = -9 19 | Q = -8 20 | K = -8, 8 21 | R = -10 22 | S = -9 23 | L = -8, 8 24 | 25 | Note: 26 | 27 | px, py - results for +1 28 | lx, ly - results for -1 29 | */ 30 | import System 31 | import System.Linq.Enumerable 32 | import System.Math 33 | 34 | px, py = BigInteger(0), BigInteger(1L) 35 | lx, ly = BigInteger(0), BigInteger(-1L) 36 | 37 | answer = 0L 38 | for i in range(12): 39 | px, py = -9*px -8*py -8, -10*px - 9*py -8 40 | if px > 0 and py > 0: 41 | answer += py 42 | 43 | lx, ly = -9*lx -8*ly +8, -10*lx - 9*ly +8 44 | if lx > 0 and ly > 0: 45 | answer += ly 46 | 47 | print answer 48 | assert answer == 1118049290473932L 49 | -------------------------------------------------------------------------------- /129.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Like 132: 3 | 4 | R(k) can be writen as: (10^k-1) / (10-1). 5 | 6 | Knowing if R(k) is divisible by some prime p is same as knowing if: 7 | 8 | (10^k-1)/9 mod p == 0 9 | or 10 | (10^k-1) mod (p*9) == 0 11 | or 12 | 10^k mod p*9 == 1 13 | 14 | We use then modular power, but incrementally, given we must test many values of 15 | k in range (1..p). We find the first k that respects the equality. 16 | 17 | We only need to test for values greater than 1.000.000, because R(n) < n. 18 | */ 19 | import System 20 | import System.Collections.Generic 21 | import System.Linq.Enumerable 22 | 23 | def first_divisible(p as int): 24 | n = 1 25 | m = p*9 26 | for k in range(1, p): 27 | n = (n*10)%m 28 | if n==1: 29 | return k 30 | 31 | return 0 32 | 33 | 34 | L = 1000000 35 | answer = 0 36 | for p in range(L, int.MaxValue): 37 | if first_divisible(p) > L: 38 | answer = p 39 | break 40 | 41 | 42 | print answer 43 | assert answer == 1000023 44 | -------------------------------------------------------------------------------- /205.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Precomputes the probability of throwing i dice and the result summing j as an 3 | array P[i,j]. Calculates for build(9,4) "9 dice of 4 sides" and build(6,6), 4 | analogous. 5 | 6 | Then, for each possible throw of Pete, multiplies by the sum of the probability 7 | of all lesser throws of Colin. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | def build(dices as int, max as int): 13 | P = matrix(decimal, dices+1, 2*max*dices) 14 | P[0,0] = cast(decimal, 1) 15 | p = cast(decimal, 1.0)/max 16 | for i in range(1, dices+1): 17 | for j in range(0, dices*max+1): 18 | for k in range(1, max+1): 19 | P[i,j+k] = P[i,j+k] + P[i-1,j] * p 20 | return P 21 | 22 | P = build(9, 4) 23 | C = build(6, 6) 24 | 25 | prob as decimal = 0 26 | 27 | for i in range(9, 37): 28 | d as decimal = 0 29 | for j in range(6, i): 30 | d += C[6, j] 31 | prob += P[9, i] * d 32 | answer = Math.Round(prob, 7) 33 | print answer 34 | assert answer == 0.5731441 -------------------------------------------------------------------------------- /018.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Dynamic programming. Runs from bottom to up, setting values of each line with 3 | the maximum each item can achieve. 4 | Then it's just to check the A[0][0] for the maximum. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | A = ( 10 | (75,), 11 | (95,64), 12 | (17,47,82), 13 | (18,35,87,10), 14 | (20,04,82,47,65), 15 | (19,01,23,75,03,34), 16 | (88,02,77,73,07,63,67), 17 | (99,65,04,28,06,16,70,92), 18 | (41,41,26,56,83,40,80,70,33), 19 | (41,48,72,33,47,32,37,16,94,29), 20 | (53,71,44,65,25,43,91,52,97,51,14), 21 | (70,11,33,28,77,73,17,78,39,68,17,57), 22 | (91,71,52,38,17,14,91,43,58,50,27,29,48), 23 | (63,66,04,68,89,53,67,30,73,16,69,87,40,31), 24 | (04,62,98,27,23,09,70,98,73,93,38,53,60,04,23) 25 | ) 26 | 27 | for i in range(13, -1): 28 | for j in range(i+1): 29 | A[i][j] = Math.Max(A[i][j]+A[i+1][j+1], A[i][j]+A[i+1][j]) 30 | 31 | answer = A[0][0] 32 | print answer 33 | assert answer == 1074 -------------------------------------------------------------------------------- /033.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Create all possible fractions in form XX/YY. Check for special property 3 | eliminating trivial cases. Saves the product into aa/bb. Then, reduces the 4 | fraction using GCD. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | def is_special(x as int, y as int): 10 | a, b = (x / 10, x % 10) 11 | c, d = (y / 10, y % 10) 12 | if (b == 0 and d == 0 or x==y): return false 13 | if a == c and d > 0: return cast(decimal, x)/y == cast(decimal, b)/d 14 | if a == d and c > 0: return cast(decimal, x)/y == cast(decimal, b)/c 15 | if b == c and d > 0: return cast(decimal, x)/y == cast(decimal, a)/d 16 | if b == d and c > 0: return cast(decimal, x)/y == cast(decimal, a)/c 17 | return false 18 | 19 | def gcd(a as int, b as int): 20 | while(b): a, b = (b, a%b) 21 | return a; 22 | 23 | aa = 1 24 | bb = 1 25 | for a in range(10, 100): 26 | for b in range(a, 100): 27 | if is_special(a, b): 28 | aa *= a 29 | bb *= b 30 | 31 | answer = bb / gcd(aa,bb) 32 | print answer 33 | assert answer == 100 -------------------------------------------------------------------------------- /207.boo: -------------------------------------------------------------------------------- 1 | /* 2 | We have that 4^t = 2^t + k. It is easy to see that 4^t = 2^2t and that 4^t is 3 | (2^t)^2. Since 2^t must be integer, if we replace 2^t with x, we have that: 4 | 5 | x^2 = x + k 6 | 7 | It means that we must find the distance (k) between a number (2^t) and its 8 | square (4^t). 9 | 10 | For this algorithm, we guess the value for 2^t meaning all integers. We know 11 | that t will be integer if and only if 2^t is an integer power of 2. So, the 12 | number of perfect partitions up to x is equal to floor(log2(x)) / (x-1). x-1 13 | because x=1 isn't valid. 14 | 15 | The, it's just a matter of trying all values of x until find one with P lesser 16 | than 1/12345. The value of k, then, is the distance between x and x^2, that is: 17 | x^2-x or x*(x-1). 18 | */ 19 | import System 20 | import System.Linq.Enumerable 21 | 22 | log2 = Math.Log(2) 23 | for x in range(2,2000000): 24 | a = Math.Floor(Math.Log(x) / log2) / (x-1) 25 | if a < 1/12345.0: 26 | answer = x*(x-1.0) 27 | break 28 | 29 | print answer 30 | assert answer == 44043947822 31 | -------------------------------------------------------------------------------- /040.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Navigates through the regions of the decimal (1 digit, 2 digits, 3 digits) 3 | 4 | find_in returns: 5 | n = the number you stopped in, not the digit, the number (e.g. 123) 6 | d = the position inside the number you stopped, counting from the right to left 7 | starting at 0 8 | f = the number of digits at the area you're at, starting at 0 9 | 10 | e.g. (456, 1, 2) means (456 / (10 ** (2 - 1)) % 10) = 5 11 | */ 12 | import System 13 | import System.Linq.Enumerable 14 | 15 | P10 = (1, 10, 100, 1000, 10000, 100000) 16 | S = (1, 10 * 2, 100 * 3, 1000 * 4, 10000 * 5, 100000 * 6) 17 | L = (9, 90 * 2, 900 * 3, 9000 * 4, 90000 * 5, 900000 * 6) 18 | 19 | def find_in(n as int): 20 | for i in range(0, L.Length): 21 | if (n-L[i]<0): return ((n+S[i])/(i+1), (n+S[i])%(i+1), i) 22 | n -= L[i] 23 | 24 | def D(n as int): 25 | n, d, f = find_in(n-1) 26 | return r = (n/P10[f-d])%10 27 | 28 | answer = D(10**0) * D(10**1) * D(10**2) * D(10**3) * D(10**4) * D(10**5) * D(10**6) 29 | 30 | print answer 31 | assert answer == 210 -------------------------------------------------------------------------------- /043.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generate permutations through backtracking, pruning invalid values (valid_for) 3 | during the process. So, the numbers that get to be created by make_number are 4 | always used to sum it up. 5 | */ 6 | import System 7 | import System.Linq.Enumerable 8 | 9 | primes = (1, 2, 3, 5, 7, 11, 13, 17) 10 | value = array(int, 10) 11 | used = array(bool, 10) 12 | 13 | def valid_for(d as int): 14 | return d<2 or (value[d-2] * 100 + value[d-1] * 10 + value[d]) % primes[d-2] == 0 15 | 16 | def make_number(): 17 | r as long = 0 18 | for i in range(10): 19 | r = r*10+value[i] 20 | return r 21 | 22 | def backtrack(d as int) as long: 23 | if d >= 10: 24 | return make_number() 25 | 26 | sum as long = 0 27 | for i in range(10): 28 | if not used[i]: 29 | value[d] = i 30 | used[i] = true 31 | if valid_for(d): 32 | sum += backtrack(d+1) 33 | used[i] = false 34 | return sum 35 | 36 | answer = backtrack(0) 37 | 38 | print answer 39 | assert answer == 16695334890 -------------------------------------------------------------------------------- /050.boo: -------------------------------------------------------------------------------- 1 | /* 2 | We use a list of primes (generated by sieve). We call it "cache". 3 | We cache the sum of primes upto index "i" in "cache". We call it T[i]. 4 | 5 | T[j]-T[i] means "the sum of all consecutive primes in the index interval (j,i]" 6 | And, for each pair (i,j) in T, we see if the results in a prime. 7 | 8 | Eg. 9 | i,j = (0, 6) 10 | E[6] - E[0] = 41, the sum of primes from indices 1 to 6 11 | 41 is prime, so 41 is a prime that is composed by the sum of 6 (j-1) primes 12 | */ 13 | import System 14 | import System.Linq.Enumerable 15 | import System.Collections.Generic 16 | 17 | primes = PrimeNumbers(10**6) 18 | cache = primes.Cache.ToArray() 19 | T = array(long, cache.Length+1) 20 | T[0] = 0 21 | 22 | for i in range(1,cache.Length+1): 23 | T[i] = T[i-1] + cache[i-1] 24 | 25 | max = 0 26 | for i in range(T.Length): 27 | if i+max >= T.Length: continue 28 | for j in range(i+max, T.Length): 29 | k = T[j] - T[i] 30 | if k>=10**6: break 31 | if primes.IsPrime(k) and j-i > max: 32 | max = j-i 33 | answer = k 34 | 35 | print answer 36 | assert answer == 997651 -------------------------------------------------------------------------------- /078.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Partition problem again. But the original solution is O(n^2) and n can get big 3 | in this problem. 4 | 5 | Now, instead of using the classic recurrence, we're gonna use integer partition 6 | with pentagonal numbers. It uses the reciprocal of Euler's function, and defines 7 | that: 8 | 9 | p(k) = p(k - 1) + p(k - 2) - p(k - 5) - p(k - 7) + p(k - 12) ... 10 | 11 | These values subtracted from k are the generalized pentagonal numbers, that are 12 | define by generating pentagonal numbers for n = 1, -1, 2, -2, ... We precompute 13 | these numbers at P. 14 | */ 15 | import System 16 | import System.Linq.Enumerable 17 | 18 | P = array(int, 1000) 19 | for i in range(1, P.Length / 2): 20 | P[2*i-2] = i*(3*i-1)/2 21 | P[2*i-1] = -i*(-3*i-1)/2 22 | 23 | T = array(int, 10**5) 24 | 25 | T[0] = 1 26 | answer = 0 27 | for answer in range(1, T.Length): 28 | s, j = 0, 0 29 | 30 | while P[j] <= answer: 31 | s = (s + (1 if j%4<2 else -1) * T[answer-P[j]]) % 10**6 32 | j++ 33 | 34 | if s==0: break 35 | T[answer] = s 36 | 37 | print answer 38 | assert answer == 55374 -------------------------------------------------------------------------------- /070.boo: -------------------------------------------------------------------------------- 1 | /* 2 | The minimum ratio n/phi(n) is achieved by having the greatest possible primes. 3 | Ths trivial case would be n being a prime number. But, phi(p) = p-1, and p-1 4 | would never be a permutation of p. So, the second case is n being a product 5 | of two primes p and q. So, it's phi will be (p-1)(q-1). 6 | 7 | Try, for every pair of primes, every product that leads to a permutated phi and 8 | checks for the minimum ratio. 9 | */ 10 | import System 11 | import System.Linq.Enumerable 12 | 13 | primes = PrimeNumbers() 14 | 15 | def same_digits(a as long, b as long): 16 | digits = array(int, 10) 17 | while(a>0): digits[a%10]++; a/=10 18 | while(b>0): digits[b%10]--; b/=10 19 | return digits.All({x|x==0}) 20 | 21 | min as double = int.MaxValue 22 | 23 | for p in primes.Until(4000): 24 | for q in primes.Until(4000): 25 | r = p*q 26 | if (r >= 10**7): break 27 | phi = (p-1)*(q-1) 28 | if same_digits(r, phi): 29 | d = r/cast(double, phi) 30 | if d < min: 31 | min = d 32 | answer = r 33 | print answer 34 | assert answer == 8319823 -------------------------------------------------------------------------------- /243.boo: -------------------------------------------------------------------------------- 1 | /* 2 | First, we find the least highly composite number that is less than the required 3 | fraction. It is something like 4 | 2 x 3 x 5 x 7 x 11 ... 5 | 6 | If we add the next prime, it would be a valid number, but not necessarily the 7 | minimum. Then we try every possible factor (not only primes) up to the next 8 | prime to find the minimum composite number that satisfies the condition. 9 | */ 10 | import System 11 | import System.Linq.Enumerable 12 | 13 | primes = PrimeNumbers() 14 | P = primes.Take(50).ToArray() 15 | L = 15499/94744.0 16 | d, next = 1L, 1L 17 | 18 | def phi(n as long) as long: 19 | factors = primes.Factorize(n).GroupBy({x|(x)}) 20 | res = 1 21 | for f in factors.Select({x|x.Key**x.Count()*(1-1.0/x.Key)}): 22 | res *= f 23 | return res 24 | 25 | def resilience(n as long) as double: 26 | return phi(n)/(n-1.0) 27 | 28 | for p in P: 29 | next = p 30 | if resilience(d*p) < L: 31 | break 32 | d *= p 33 | 34 | for i in range(2,next+1): 35 | if resilience(d*i) < L: 36 | answer = d*i 37 | break 38 | 39 | print answer 40 | assert answer == 892371480 41 | -------------------------------------------------------------------------------- /041.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generate all indexed permutions of size 7 using factoradic. You may try with 3 | 9 and 8 first, but will see it'll produce no primes. 4 | 5 | Generate them from the end to start, to ensure get the greatest value. 6 | 7 | Returns the first that is prime. 8 | */ 9 | import System 10 | import System.Linq.Enumerable 11 | 12 | def kth_permutation(n as int, k as int): 13 | data = array(int, n) 14 | for j in range(1, n+1): 15 | data[n-j] = (k % j + 1) 16 | k /= j 17 | 18 | data[n-1] = 1 19 | for i in range(n-2, -1): 20 | for j in range(i+1, n): 21 | if data[j] >= data[i]: data[j] += 1 22 | num = 0 23 | for i in range(0, data.Length): 24 | num = num*10+ data[i] 25 | return num 26 | 27 | primes = PrimeNumbers() 28 | def answer_with_n_digits(n as int): 29 | #362880 is the best value, because mods with up-to-9 well 30 | permutations = range(362880-1, -1).Select({x as int|kth_permutation(n,x)}) 31 | return permutations.Where(primes.IsPrime).First() 32 | 33 | answer = answer_with_n_digits(7) #try with 9 and 8... nothing 34 | print answer 35 | assert answer == 7652413 -------------------------------------------------------------------------------- /088.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Backtrack through all possible distinct multiplications of numbers greater 3 | than 1. Also accumulates their sums. So, if we have a multiplication: 2x2x3, 4 | for example, we know we need (2x2x3)-(2+2+3) "1"s to complete the sum. 5 | 6 | 1x1x1x1x1x2x2x3 = 1+1+1+1+1+2+2+3 7 | 8 | Just try to get the minimum product (pa) for each number of digits (na). 9 | */ 10 | import System 11 | import System.Linq.Enumerable 12 | 13 | R = array(int, 12001) 14 | for i in range(R.Length): 15 | R[i] = 1000000 16 | V = array(bool, 24001) 17 | 18 | def backtrack(last as int, sum as int, prod as int, digits as int): 19 | if digits > 32: 20 | return 21 | for i in range(last, 12000): 22 | sa = sum+i 23 | pa = prod*i 24 | if pa > 24000: 25 | return 26 | 27 | na = pa-sa+digits 28 | if na < R.Length: 29 | R[na] = Math.Min(R[na], pa) 30 | backtrack(i, sa, pa, digits+1) 31 | 32 | backtrack(2, 0, 1, 1) 33 | 34 | answer=0 35 | for i in range(2,12001): 36 | if not V[R[i]]: 37 | answer+=R[i] 38 | V[R[i]]=true 39 | 40 | print answer 41 | assert answer == 7587457 42 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Utils/FhtMultiplicationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace BooRunner.Tools 5 | { 6 | /// 7 | /// Used when FHT multiplication result is incorrect. 8 | /// 9 | [Serializable] 10 | public class FhtMultiplicationException : ApplicationException, ISerializable 11 | { 12 | /// 13 | /// Initializes a new instance of the class with a specified error message. 14 | /// 15 | /// A message that describes the error. 16 | public FhtMultiplicationException(string message) : base(message) {} 17 | 18 | /// 19 | /// Initializes a new instance of the class with serialized data. 20 | /// 21 | /// The object that holds the serialized object data. 22 | /// The contextual information about the source or destination. 23 | protected FhtMultiplicationException(SerializationInfo info, StreamingContext context) 24 | : base(info, context) {} 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /075.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generate all pythagorean triangles by using Euclid's formula. 3 | I.e.: pick any n, m, n>m, coprime (gcd==1) and with one of them even. 4 | a = n*n-m*m 5 | b = 2*m*n 6 | c = n*n+m*m 7 | 8 | e.g. nm(1,2) => abc(3,4,5) 9 | 10 | Generate all the derived triangles by multipling it by constant k, until it 11 | overflows the target. 12 | 13 | e.g. (3,4,5) => (6, 8, 10), (9, 12, 15) and so on... 14 | */ 15 | import System 16 | import System.Linq.Enumerable 17 | 18 | L = 1.5*10**6+1 19 | SL = cast(int, Math.Sqrt(L)) 20 | T = array(int, L) 21 | 22 | def gcd(a as int, b as int): 23 | while(b): a, b = (b, a%b) 24 | return a; 25 | 26 | answer = 0 27 | for m in range(1, SL): 28 | for n in range(m+1, SL): 29 | if (n+m)%2 != 1 or gcd(m,n) != 1: continue 30 | a,b,c = (n*n-m*m, 2*m*n, n*n+m*m) 31 | if a+b+c >= L: break 32 | 33 | ka,kb,kc = 0,0,0 34 | for k in range(1,L): 35 | ka, kb, kc = (ka+a,kb+b,kc+c) 36 | if ka+kb+kc >= L: break 37 | d = ++T[ka+kb+kc] 38 | if d==1: answer+=1 39 | elif d==2: answer-=1 40 | 41 | 42 | print answer 43 | assert answer == 161667 -------------------------------------------------------------------------------- /111.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Clever backtrack. Try, for each digit backwards fixing number of required 3 | repetitions (tr). 4 | 5 | Then backtrack in a way that you only generate numbers with the correct 6 | ammout of repeated digits. 7 | */ 8 | import System 9 | import System.Collections.Generic 10 | import System.Linq.Enumerable 11 | 12 | primes = PrimeNumbers(100000) 13 | 14 | def backtrack(a as long, d as int, kn as int, kr as int, tn as int, tr as int) as long: 15 | if tn-kn-(tr-kr) == 0: 16 | while tr-kr: 17 | a = a*10+d 18 | kr+=1 19 | return (a if primes.IsPrime(a) else 0) 20 | 21 | res = 0L 22 | sa = a 23 | bound = (tr-kr+1 if kn>0 or d!=0 else 1) 24 | for i in range(bound): 25 | for j in range(10): 26 | if j==d: continue 27 | if sa==0 and j==0: continue 28 | res += backtrack(sa*10+j, d, kn+i+1, kr+i, tn, tr) 29 | sa = sa*10+d 30 | return res 31 | 32 | answer = 0L 33 | for i in range(10): 34 | for j in range(9, 0): 35 | b = backtrack(0, i, 0, 0, 10, j) 36 | if b: 37 | answer += b 38 | break 39 | 40 | print answer 41 | assert answer == 612407567715 42 | -------------------------------------------------------------------------------- /122.boo: -------------------------------------------------------------------------------- 1 | /* 2 | This problem is known as shortest addition chain. And is NP-complete. 3 | 4 | First, I guessed all the numbers up to 200 could be represented in less than 5 | 15 multiplications. Then I made a backtrack to try combinations in a special 6 | way. Every add must be done with a value already on the buffer, and it should 7 | always be at least equal in length with the best already found. E.g. 8 | 9 | 1 2 4 5 10 | 11 | If the buffer is like the above, the only options for the 5th number are: 12 | 13 | 6 = 5+1 14 | 7 = 5+2 15 | 9 = 5+4 16 | 10 = 5+5 17 | 18 | This way, every step adds only 1 multiplication to result, as all the factors 19 | are already calculated before. 20 | */ 21 | import System 22 | import System.Linq.Enumerable 23 | 24 | T = array(int, 201) 25 | V = array(int, 15) 26 | 27 | def backtrack(k as int): 28 | if k>=15: return 29 | for i in range(k): 30 | V[k] = V[k-1]+V[i] 31 | if V[k] <= 200 and k<=T[V[k]]: 32 | T[V[k]] = k 33 | backtrack(k+1) 34 | 35 | 36 | for i in range(2,201): 37 | T[i] = 1000 38 | 39 | V[0] = 1 40 | backtrack(1) 41 | 42 | answer = T.Take(201).Sum() 43 | print answer 44 | assert answer == 1582 -------------------------------------------------------------------------------- /tools/src/BooRunner/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Diagnostics; 6 | using System.IO; 7 | using System.Threading; 8 | using System.Reflection; 9 | using Boo.Lang.Compiler; 10 | 11 | namespace BooEulerTool 12 | { 13 | class Program 14 | { 15 | static int Main(string[] args) 16 | { 17 | var options = new Options(args); 18 | 19 | if (!options.Files.Any()) 20 | { 21 | Console.Error.WriteLine("no input files found"); 22 | return 2; 23 | } 24 | 25 | var exit = Run(options); 26 | //Console.ReadLine(); 27 | return exit; 28 | } 29 | 30 | 31 | 32 | private static int Run(Options option) 33 | { 34 | if ((option.Files.Length == 1 || option.ForceOne) && !option.ForceMany) 35 | return option.Files.Select(x => OneRunner.Run(x, option.Timeout ?? Timeout.Infinite)).Max(); 36 | else 37 | return ManyRunner.Run(option.Files, option.Timeout ?? 5000, option.Sort); 38 | } 39 | 40 | 41 | 42 | 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /090.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force with bracktrack. Only gotcha is that we replace every 9 with a 6, 3 | to make things easier to compare. 4 | 5 | Also reuses check array (the one that is 0..99), using an integer that 6 | represents the case number, instead of a boolean. 7 | */ 8 | import System 9 | import System.Collections.Generic 10 | import System.Linq.Enumerable 11 | 12 | V1 = array(int, 6) 13 | V2 = array(int, 6) 14 | T = array(int, 100) 15 | 16 | answer = 0 17 | case = 0 18 | 19 | def bt2(k as int, v as int) as void: 20 | if k==6: 21 | for a in V1: 22 | for b in V2: 23 | if a>=0 and b>=0: 24 | T[a*10+b]=case+1 25 | T[b*10+a]=case+1 26 | 27 | if (01, 04, 06, 16, 25, 36, 46, 64, 81).All({x|T[x]>case}): 28 | answer+=1 29 | case+=1 30 | return 31 | 32 | for i in range(v, 10, 1): 33 | V2[k]=i 34 | if i==9: V2[k]=6 35 | bt2(k+1, i+1) 36 | 37 | 38 | def bt1(k as int, v as int): 39 | if k==6: 40 | bt2(0,0) 41 | return 42 | 43 | for i in range(v, 10, 1): 44 | V1[k]=i 45 | if i==9: V1[k]=6 46 | bt1(k+1, i+1) 47 | 48 | 49 | bt1(0,0) 50 | answer /= 2 51 | print answer 52 | assert answer == 1217 53 | -------------------------------------------------------------------------------- /039.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generate all pythagorean triangles by using Euclid's formula. 3 | I.e.: pick any n, m, n>m, coprime (gcd==1) and with one of them even. 4 | a = n*n-m*m 5 | b = 2*m*n 6 | c = n*n+m*m 7 | 8 | e.g. nm(1,2) => abc(3,4,5) 9 | 10 | Generate all the derived triangles by multipling it by constant k, until it 11 | overflows the target. 12 | 13 | e.g. (3,4,5) => (6, 8, 10), (9, 12, 15) and so on... 14 | */ 15 | import System 16 | import System.Linq.Enumerable 17 | 18 | L = 1001 19 | SL = cast(int, Math.Sqrt(L)) 20 | T = array(int, L) 21 | 22 | def gcd(a as int, b as int): 23 | while(b): a, b = (b, a%b) 24 | return a; 25 | 26 | answer = 0 27 | for m in range(1, SL): 28 | for n in range(m+1, SL): 29 | if (n+m)%2 != 1 or gcd(m,n) != 1: continue 30 | a,b,c = (n*n-m*m, 2*m*n, n*n+m*m) 31 | if a+b+c >= L: break 32 | 33 | ka,kb,kc = 0,0,0 34 | for k in range(1,L): 35 | ka, kb, kc = (ka+a,kb+b,kc+c) 36 | if ka+kb+kc >= L: break 37 | d = ++T[ka+kb+kc] 38 | if d==1: answer+=1 39 | elif d==2: answer-=1 40 | 41 | max = 0 42 | for i in range(1, 1001): 43 | if (T[i] > max): 44 | max = T[i] 45 | answer = i 46 | 47 | print answer 48 | assert answer == 840 -------------------------------------------------------------------------------- /tools/src/BooEulerTools.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BooRunner", "BooRunner\BooRunner.csproj", "{8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Debug|x86 = Debug|x86 10 | Release|Any CPU = Release|Any CPU 11 | Release|x86 = Release|x86 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}.Debug|x86.ActiveCfg = Debug|x86 17 | {8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}.Debug|x86.Build.0 = Debug|x86 18 | {8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}.Release|x86.ActiveCfg = Release|x86 21 | {8BAC2A26-1794-440A-BDE7-69F0C8DC2CF1}.Release|x86.Build.0 = Release|x86 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/StringConverters/IStringConverter.cs: -------------------------------------------------------------------------------- 1 | namespace BooRunner.Tools 2 | { 3 | /// 4 | /// ToString converter class interface. 5 | /// 6 | internal interface IStringConverter 7 | { 8 | /// 9 | /// Returns string representation of object in given base. 10 | /// 11 | /// Big integer to convert. 12 | /// Base of system in which to do output. 13 | /// Alphabet which contains chars used to represent big integer, char position is coresponding digit value. 14 | /// Object string representation. 15 | string ToString(BigInteger intX, uint numberBase, char[] alphabet); 16 | 17 | /// 18 | /// Converts digits from internal representaion into given base. 19 | /// 20 | /// Big integer digits. 21 | /// Big integer length. 22 | /// Base to use for output. 23 | /// Calculated output length (will be corrected inside). 24 | /// Conversion result (later will be transformed to string). 25 | uint[] ToString(uint[] digits, uint length, uint numberBase, ref uint outputLength); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /206.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Semi brute force. 3 | 4 | Fact: Since the square ends in 0, it is divisible by 10. So, the base must also. 5 | We can assume then that the answer ends in "0". So, the square itself will be 6 | divisible by 100, ie, will end in "00" 7 | 8 | In this algorithm, we try to generate possible square roots for the target 9 | number. We try all numbers in form 1a2b3c4xxxxxxxxxx00 where x sequence can be 10 | any number. We map the first and the last square roots that results in each 11 | pattern and iterate through the values. The yield n*10 is because of the fact 12 | above. 13 | */ 14 | import System 15 | import System.Linq.Enumerable 16 | 17 | expected = (1,2,3,4,5,6,7,8,9,0) 18 | 19 | def is_answer(n as long): 20 | i = 10 21 | n = n*n 22 | while n: 23 | if n%10 != expected[i-1]: return false 24 | n/=100 25 | i-- 26 | return i==0 27 | 28 | def candidates(): 29 | for a in range(0,10): 30 | for b in range(0,10): 31 | for c in range(0,10): 32 | base = (1020304+a*10**5+b*10**3+c*10**1) * 10**10L 33 | start = Math.Sqrt(base) cast long 34 | end = Math.Sqrt(base+10**10) cast long 35 | for n as long in range(start,end): 36 | yield n*10 37 | 38 | answer = candidates().First(is_answer) 39 | print answer 40 | assert answer == 1389019170 -------------------------------------------------------------------------------- /058.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generates all diagonal values and check for their primality. 3 | 4 | The gotcha here is that the primes can get big (and they're many), so the 5 | primality check through the sieve is not efficient enough. So, we're using the 6 | Miller-Rabin primality test to check if the diagonal number is prime. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | def pow(a as int, n as int, mod as int): 12 | r, p = (1L, cast(long, a)) 13 | while(n): 14 | if n%2: r=(r*p)%mod 15 | p=(p*p)%mod 16 | n/=2 17 | 18 | return r 19 | 20 | 21 | def witness(a as int, n as int): 22 | u,t= (n/2, 1) 23 | while(u%2==0): u,t = (u/2, t+1) 24 | 25 | prev = pow(a,u,n); 26 | 27 | for i in range(t): 28 | curr=(prev*prev)%n 29 | if curr==1 and prev!=1 and prev!=n-1: return true 30 | prev=curr 31 | 32 | return curr != 1 33 | 34 | 35 | def is_prime(n as int): 36 | if n in (2, 7, 61): return true 37 | if witness(2,n): return false 38 | if witness(7,n): return false 39 | if witness(61,n): return false 40 | return true 41 | 42 | n, p = (1, 0) 43 | for side in range(3, 100000, 2): 44 | for i in range(4): 45 | n += side-1 46 | if (is_prime(n)): p+=1 47 | if p/(2*side-1.0) < 0.1: 48 | answer = side 49 | break 50 | 51 | print answer 52 | assert answer == 26241 -------------------------------------------------------------------------------- /104.boo: -------------------------------------------------------------------------------- 1 | /* 2 | We use the principle that (a+b)%n == (a%n+b%n)%n. 3 | 4 | So, instead of calculating the entire fibonacci number, we just calculate it's last 9 digits, but 5 | modding all around (to fit in an integer and keep complexity of adding low). Then, for each last 9 6 | digits that are pandigital, we calculate the top 9 digits. We do it by using some log tricks. 7 | 8 | OEIS (http://oeis.org/A000045) sais Fibonacci sequence can be written as: 9 | 10 | round(phi^n/sqrt(5)) 11 | 12 | Applying log10 to all of it, we have: 13 | 14 | n*log(phi)-log(sqrt(5) 15 | 16 | Now, it's just a matter of getting the fractional part of the number and ensure it'll be almost 9. 17 | 18 | Then check if it's top9 digits are pandigital. 19 | */ 20 | import System 21 | import System.Linq.Enumerable 22 | 23 | phi = (1.0 + Math.Sqrt(5.0))/2.0 24 | logPhi = Math.Log10(phi) 25 | logSqrt = Math.Log10(Math.Sqrt(5.0)) 26 | 27 | def top9(i as int) as int: 28 | k = i*logPhi-logSqrt 29 | return 10**(k - cast(int, k) + 8) 30 | 31 | def pandigital(i as int): 32 | T = array(int, 9) 33 | while i: 34 | T[(i%10)-1]++ 35 | i/=10 36 | return T.All({x|x==1}) 37 | 38 | a,b=1,0 39 | for i in range(1,1000000000): 40 | a,b=(a+b)%1000000000,a 41 | if pandigital(b) and pandigital(top9(i)): 42 | answer = i 43 | break 44 | 45 | print answer 46 | assert answer == 329468 -------------------------------------------------------------------------------- /092.boo: -------------------------------------------------------------------------------- 1 | /* 2 | It is easy to prove that every number less than ten million is reduced to less 3 | than 600 in the first iteration. What we do is to calculate where every number 4 | less than 600 will lead to (with all the iterations). 5 | 6 | Then, to know where each number up to ten million will lead (with only one 7 | iteration) we use a dynamic programming that stores in T[i, j], how many 8 | numbers with upto "i" digits will lead to "j" after its first iteration. 9 | It iterates in the number digits [1..7] and the possible number for each 10 | position [0..9], instead of the number itself. 11 | 12 | So, for each number "i" less than 600, we sum T[7, i] if lead_to[i] == 89. 13 | */ 14 | import System 15 | import System.Linq.Enumerable 16 | 17 | def ends_in(a as int) as int: 18 | if (a==0): return 1 19 | sum = 0 20 | while a not in (1, 89): 21 | sum = 0 22 | while(a): 23 | sum += (a%10)**2 24 | a/=10 25 | a = sum 26 | return a 27 | 28 | lead_to = range(600).Select(ends_in).ToArray() 29 | T = matrix(int, 8, 600) 30 | T[0, 0] = 1 31 | 32 | for i in range(1,8): 33 | for j in range(10): 34 | for k in range(600-j*j): 35 | T[i, k+j*j] = T[i, k+j*j] + T[i-1, k] 36 | 37 | 38 | answer = 0 39 | for i in range(600): 40 | if (lead_to[i] == 89): 41 | answer += T[7, i] 42 | print answer 43 | assert answer == 8581146 -------------------------------------------------------------------------------- /127.boo: -------------------------------------------------------------------------------- 1 | /* 2 | First, precalculate all the values for rad(n) using same method as problem 124. 3 | 4 | Iterates through all possible c values. For each c, iterates trough all 5 | possible a values sorted by rad(a). We do this so we can stop iteration ealy 6 | if rad(a)*rad(c) > c/2, because rad(b) will be at least 2. 7 | 8 | We check if gcd(a,c) == 1. If so, as a+b=c, we know also gcd(a,b) == 1 and 9 | gcd(b,c) == 1. This is because b=c-a, if no divisor of c can divide a, then it 10 | can't divide c-a, which is b. The same for a divisors. 11 | */ 12 | import System 13 | import System.Linq.Enumerable 14 | 15 | def gcd(a as int, b as int): 16 | while(b): 17 | tmp = b 18 | b = a%b 19 | a = tmp 20 | return a; 21 | 22 | L = 120000 23 | primes = PrimeNumbers(L) 24 | 25 | rad = array(long, L) 26 | for i in range(L): 27 | rad[i] = 1 28 | 29 | for i in primes.Until(L): 30 | for j in range(i, L, i): 31 | rad[j] *= i 32 | 33 | sorted_rad = range(1, L).OrderBy({x|rad[x]}).ToList() 34 | 35 | answer = 0 36 | for c in range(3, L): 37 | for a in sorted_rad: 38 | if a>c/2 or not gcd(a, c) == 1: continue 39 | if rad[a]*rad[c] > c/2: break 40 | b = c-a 41 | 42 | if an: C[n,k] = 0 36 | else: C[n,k] = C[n-1,k-1] + C[n-1,k] 37 | 38 | answer = 0L 39 | for i in range(3, 27): 40 | answer = Math.Max(answer, C[26,i]*E[i]) 41 | 42 | print answer 43 | assert answer == 409511334375 -------------------------------------------------------------------------------- /008.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force solution. Using generator. 3 | */ 4 | import System 5 | import System.Linq.Enumerable 6 | 7 | input = '7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450' 8 | 9 | to_int = {c as char|cast(int, c)-cast(int,char('0'))} 10 | product = {x as (int) | x[0] * x[1] * x[2]* x[3] * x[4]} #Aggregate failing :( 11 | 12 | def numbers(): 13 | for i in range(input.Length-5): 14 | yield input.Substring(i, 5).Select(to_int).ToArray(); 15 | 16 | answer = numbers().Select(product).Max() 17 | 18 | print answer 19 | assert answer == 40824 -------------------------------------------------------------------------------- /080.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generates each square root by using continued fractions method, but with one 3 | modification: the resulting numerator is multiplied by 10^99, in order to shift 4 | the 99 digits (of the resulting convergent) after the period to before it. 5 | Then, it's just a matter of doing the integer division and get the resulting 6 | value as an integer. 7 | 8 | Obviously, it uses BigInteger. 9 | */ 10 | import System 11 | import System.Linq.Enumerable 12 | 13 | def CF(n as int): 14 | n1,d1 =(0,1) 15 | sqrtn = Math.Sqrt(n) 16 | while true: 17 | if d1 == 0: break 18 | 19 | nextn = cast(int, (sqrtn + n1) / d1) 20 | yield nextn 21 | 22 | n2, d2 = (d1, n1 - d1 * nextn) 23 | n3, d3 = (-d2, (n - d2 ** 2) / n2) 24 | n1, d1 = (n3, d3) 25 | 26 | def special_root(n as int, p as int): 27 | b = CF(n).First() 28 | L = (BigInteger(1),BigInteger(0)) 29 | T = (BigInteger(b),BigInteger(1)) 30 | for i in CF(n).Skip(1).Take(p*2): 31 | L, T = (T, (i*T[0]+L[0], i*T[1]+L[1])) 32 | return T[0] * BigInteger(10).Pow(p) / T[1] 33 | 34 | def is_perfect(r as int, n as int): 35 | return r*r == n 36 | 37 | def sum_of(n as int): 38 | if is_perfect(Math.Sqrt(n), n): return 0 39 | root = special_root(n, 99) 40 | r = 0 41 | while(root > 0): 42 | r += cast(int, root % 10) 43 | root /= 10 44 | return r 45 | 46 | answer = range(1, 101).Sum(sum_of) 47 | 48 | print answer 49 | assert answer == 40886 50 | -------------------------------------------------------------------------------- /106.boo: -------------------------------------------------------------------------------- 1 | /* 2 | The trick is, given the set is ordered and the elements are unique (to respect 3 | second rule), if every element in set B has a corresponding greater element at 4 | C, we do not need to test, as we know its sum is strictly lesser than C. 5 | 6 | For example, given the hypotetical set 7 | A = (1, 2, 3, 4) (that do not respect second rule, but it's just an example). 8 | 9 | If B = (1, 2) and C = (3, 4), we know that S(B) != S(C) because every element 10 | of B has a corresponding greater at C (1<3 and 2<4). 11 | 12 | We represent here the sets as a bitmask from 1 to 2^size. The need_count 13 | calculates the "balance" in the bit appearances in each bitmask. If the 14 | greater number appears with one bit without any corresponding bit on the 15 | lesser, we say it need to be checked for equality. 16 | */ 17 | import System 18 | import System.Linq.Enumerable 19 | 20 | def need_count(a as int, b as int): 21 | if a&b: return false 22 | 23 | ca,cb,balance=0,0,0 24 | need=false 25 | 26 | while a or b: 27 | if a&1: 28 | ca+=1 29 | balance-=1 30 | if b&1: 31 | cb+=1 32 | balance+=1 33 | if balance>0: 34 | need=true 35 | a>>=1 36 | b>>=1 37 | 38 | return ca==cb and ca!=1 and need 39 | 40 | answer = 0 41 | for a in range(1,2**12): 42 | for b in range(a+1,2**12): 43 | if need_count(a,b): 44 | answer += 1 45 | 46 | 47 | print answer 48 | assert answer == 21384 49 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Parsers/IParser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Parser class interface. 7 | /// 8 | internal interface IParser 9 | { 10 | /// 11 | /// Parses provided string representation of object. 12 | /// 13 | /// Number as string. 14 | /// Number base. 15 | /// Char->digit dictionary. 16 | /// Check actual format of number (0 or 0x at start). 17 | /// Parsed object. 18 | BigInteger Parse(string value, uint numberBase, IDictionary charToDigits, bool checkFormat); 19 | 20 | /// 21 | /// Parses provided string representation of object. 22 | /// 23 | /// Number as string. 24 | /// Index inside string from which to start. 25 | /// Index inside string on which to end. 26 | /// Number base. 27 | /// Char->digit dictionary. 28 | /// Resulting digits. 29 | /// Parsed integer length. 30 | uint Parse(string value, int startIndex, int endIndex, uint numberBase, IDictionary charToDigits, uint[] digitsRes); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /066.boo: -------------------------------------------------------------------------------- 1 | /* 2 | The problem's equation is known as Pell's equation. 3 | 4 | The fundamental solution is to find the first hi/k1 continued fraction for 5 | sqrt(D) that, letting x = h1 and y = h1, satisfies the equation. That's 6 | guaranteed to be the very first solution. 7 | 8 | Uses classic algorithm to generate continued fractions (CF) and calculate 9 | the convergents. Then, check if the value satisfies the equation. 10 | */ 11 | import System 12 | import System.Linq.Enumerable 13 | 14 | def CF(n as int): 15 | n1,d1 =(0,1) 16 | sqrtn = Math.Sqrt(n) 17 | while true: 18 | if d1 == 0: break 19 | 20 | nextn = cast(int, (sqrtn + n1) / d1) 21 | yield nextn 22 | 23 | n2, d2 = (d1, n1 - d1 * nextn) 24 | n3, d3 = (-d2, (n - d2 ** 2) / n2) 25 | n1, d1 = (n3, d3) 26 | 27 | def convergents(n as int): 28 | b = CF(n).First() 29 | L = (BigInteger(1),BigInteger(0)) 30 | T = (BigInteger(b),BigInteger(1)) 31 | for i in CF(n).Skip(1): 32 | yield T 33 | L, T = (T, (i*T[0]+L[0], i*T[1]+L[1])) 34 | 35 | def is_perfect_square(D as int): 36 | return cast(int,cast(int, Math.Sqrt(D))**2) == D 37 | 38 | max = BigInteger(0) 39 | for D in range(1001): 40 | if is_perfect_square(D): continue 41 | for a,b in convergents(D).Take(100): 42 | if a*a-D*b*b == 1: 43 | if a > max: 44 | max = a 45 | answer = D 46 | break 47 | 48 | print answer 49 | assert answer == 661 50 | -------------------------------------------------------------------------------- /118.boo: -------------------------------------------------------------------------------- 1 | /* 2 | For every prime number with upto 8 digits, calculate: 3 | 4 | "m" the bitmask of the digit ocupation from 0 to 9 for this prime 5 | "c" the digit count of this prime 6 | 7 | Store it in a single integer, "c" in the last 4 bits and "m" shifted 4 bits to 8 | the left. 9 | 10 | Discard every prime that contains: (a) zeroes or (b) repeated digits. 11 | 12 | Then, for every selected prime, backtrack creating the selected number. Avoid 13 | digits repetition and overflow. Every answer that achieves the 9-digit number is 14 | a hooray! 15 | */ 16 | import System 17 | import System.Linq.Enumerable 18 | 19 | def mask_for(p as int) as int: 20 | c,v,m,r=0,0,0,0 21 | while p: 22 | q = p/10 23 | v = 1<<(p-q*10) 24 | if v==1 or v&m!=0: 25 | return 0 26 | m|=v 27 | c+=1 28 | p = q 29 | return (m<<4) | c 30 | 31 | primes = PrimeNumbers(100000000) 32 | mask, count = 0, 0 33 | masks = primes.Cache.Select(mask_for).Where({x|x!=0}).ToArray() 34 | 35 | answer = 0 36 | def backtrack(a as int) as void: 37 | if count==9: 38 | answer+=1 39 | return 40 | 41 | for i in range(a, masks.Length): 42 | h = masks[i] 43 | m,c = h>>4, h&0xF 44 | if count+c>9: break 45 | if m&mask!=0: continue 46 | 47 | mask|=m 48 | count+=c 49 | 50 | backtrack(i+1) 51 | 52 | mask&=~m 53 | count-=c 54 | 55 | backtrack(0) 56 | print answer 57 | assert answer == 44680 58 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Bits.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Contains helping methods to with with bits in dword (). 7 | /// 8 | 9 | static public class Bits 10 | { 11 | /// 12 | /// Returns number of leading zero bits in int. 13 | /// 14 | /// Int value. 15 | /// Number of leading zero bits. 16 | static public int Nlz(uint x) 17 | { 18 | if (x == 0) return 32; 19 | 20 | int n = 1; 21 | if ((x >> 16) == 0) { n += 16; x <<= 16; } 22 | if ((x >> 24) == 0) { n += 8; x <<= 8; } 23 | if ((x >> 28) == 0) { n += 4; x <<= 4; } 24 | if ((x >> 30) == 0) { n += 2; x <<= 2; } 25 | return n - (int)(x >> 31); 26 | } 27 | 28 | /// 29 | /// Counts position of the most significant bit in int. 30 | /// Can also be used as Floor(Log2()). 31 | /// 32 | /// Int value. 33 | /// Position of the most significant one bit (-1 if all zeroes). 34 | static public int Msb(uint x) 35 | { 36 | return 31 - Nlz(x); 37 | } 38 | 39 | /// 40 | /// Ceil(Log2()). 41 | /// 42 | /// Int value. 43 | /// Ceil of the Log2. 44 | static public int CeilLog2(uint x) 45 | { 46 | int msb = Msb(x); 47 | if (x != 1U << msb) 48 | { 49 | ++msb; 50 | } 51 | return msb; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Options.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace BooEulerTool 8 | { 9 | public class Options 10 | { 11 | public string[] Files { get; private set; } 12 | public int? Timeout { get; private set; } 13 | public bool ForceOne { get; private set; } 14 | public bool ForceMany { get; private set; } 15 | public bool Sort { get; private set; } 16 | 17 | public Options(string[] args) 18 | { 19 | var files = new List(); 20 | for (int i = 0; i < args.Length; i++) 21 | { 22 | switch (args[i]) 23 | { 24 | case "-t": 25 | if (++i < args.Length) 26 | Timeout = int.Parse(args[i]); 27 | break; 28 | case "-fo": ForceOne = true; break; 29 | case "-fm": ForceMany = true; break; 30 | case "-sort": Sort = true; break; 31 | default: 32 | files.Add(args[i]); 33 | break; 34 | } 35 | } 36 | Files = files.SelectMany(pattern => 37 | { 38 | var dir = Path.GetDirectoryName(pattern); 39 | if (string.IsNullOrEmpty(dir)) dir = "."; 40 | return Directory.GetFiles(dir, Path.GetFileName(pattern)); 41 | }).ToArray(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("BooEulerTool")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("BooEulerTool")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("d103fe62-f2af-49fc-8e2a-4fbe66f122a0")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /095.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Generate next numbers in amicable chain through a sieve-like algorithm. 3 | 4 | That is, for each pair of divisors a and b, sum a+b to a*b. Be careful with 5 | the squares. 6 | 7 | Then, find all the strongly connected components through the classic algorithm 8 | and get the greater of them and find the minimum value in it. 9 | */ 10 | import System 11 | import System.Collections.Generic 12 | import System.Linq.Enumerable 13 | 14 | T = array(int, 1000001) 15 | T2 = array(int, 1000001) 16 | 17 | for i in range(T.Length): 18 | T[i]+=1 19 | 20 | for a in range(2, 1001): 21 | T[a*a]+=a 22 | b=a+1 23 | while a*b < T.Length: 24 | T[a*b]+=a+b 25 | b+=1 26 | for i in range(T.Length): 27 | if T[i] < T.Length: 28 | T2[T[i]]=i 29 | 30 | V = array(int, T.Length) 31 | O = array(int, T.Length) 32 | C = array(int, T.Length) 33 | 34 | maxv, maxx, count = 0,0,0 35 | 36 | def dfs1(v as int) as void: 37 | V[v] = 1 38 | u = T[v] 39 | if u maxx: 59 | maxx = C[V[i]] 60 | maxv = i 61 | 62 | answer = maxv 63 | print answer 64 | assert answer == 14316 65 | -------------------------------------------------------------------------------- /tools/src/BooRunner/BooEulerCompiler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Boo.Lang.Compiler; 6 | using Boo.Lang.Compiler.Pipelines; 7 | using Boo.Lang.Compiler.IO; 8 | using System.IO; 9 | using System.Reflection; 10 | 11 | namespace BooEulerTool 12 | { 13 | public class BooEulerCompiler 14 | { 15 | BooCompiler booc = new BooCompiler(); 16 | public BooEulerCompiler() 17 | { 18 | booc.Parameters.Pipeline = new CompileToMemory(); 19 | } 20 | 21 | public Action Compile(string file) 22 | { 23 | var fileLines = File.ReadAllLines(file); 24 | if (!fileLines.Any(x => x.StartsWith("print "))) throw new ArgumentException("must specify at least one 'print' statement"); 25 | if (!fileLines.Any(x => x.StartsWith("assert "))) throw new ArgumentException("must specify at least one 'assert' statement"); 26 | 27 | booc.Parameters.Input.Clear(); 28 | booc.Parameters.Input.Add(new FileInput(file)); 29 | booc.Parameters.OutputType = CompilerOutputType.Library; 30 | booc.Parameters.References.Add(Assembly.GetExecutingAssembly()); 31 | 32 | var ctx = booc.Run(); 33 | if (ctx.Errors.Count > 0) 34 | throw ctx.Errors[0]; 35 | var assembly = ctx.GeneratedAssembly; 36 | var method = assembly.GetTypes().First(x => x.Name.EndsWith("Module")).GetMethod("Main", BindingFlags.NonPublic | BindingFlags.Static); 37 | 38 | return args => method.Invoke(null, new object[] { args }); 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/DigitConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BooEulerTool.Tools.IntX.Utils; 3 | 4 | namespace BooRunner.Tools 5 | { 6 | /// 7 | /// Converts digits to/from byte array. 8 | /// 9 | 10 | static public class DigitConverter 11 | { 12 | /// 13 | /// Converts big integer digits to bytes. 14 | /// 15 | /// digits. 16 | /// Resulting bytes. 17 | /// 18 | /// Digits can be obtained using method. 19 | /// 20 | static public byte[] ToBytes(uint[] digits) 21 | { 22 | if (digits == null) 23 | { 24 | throw new ArgumentNullException("digits"); 25 | } 26 | 27 | byte[] bytes = new byte[digits.Length * 4]; 28 | Buffer.BlockCopy(digits, 0, bytes, 0, bytes.Length); 29 | return bytes; 30 | } 31 | 32 | /// 33 | /// Converts bytes to big integer digits. 34 | /// 35 | /// Bytes. 36 | /// Resulting digits. 37 | /// 38 | /// Big integer can be created from digits using constructor. 39 | /// 40 | static public uint[] FromBytes(byte[] bytes) 41 | { 42 | if (bytes == null) 43 | { 44 | throw new ArgumentNullException("bytes"); 45 | } 46 | if (bytes.Length % 4 != 0) 47 | { 48 | throw new ArgumentException(Strings.DigitBytesLengthInvalid, "bytes"); 49 | } 50 | 51 | uint[] digits = new uint[bytes.Length / 4]; 52 | Buffer.BlockCopy(bytes, 0, digits, 0, bytes.Length); 53 | return digits; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Multipliers/IMultiplier.cs: -------------------------------------------------------------------------------- 1 | namespace BooRunner.Tools 2 | { 3 | /// 4 | /// Multiplier class interface. 5 | /// 6 | internal interface IMultiplier 7 | { 8 | /// 9 | /// Multiplies two big integers. 10 | /// 11 | /// First big integer. 12 | /// Second big integer. 13 | /// Resulting big integer. 14 | BigInteger Multiply(BigInteger int1, BigInteger int2); 15 | 16 | /// 17 | /// Multiplies two big integers represented by their digits. 18 | /// 19 | /// First big integer digits. 20 | /// First big integer real length. 21 | /// Second big integer digits. 22 | /// Second big integer real length. 23 | /// Where to put resulting big integer. 24 | /// Resulting big integer real length. 25 | uint Multiply(uint[] digits1, uint length1, uint[] digits2, uint length2, uint[] digitsRes); 26 | 27 | /// 28 | /// Multiplies two big integers using pointers. 29 | /// 30 | /// First big integer digits. 31 | /// First big integer length. 32 | /// Second big integer digits. 33 | /// Second big integer length. 34 | /// Resulting big integer digits. 35 | /// Resulting big integer length. 36 | unsafe uint Multiply(uint* digitsPtr1, uint length1, uint* digitsPtr2, uint length2, uint* digitsResPtr); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tools/src/BooRunner/OneRunner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Diagnostics; 6 | using System.Reflection; 7 | using Boo.Lang.Compiler; 8 | using System.IO; 9 | 10 | namespace BooEulerTool 11 | { 12 | public class OneRunner 13 | { 14 | public static int Run(string file, int timeout) 15 | { 16 | var compiler = new BooEulerCompiler(); 17 | Stopwatch run = new Stopwatch(); 18 | int exit = 0; 19 | try 20 | { 21 | Console.Error.Write("Compiling {0}...", Path.GetFileName(file)); 22 | var action = compiler.Compile(file); 23 | Console.Error.WriteLine(" OK, start!"); 24 | run.Start(); 25 | action(null); 26 | } 27 | catch (Exception e) 28 | { 29 | while (e is TargetInvocationException) e = (e as TargetInvocationException).InnerException; 30 | Console.ForegroundColor = ConsoleColor.Yellow; 31 | while (e != null) 32 | { 33 | Console.Error.WriteLine("{0}: {1}", e.GetType().Name, e.Message); 34 | if (e is CompilerError) 35 | Console.Error.WriteLine("{0} {1}", (e as CompilerError).Code, (e as CompilerError).LexicalInfo); 36 | Console.Error.WriteLine(e.StackTrace); 37 | e = e.InnerException; 38 | } 39 | exit = 3; 40 | } 41 | Console.ForegroundColor = ConsoleColor.Gray; 42 | Console.Error.WriteLine("Time: {0}ms", run.ElapsedMilliseconds); 43 | return exit; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Settings/IntXSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// instance settings. 7 | /// 8 | sealed public class IntXSettings 9 | { 10 | #region Private fields 11 | 12 | ToStringMode _toStringMode = ToStringMode.Fast; 13 | bool _autoNormalize = false; 14 | 15 | #endregion Private fields 16 | 17 | /// 18 | /// Creates new instance. 19 | /// 20 | /// IntX global settings to copy. 21 | internal IntXSettings(IntXGlobalSettings globalSettings) 22 | { 23 | // Copy local settings from global ones 24 | _autoNormalize = globalSettings.AutoNormalize; 25 | _toStringMode = globalSettings.ToStringMode; 26 | } 27 | 28 | #region Public properties 29 | 30 | /// 31 | /// To string conversion mode used in this instance. 32 | /// Set to value from by default. 33 | /// 34 | public ToStringMode ToStringMode 35 | { 36 | get { return _toStringMode; } 37 | set 38 | { 39 | // Check value 40 | if (!Enum.IsDefined(typeof(ToStringMode), value)) 41 | { 42 | throw new ArgumentOutOfRangeException("value"); 43 | } 44 | 45 | _toStringMode = value; 46 | } 47 | } 48 | 49 | /// 50 | /// If true then each operation is ended with big integer normalization. 51 | /// Set to value from by default. 52 | /// 53 | public bool AutoNormalize 54 | { 55 | get { return _autoNormalize; } 56 | set { _autoNormalize = value; } 57 | } 58 | 59 | #endregion Public properties 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tools/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $(MSBuildProjectDirectory)\build\ 4 | $(MSBuildProjectDirectory)\pkg\ 5 | $(MSBuildProjectDirectory)\..\ 6 | 7 | $(MSBuildProjectDirectory)\src\ 8 | Release 9 | x86 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /tools/src/BooRunner/ManyRunner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | 7 | namespace BooEulerTool 8 | { 9 | public class ManyRunner 10 | { 11 | public static int Run(string[] files, int timeout, bool sorted) 12 | { 13 | var compiler = new BooEulerCompiler(); 14 | var runner = new TimeoutRunner(timeout); 15 | 16 | IList results = files.Select(x => new RunnerResult(x)).ToList(); 17 | var columns = results.Max(x => x.RecommendedWidth); 18 | if (sorted) 19 | { 20 | results = results.Select(x => x.RunWith(compiler, runner).PrintSilent()) 21 | .OrderBy(x => x.HasException).ThenBy(x => x.Elapsed).ToList(); 22 | Console.Error.WriteLine(); 23 | foreach (var result in results) 24 | result.PrintFile(columns).PrintResult(); 25 | } 26 | else 27 | { 28 | results = results.Select(x => x.PrintFile(columns).RunWith(compiler, runner).PrintResult()).ToList(); 29 | } 30 | 31 | return PrintFinish(files, results); 32 | } 33 | private static int PrintFinish(string[] files, IEnumerable results) 34 | { 35 | var failed = results.Where(x => x.HasException).Count(); 36 | var time = results.Select(x => x.Elapsed.TotalMilliseconds).Sum(); 37 | 38 | Console.Error.Write("Total: {0} examples in {1:0.0}ms", files.Length, time); 39 | if (failed > 0) Console.Error.Write(" Failed: {0}", failed); 40 | Console.Error.WriteLine(); 41 | return failed == 0 ? 0 : 3; 42 | } 43 | 44 | 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /051.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Aims to generate all possible masks. So, design a base-11 number system, that 3 | compreehends 0..9 and *. Iterate through all the numbers in that system, and 4 | for each number, create all possible decimal representations (remake_as), 5 | replacing * by a number from 0..9. If a mask can generate 8 different primes 6 | with calls to remake_as, then we found our answer. 7 | 8 | Uses some black magic (see comment below). 9 | */ 10 | import System 11 | import System.Linq.Enumerable 12 | import System.Collections.Generic 13 | 14 | primes = PrimeNumbers() 15 | P10 = (1, 10**1, 10**2, 10**3, 10**4, 10**5, 10**6, 10**7, 10**8) 16 | def remake_as(mask as int, number as int): 17 | result,count,wildcards,temp=(0,0,0,0) 18 | while(mask): 19 | mask = Math.DivRem(mask, 11, temp) 20 | 21 | if (temp == 10): 22 | if not (mask or number): return 0 23 | temp = number 24 | wildcards++ 25 | result += P10[count++] * temp 26 | 27 | #BLACK MAGIC (most of the performance goes here) 28 | #only because numbers must be changed in groups of three 29 | #because looping throught the wildcard otherwise will generate 30 | #at least 3 multiples of 3 (10-3 = 7, at most) 31 | #actually, it should be %3, but we can cheat here, can't we? 32 | if wildcards != 3: return -1 33 | return result 34 | 35 | for i in range(int.MaxValue): 36 | count = 0 37 | 38 | for j in range(10): 39 | candidate = remake_as(i, j) 40 | if candidate == -1: break 41 | if primes.IsPrime(candidate): 42 | if ++count == 1: 43 | answer = candidate 44 | if j-count > 1: break #almost missed more than two, give up for this one 45 | if count == 8: break 46 | 47 | print answer 48 | assert answer == 121313 -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/Heap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Linq; 5 | using System.Collections; 6 | 7 | public class Heap 8 | { 9 | private List V; 10 | private Comparison comparer; 11 | 12 | public Heap() : this(null) { } 13 | public Heap(Comparison comparer) 14 | { 15 | this.comparer = comparer ?? Comparer.Default.Compare; 16 | this.V = new List(); 17 | V.Add(default(T)); 18 | } 19 | 20 | public virtual int Count { get { return V.Count - 1; } } 21 | public virtual T Front { get { return Count > 0 ? V[1] : default(T); } } 22 | 23 | public virtual void Push(T value) 24 | { 25 | V.Add(value); 26 | BubbleUp(Count); 27 | } 28 | 29 | public virtual T Pop() 30 | { 31 | if (Count == 0) return default(T); 32 | T value = V[1]; 33 | 34 | V[1] = V[Count]; 35 | V.RemoveAt(Count); 36 | 37 | BubbleDown(1); 38 | 39 | return value; 40 | } 41 | 42 | private void BubbleUp(int n) 43 | { 44 | while (n != 1 && IsLess(n, n / 2)) 45 | Swap(n, n = n / 2); 46 | } 47 | 48 | private void BubbleDown(int n) 49 | { 50 | while (IsLess(n * 2, n) || IsLess(n * 2 + 1, n)) 51 | Swap(n, n = Min(n * 2, n * 2 + 1)); 52 | } 53 | 54 | private bool IsLess(int a, int b) 55 | { 56 | if (a >= V.Count) return false; 57 | if (b >= V.Count) return true; 58 | return comparer(V[a], V[b]) < 0; 59 | } 60 | 61 | private int Min(int a, int b) 62 | { 63 | return IsLess(a, b) ? a : b; 64 | } 65 | 66 | private void Swap(int a, int b) 67 | { 68 | T c = V[a]; 69 | V[a] = V[b]; 70 | V[b] = c; 71 | } 72 | 73 | } 74 | 75 | 76 | -------------------------------------------------------------------------------- /101.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Creates linear system and solve by gaussian elimination. 3 | 4 | E.g.: to create a 4-term minimum polynomial for polynomial n^4, we have that: 5 | 6 | a + bn + cn^2 + dn^3 = n^4, or 7 | 8 | a + b + c + d = 1 9 | a + 2b + 4c + 8d = 16 10 | a + 3b + 9c + 27d = 81 11 | a + 4b + 16c + 64d = 256 12 | 13 | We can, now solve this system by gaussian elimination and discover what are 14 | the coeficients a,b,c,d. All we have to do is make this process to all degrees 15 | required by the problem. 16 | 17 | Credits for the solution to Jacqueline Abreu (@JacAbreu). 18 | */ 19 | import System 20 | import System.Linq.Enumerable 21 | 22 | def poly(n as double): 23 | return 1.0 - n + n**2 - n**3 + n**4 - n**5 + n**6 - n**7 + n**8 - n**9 + n**10 24 | 25 | def gauss(M as (double, 2)): 26 | n, m = len(M,0), len(M,1) 27 | for i in range(n): 28 | factor = M[i,i] 29 | for j in range(m): 30 | M[i,j] = M[i,j] / factor 31 | 32 | for k in range(n): 33 | if k==i: continue 34 | factor = M[k,i] 35 | for j in range(m): 36 | M[k,j] = M[k,j] - M[i,j]*factor 37 | 38 | return range(n).Select({a|M[a,m-1]}).ToArray() 39 | 40 | def create(i as double): 41 | M = matrix(double, i, i+1) 42 | for a as double in range(i): 43 | for b as double in range(i): 44 | M[a,b] = (a+1)**b 45 | M[a,i] = poly(a+1) 46 | return M 47 | 48 | def apply(F as (double), n as double): 49 | res = 0.0 50 | for i in range(F.Length): 51 | res += F[i] * n**i 52 | return res 53 | 54 | answer = 0.0 55 | for i in range(1, 11): 56 | M = create(i) 57 | G = gauss(M) 58 | 59 | for n in range(1,int.MaxValue): 60 | v1 = poly(n) 61 | v2 = apply(G, n) 62 | if v1!=v2: 63 | answer += v2 64 | break 65 | 66 | print answer 67 | assert answer == 37076114526 68 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Dividers/DivideManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Used to retrieve needed divider. 7 | /// 8 | static internal class DivideManager 9 | { 10 | #region Fields 11 | 12 | /// 13 | /// Classic divider instance. 14 | /// 15 | static readonly public IDivider ClassicDivider; 16 | 17 | /// 18 | /// Newton divider instance. 19 | /// 20 | static readonly public IDivider AutoNewtonDivider; 21 | 22 | #endregion Fields 23 | 24 | #region Constructors 25 | 26 | // .cctor 27 | static DivideManager() 28 | { 29 | // Create new classic divider instance 30 | IDivider classicDivider = new ClassicDivider(); 31 | 32 | // Fill publicity visible divider fields 33 | ClassicDivider = classicDivider; 34 | AutoNewtonDivider = new AutoNewtonDivider(classicDivider); 35 | } 36 | 37 | #endregion Constructors 38 | 39 | #region Methods 40 | 41 | /// 42 | /// Returns divider instance for given divide mode. 43 | /// 44 | /// Divide mode. 45 | /// Divider instance. 46 | /// is out of range. 47 | static public IDivider GetDivider(DivideMode mode) 48 | { 49 | // Check value 50 | if (!Enum.IsDefined(typeof(DivideMode), mode)) 51 | { 52 | throw new ArgumentOutOfRangeException("mode"); 53 | } 54 | 55 | switch (mode) 56 | { 57 | case DivideMode.AutoNewton: 58 | return AutoNewtonDivider; 59 | default: 60 | return ClassicDivider; 61 | } 62 | } 63 | 64 | /// 65 | /// Returns current divider instance. 66 | /// 67 | /// Current divider instance. 68 | static public IDivider GetCurrentDivider() 69 | { 70 | return GetDivider(BigInteger.GlobalSettings.DivideMode); 71 | } 72 | 73 | #endregion Methods 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Parsers/ParseManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Used to retrieve needed parser. 7 | /// 8 | static internal class ParseManager 9 | { 10 | #region Fields 11 | 12 | /// 13 | /// Classic parser instance. 14 | /// 15 | static readonly public IParser ClassicParser; 16 | 17 | /// 18 | /// Fast parser instance. 19 | /// 20 | static readonly public IParser FastParser; 21 | 22 | #endregion Fields 23 | 24 | #region Constructors 25 | 26 | // .cctor 27 | static ParseManager() 28 | { 29 | // Create new pow2 parser instance 30 | IParser pow2Parser = new Pow2Parser(); 31 | 32 | // Create new classic parser instance 33 | IParser classicParser = new ClassicParser(pow2Parser); 34 | 35 | // Fill publicity visible parser fields 36 | ClassicParser = classicParser; 37 | FastParser = new FastParser(pow2Parser, classicParser); 38 | } 39 | 40 | #endregion Constructors 41 | 42 | #region Methods 43 | 44 | /// 45 | /// Returns parser instance for given parse mode. 46 | /// 47 | /// Parse mode. 48 | /// Parser instance. 49 | /// is out of range. 50 | static public IParser GetParser(ParseMode mode) 51 | { 52 | // Check value 53 | if (!Enum.IsDefined(typeof(ParseMode), mode)) 54 | { 55 | throw new ArgumentOutOfRangeException("mode"); 56 | } 57 | 58 | switch (mode) 59 | { 60 | case ParseMode.Fast: 61 | return FastParser; 62 | default: 63 | return ClassicParser; 64 | } 65 | } 66 | 67 | /// 68 | /// Returns current parser instance. 69 | /// 70 | /// Current parser instance. 71 | static public IParser GetCurrentParser() 72 | { 73 | return GetParser(BigInteger.GlobalSettings.ParseMode); 74 | } 75 | 76 | #endregion Methods 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/StringConverters/StringConvertManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Used to retrieve needed ToString converter. 7 | /// 8 | static internal class StringConvertManager 9 | { 10 | #region Fields 11 | 12 | /// 13 | /// Classic converter instance. 14 | /// 15 | static readonly public IStringConverter ClassicStringConverter; 16 | 17 | /// 18 | /// Fast converter instance. 19 | /// 20 | static readonly public IStringConverter FastStringConverter; 21 | 22 | #endregion Fields 23 | 24 | #region Constructors 25 | 26 | // .cctor 27 | static StringConvertManager() 28 | { 29 | // Create new pow2 converter instance 30 | IStringConverter pow2StringConverter = new Pow2StringConverter(); 31 | 32 | // Create new classic converter instance 33 | IStringConverter classicStringConverter = new ClassicStringConverter(pow2StringConverter); 34 | 35 | // Fill publicity visible converter fields 36 | ClassicStringConverter = classicStringConverter; 37 | FastStringConverter = new FastStringConverter(pow2StringConverter, classicStringConverter); 38 | } 39 | 40 | #endregion Constructors 41 | 42 | #region Methods 43 | 44 | /// 45 | /// Returns ToString converter instance for given ToString mode. 46 | /// 47 | /// ToString mode. 48 | /// Converter instance. 49 | /// is out of range. 50 | static public IStringConverter GetStringConverter(ToStringMode mode) 51 | { 52 | // Check value 53 | if (!Enum.IsDefined(typeof(ToStringMode), mode)) 54 | { 55 | throw new ArgumentOutOfRangeException("mode"); 56 | } 57 | 58 | switch (mode) 59 | { 60 | case ToStringMode.Fast: 61 | return FastStringConverter; 62 | default: 63 | return ClassicStringConverter; 64 | } 65 | } 66 | 67 | #endregion Methods 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /084.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Simple Markov Chain 3 | 4 | Given M[i,j], the probability of starting at "i" and end at "j", computes the 5 | result of M^1024. 6 | */ 7 | import System 8 | import System.Collections.Generic 9 | import System.Linq.Enumerable 10 | 11 | M = matrix(double, 40, 40) 12 | 13 | def add(i as int, j as int, v as double): 14 | M[i,j] = M[i,j] + v 15 | 16 | dice = 4 17 | for i in range(40): 18 | for a in range(1,dice+1): 19 | for b in range(1,dice+1): 20 | d = (i+a+b)%40 21 | p = 1.0/(dice*dice) 22 | if a==b: 23 | add(i,10,p /(dice*dice)) 24 | p -= p /(dice*dice) 25 | 26 | if d in (2,17,33): 27 | add(i,0, p/16) 28 | add(i,10, p/16) 29 | add(i,d, p*14/16) 30 | continue 31 | 32 | if d in (7, 22, 36): 33 | add(i,0, p/16) 34 | add(i,10, p/16) 35 | add(i,11, p/16) 36 | add(i,24, p/16) 37 | add(i,39, p/16) 38 | add(i,5, p/16) 39 | add(i,((d+5) * 10 / 10 + 5)%40, p*2/16) 40 | 41 | if d<12 or d>28: 42 | add(i,12,p/16) 43 | elif d<28: 44 | add(i,28,p/16) 45 | add(i,(d+37)%40, p/16) 46 | add(i,d, p*6/16) 47 | continue 48 | 49 | if d==30: d = 10 50 | 51 | add(i,d, p) 52 | 53 | T = M 54 | for steps in range(10): 55 | T2 = matrix(double, 40, 40) 56 | for i in range(40): 57 | for k in range(40): 58 | for j in range(40): 59 | T2[i,j] = T2[i,j] + T[i,k]*T[k,j] 60 | T = T2 61 | 62 | L = List[of (double)]() 63 | for i in range(40): 64 | s = 0.0 65 | for j in range(40): 66 | s += T[j,i] 67 | L.Add((s,i)) 68 | 69 | answer = int.Parse(String.Join("", L.OrderByDescending({x|x[0]}).Select({x|x[1].ToString("00")}).Take(3).ToArray())) 70 | print answer 71 | assert answer == 101524 72 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/StringConverters/ClassicStringConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Classic ToString converting algorithm using division (O[n^2]). 7 | /// 8 | sealed internal class ClassicStringConverter : StringConverterBase 9 | { 10 | #region Constructor 11 | 12 | /// 13 | /// Creates new instance. 14 | /// 15 | /// Converter for pow2 case. 16 | public ClassicStringConverter(IStringConverter pow2StringConverter) : base(pow2StringConverter) {} 17 | 18 | #endregion Constructor 19 | 20 | /// 21 | /// Converts digits from internal representaion into given base. 22 | /// 23 | /// Big integer digits. 24 | /// Big integer length. 25 | /// Base to use for output. 26 | /// Calculated output length (will be corrected inside). 27 | /// Conversion result (later will be transformed to string). 28 | override public uint[] ToString(uint[] digits, uint length, uint numberBase, ref uint outputLength) 29 | { 30 | uint[] outputArray = base.ToString(digits, length, numberBase, ref outputLength); 31 | 32 | // Maybe base method already converted this number 33 | if (outputArray != null) return outputArray; 34 | 35 | // Create an output array for storing of number in other base 36 | outputArray = new uint[outputLength + 1]; 37 | 38 | // Make a copy of initial data 39 | uint[] digitsCopy = new uint[length]; 40 | Array.Copy(digits, digitsCopy, length); 41 | 42 | // Calculate output numbers by dividing 43 | uint outputIndex; 44 | for (outputIndex = 0; length > 0; ++outputIndex) 45 | { 46 | length = DigitOpHelper.DivMod(digitsCopy, length, numberBase, digitsCopy, out outputArray[outputIndex]); 47 | } 48 | 49 | outputLength = outputIndex; 50 | return outputArray; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Multipliers/MultiplyManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Used to retrieve needed multiplier. 7 | /// 8 | static internal class MultiplyManager 9 | { 10 | #region Fields 11 | 12 | /// 13 | /// Classic multiplier instance. 14 | /// 15 | static readonly public IMultiplier ClassicMultiplier; 16 | 17 | /// 18 | /// FHT multiplier instance. 19 | /// 20 | static readonly public IMultiplier AutoFhtMultiplier; 21 | 22 | #endregion Fields 23 | 24 | #region Constructors 25 | 26 | // .cctor 27 | static MultiplyManager() 28 | { 29 | // Create new classic multiplier instance 30 | IMultiplier classicMultiplier = new ClassicMultiplier(); 31 | 32 | // Fill publicity visible multiplier fields 33 | ClassicMultiplier = classicMultiplier; 34 | AutoFhtMultiplier = new AutoFhtMultiplier(classicMultiplier); 35 | } 36 | 37 | #endregion Constructors 38 | 39 | #region Methods 40 | 41 | /// 42 | /// Returns multiplier instance for given multiply mode. 43 | /// 44 | /// Multiply mode. 45 | /// Multiplier instance. 46 | /// is out of range. 47 | static public IMultiplier GetMultiplier(MultiplyMode mode) 48 | { 49 | // Check value 50 | if (!Enum.IsDefined(typeof(MultiplyMode), mode)) 51 | { 52 | throw new ArgumentOutOfRangeException("mode"); 53 | } 54 | 55 | switch (mode) 56 | { 57 | case MultiplyMode.AutoFht: 58 | return AutoFhtMultiplier; 59 | default: 60 | return ClassicMultiplier; 61 | } 62 | } 63 | 64 | /// 65 | /// Returns current multiplier instance. 66 | /// 67 | /// Current multiplier instance. 68 | static public IMultiplier GetCurrentMultiplier() 69 | { 70 | return GetMultiplier(BigInteger.GlobalSettings.MultiplyMode); 71 | } 72 | 73 | #endregion Methods 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /103.boo: -------------------------------------------------------------------------------- 1 | /* 2 | We use the answers from 105 and 106 to calculate this answer. So please, see 3 | them first. 4 | 5 | We backtrack through all possible sets, pruning some extreme conditions, to 6 | verify if it forms a special sum set, then we check if it is minimum. 7 | */ 8 | import System 9 | import System.Linq.Enumerable 10 | 11 | K = List[of (int)]() 12 | 13 | def need_count(a as int, b as int): 14 | if a&b: return false 15 | 16 | ca,cb,balance=0,0,0 17 | need=false 18 | 19 | while a or b: 20 | if a&1: 21 | ca+=1 22 | balance-=1 23 | if b&1: 24 | cb+=1 25 | balance+=1 26 | if balance>0: 27 | need=true 28 | a>>=1 29 | b>>=1 30 | 31 | return ca==cb and ca!=1 and need 32 | 33 | def property1(A as (int)): 34 | begin,end=A[0],0 35 | for i in range(1, (A.Length-1)/2+1): 36 | begin += A[i] 37 | end += A[A.Length-i] 38 | if begin <= end: 39 | return false 40 | return true 41 | 42 | def property2(A as (int)): 43 | for b, c in K: 44 | sb,sc,i = 0, 0, 0 45 | while b or c: 46 | if b&1: sb += A[i] 47 | if c&1: sc += A[i] 48 | 49 | i += 1 50 | b >>= 1 51 | c >>= 1 52 | if sb==sc: return false 53 | return true 54 | 55 | def property(A as (int)): 56 | return property1(A) and property2(A) 57 | 58 | L = 7 59 | for a in range(1,2**L): 60 | for b in range(a+1,2**L): 61 | if need_count(a,b): 62 | K.Add((a,b)) 63 | 64 | T = array(int, L) 65 | minn = int.MaxValue 66 | answer = 0L 67 | 68 | def backtrack(k as int, s as int) as void: 69 | if k==L: 70 | if property(T) and s0 else 0)+1 76 | end = (T[0] + T[1] if k>1 else 32) 77 | for i in range(start, end): 78 | T[k] = i 79 | backtrack(k+1, s+i) 80 | 81 | backtrack(0,0) 82 | 83 | print answer 84 | assert answer == 20313839404245 85 | -------------------------------------------------------------------------------- /068.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Extremely bruteforce. Defines the 5-gon as 3 | F 4 | A 5 | B C 6 | G D E 7 | 8 | And so on. Generate values only until F. The others can be calculated. Apply 9 | constraints. Only F..J can reach 10, otherwise it'll create an 17-digit string. 10 | 11 | I know, it's ugly, but works and runs fast :) 12 | */ 13 | import System 14 | import System.Linq.Enumerable 15 | 16 | def make_number(triples as ((int))): 17 | min = triples.Select({x|x[0]}).Min() 18 | for i in range(5): 19 | if triples[i][0] == min: 20 | start = i 21 | 22 | 23 | triples = triples.Skip(start).Concat(triples.Take(start)).ToArray() 24 | numbers = triples.Select({x|string.Join('',x.Select({x|Convert.ToString(x)}).ToArray())}) 25 | number = long.Parse(string.Join('', numbers.ToArray())) 26 | return number 27 | 28 | answer = 0L 29 | for a in range(1,10): 30 | for b in range(1,10): 31 | if b in (a,): continue 32 | for c in range(1,10): 33 | if c in (a,b): continue 34 | for d in range(1,10): 35 | if d in (a,b,c): continue 36 | for e in range(1,10): 37 | if e in (a,b,c,d): continue 38 | for f in range(1,11): 39 | if f in (a,b,c,d,e): continue 40 | z = f+a+c 41 | g = z-b-a 42 | if g < 0 or g > 10 or g in (a,b,c,d,e,f): continue 43 | 44 | h = z-d-b 45 | if h < 0 or h > 10 or h in (a,b,c,d,e,f,g): continue 46 | 47 | i = z-e-d 48 | if i < 0 or i > 10 or i in (a,b,c,d,e,f,g,h): continue 49 | 50 | j = z-c-e 51 | if j < 0 or j > 10 or j in (a,b,c,d,e,f,g,h, i): continue 52 | 53 | triples = ((j,c,e),(i,e,d),(h,d,b),(g,b,a),(f,a,c)) 54 | answer = Math.Max(answer, make_number(triples)) 55 | 56 | print answer 57 | assert answer == 6531031914842725 58 | -------------------------------------------------------------------------------- /011.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Pure brute force. Defines all pairs in all directions then searches for the 3 | greatest product. 4 | */ 5 | import System 6 | import System.Linq.Enumerable 7 | 8 | A = ( 9 | (08,02,22,97,38,15,00,40,00,75,04,05,07,78,52,12,50,77,91,08), 10 | (49,49,99,40,17,81,18,57,60,87,17,40,98,43,69,48,04,56,62,00), 11 | (81,49,31,73,55,79,14,29,93,71,40,67,53,88,30,03,49,13,36,65), 12 | (52,70,95,23,04,60,11,42,69,24,68,56,01,32,56,71,37,02,36,91), 13 | (22,31,16,71,51,67,63,89,41,92,36,54,22,40,40,28,66,33,13,80), 14 | (24,47,32,60,99,03,45,02,44,75,33,53,78,36,84,20,35,17,12,50), 15 | (32,98,81,28,64,23,67,10,26,38,40,67,59,54,70,66,18,38,64,70), 16 | (67,26,20,68,02,62,12,20,95,63,94,39,63,08,40,91,66,49,94,21), 17 | (24,55,58,05,66,73,99,26,97,17,78,78,96,83,14,88,34,89,63,72), 18 | (21,36,23,09,75,00,76,44,20,45,35,14,00,61,33,97,34,31,33,95), 19 | (78,17,53,28,22,75,31,67,15,94,03,80,04,62,16,14,09,53,56,92), 20 | (16,39,05,42,96,35,31,47,55,58,88,24,00,17,54,24,36,29,85,57), 21 | (86,56,00,48,35,71,89,07,05,44,44,37,44,60,21,58,51,54,17,58), 22 | (19,80,81,68,05,94,47,69,28,73,92,13,86,52,17,77,04,89,55,40), 23 | (04,52,08,83,97,35,99,16,07,97,57,32,16,26,26,79,33,27,98,66), 24 | (88,36,68,87,57,62,20,72,03,46,33,67,46,55,12,32,63,93,53,69), 25 | (04,42,16,73,38,25,39,11,24,94,72,18,08,46,29,32,40,62,76,36), 26 | (20,69,36,41,72,30,23,88,34,62,99,69,82,67,59,85,74,04,36,16), 27 | (20,73,35,29,78,31,90,01,74,31,49,71,48,86,81,16,23,57,05,54), 28 | (01,70,54,71,83,51,54,69,16,92,33,48,61,43,52,01,89,19,67,48) 29 | ) 30 | 31 | pairs = [(a,b) for a in range(0,20) for b in range(0, 20)] 32 | 33 | S = [[(a+i,b) for i in range(0, 4) if a+i<20] for a as int, b as int in pairs] 34 | E = [[(a,b+i) for i in range(0, 4) if b+i<20] for a as int, b as int in pairs] 35 | SE = [[(a+i,b+i) for i in range(0, 4) if a+i<20 and b+i<20] for a as int, b as int in pairs] 36 | NE = [[(a-i,b+i) for i in range(0, 4) if a-i>=0 and b+i<20] for a as int, b as int in pairs] 37 | 38 | product = {x as (int)|x[0]*x[1]*x[2]*x[3]} 39 | make_sum = {x as List|product(x.Cast[of (int)]().Select({y|A[y[0]][y[1]]}).ToArray())} 40 | 41 | answer = (S+E+SE+NE).Cast[of List]().Where({x|x.Count == 4}).Select(make_sum).Max() 42 | 43 | print answer 44 | assert answer == 70600674 -------------------------------------------------------------------------------- /061.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Well, that's hard to explain. 3 | 4 | First, we simplify all the functions to its parameters. 5 | e.g. n(5n-3)/2 yields a=5, b=-2,c=2 6 | 7 | With these parameters, we define generate and check functions. Each function 8 | type is defined by an index. 0 is triangle, 1 is square, etc. 9 | 10 | Then we generate all possible permutations of the function indexes, allowing 11 | to have any order of functions for the generated number. We only freezes the 12 | last as being 5 to avoid multiple solutions by cycling the permutations. And 13 | to reduce execution time also. 14 | 15 | Please note that only the first, third and fifth values are generated. The 16 | others can be calculated by cycling them. To find a solution, it's just a matter 17 | of testing if the cycled values are of the type of values they claim to be. 18 | */ 19 | import System 20 | import System.Linq.Enumerable 21 | 22 | formulae = ((1,1,2), (1,0,1), (3,-1,2), (2,-1,1), (5,-3,2), (3,-2,1)) 23 | 24 | def generate(f as int): 25 | a,b,c = formulae[f] 26 | for n in range(int.MaxValue): 27 | v = n*(a*n+b)/c 28 | if v >= 10**4: break 29 | if v >= 10**3 and v%100 > 9: yield v 30 | 31 | def check(f as int, x as int): 32 | if x < 1000: return false 33 | a,b,c = formulae[f] 34 | n = (-b + Math.Sqrt(b*b + 4*a*c*x)) / (2.0*a) 35 | return cast(int, n) == n 36 | 37 | def cycle(a as int, b as int): 38 | return a%100*100+b/100 39 | 40 | def kth_permutation(n as int, k as int): 41 | data = array(int, n) 42 | for j in range(1, n+1): 43 | data[n-j] = (k % j) 44 | k /= j 45 | 46 | data[n-1] = 0 47 | for i in range(n-2, -1): 48 | for j in range(i+1, n): 49 | if data[j] >= data[i]: data[j] += 1 50 | return data 51 | 52 | for k in range(5*4*3*2*1): 53 | a,b,c,d,e = kth_permutation(5, k) 54 | f = 5 55 | for va in generate(a): 56 | for vc in generate(c): 57 | vb = cycle(va,vc) 58 | if not check(b, vb): continue 59 | for ve in generate(e): 60 | vd = cycle(vc,ve) 61 | if not check(d, vd): continue 62 | vf = cycle(ve,va) 63 | if not check(f, vf): continue 64 | answer = va+vb+vc+vd+ve+vf 65 | 66 | print answer 67 | assert answer == 28684 -------------------------------------------------------------------------------- /093.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Backtrack to create all possible reverse polish expressions. 3 | 4 | Digits 10..13 represents the operations. So, the following expressions are 5 | equivalent: 6 | 7 | 1 2 10 3 4 12 13 <=> 1 2 + 3 4 * / <=> (1 + 2) / (3 * 4) 8 | 9 | Gotta be careful to add at most 4 digits and 3 operators. Also, avoid adding 10 | an operator until there is 2 more digits than operators (to have what to 11 | operate). 12 | 13 | Then just executes the expression using a stack. 14 | */ 15 | import System 16 | import System.Collections.Generic 17 | import System.Linq.Enumerable 18 | 19 | N = matrix(bool, 10000, 10000) 20 | V = array(bool, 14) 21 | T = array(int, 7) 22 | IMP = -10000000 23 | 24 | add = { x as double, y as double | x+y } 25 | sub = { x as double, y as double | x-y } 26 | mul = { x as double, y as double | x*y } 27 | div = { x as double, y as double | (x/y if y!=0 else IMP ) } 28 | all = (add, sub, mul, div) 29 | 30 | def back(k as int, numbs as int, ops as int) as void: 31 | if k==7: 32 | q = Stack[of double]() 33 | digits = List[of int]() 34 | for i in T: 35 | if i < 10: 36 | q.Push(i) 37 | digits.Add(i) 38 | else: 39 | a,b=q.Pop(),q.Pop() 40 | c = all[i-10](b,a) 41 | if c == IMP: return 42 | q.Push(c) 43 | v = q.Pop() 44 | if v<0 or v != cast(int, v): return 45 | 46 | n = 0 47 | for i in digits.OrderBy({x | return x}): 48 | n = n*10+i 49 | N[n,v] = true 50 | 51 | return 52 | 53 | if numbs < 4: 54 | for i in range(1, 10): 55 | if V[i]: continue 56 | 57 | V[i] = true 58 | T[k] = i 59 | back(k+1, numbs+1, ops) 60 | V[i] = false 61 | 62 | if numbs-ops >= 2 and ops < 3: 63 | for i in range(10, 14): 64 | T[k] = i 65 | back(k+1, numbs, ops+1) 66 | 67 | back(0, 0, 0) 68 | 69 | answer = 0 70 | maxx = 0 71 | for i in range(10000): 72 | for j in range(1, 10000): 73 | if not N[i,j]: 74 | if j > maxx: 75 | answer = i 76 | maxx = j 77 | break 78 | print answer 79 | assert answer == 1258 80 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Multipliers/ClassicMultiplier.cs: -------------------------------------------------------------------------------- 1 | namespace BooRunner.Tools 2 | { 3 | /// 4 | /// Multiplies using "classic" algorithm. 5 | /// 6 | sealed internal class ClassicMultiplier : MultiplierBase 7 | { 8 | /// 9 | /// Multiplies two big integers using pointers. 10 | /// 11 | /// First big integer digits. 12 | /// First big integer length. 13 | /// Second big integer digits. 14 | /// Second big integer length. 15 | /// Resulting big integer digits. 16 | /// Resulting big integer length. 17 | override unsafe public uint Multiply(uint* digitsPtr1, uint length1, uint* digitsPtr2, uint length2, uint* digitsResPtr) 18 | { 19 | ulong c; 20 | 21 | // External cycle must be always smaller 22 | if (length1 < length2) 23 | { 24 | // First must be bigger - swap 25 | uint lengthTemp = length1; 26 | length1 = length2; 27 | length2 = lengthTemp; 28 | 29 | uint* ptrTemp = digitsPtr1; 30 | digitsPtr1 = digitsPtr2; 31 | digitsPtr2 = ptrTemp; 32 | } 33 | 34 | // Prepare end pointers 35 | uint* digitsPtr1End = digitsPtr1 + length1; 36 | uint* digitsPtr2End = digitsPtr2 + length2; 37 | 38 | // We must always clear first "length1" digits in result 39 | DigitHelper.SetBlockDigits(digitsResPtr, length1, 0U); 40 | 41 | // Perform digits multiplication 42 | uint* ptr1, ptrRes = null; 43 | for (; digitsPtr2 < digitsPtr2End; ++digitsPtr2, ++digitsResPtr) 44 | { 45 | // Check for zero (sometimes may help). There is no sense to make this check in internal cycle - 46 | // it would give performance gain only here 47 | if (*digitsPtr2 == 0) continue; 48 | 49 | c = 0; 50 | for (ptr1 = digitsPtr1, ptrRes = digitsResPtr; ptr1 < digitsPtr1End; ++ptr1, ++ptrRes) 51 | { 52 | c += (ulong)*digitsPtr2 * *ptr1 + *ptrRes; 53 | *ptrRes = (uint)c; 54 | c >>= 32; 55 | } 56 | *ptrRes = (uint)c; 57 | } 58 | 59 | uint newLength = length1 + length2; 60 | if (newLength > 0 && (ptrRes == null || *ptrRes == 0)) 61 | { 62 | --newLength; 63 | } 64 | return newLength; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Parsers/ClassicParser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Classic parsing algorithm using multiplication (O[n^2]). 7 | /// 8 | sealed internal class ClassicParser : ParserBase 9 | { 10 | #region Constructor 11 | 12 | /// 13 | /// Creates new instance. 14 | /// 15 | /// Parser for pow2 case. 16 | public ClassicParser(IParser pow2Parser) : base(pow2Parser) {} 17 | 18 | #endregion Constructor 19 | 20 | /// 21 | /// Parses provided string representation of object. 22 | /// 23 | /// Number as string. 24 | /// Index inside string from which to start. 25 | /// Index inside string on which to end. 26 | /// Number base. 27 | /// Char->digit dictionary. 28 | /// Resulting digits. 29 | /// Parsed integer length. 30 | override public uint Parse(string value, int startIndex, int endIndex, uint numberBase, IDictionary charToDigits, uint[] digitsRes) 31 | { 32 | uint newLength = base.Parse(value, startIndex, endIndex, numberBase, charToDigits, digitsRes); 33 | 34 | // Maybe base method already parsed this number 35 | if (newLength != 0) return newLength; 36 | 37 | // Do parsing in big cycle 38 | ulong numberBaseLong = numberBase; 39 | ulong digit; 40 | for (int i = startIndex; i <= endIndex; ++i) 41 | { 42 | digit = StrRepHelper.GetDigit(charToDigits, value[i], numberBase); 43 | 44 | // Next multiply existing values by base and add this value to them 45 | if (newLength == 0) 46 | { 47 | if (digit != 0) 48 | { 49 | digitsRes[0] = (uint)digit; 50 | newLength = 1; 51 | } 52 | } 53 | else 54 | { 55 | for (uint j = 0; j < newLength; ++j) 56 | { 57 | digit += digitsRes[j] * numberBaseLong; 58 | digitsRes[j] = (uint)digit; 59 | digit >>= 32; 60 | } 61 | if (digit != 0) 62 | { 63 | digitsRes[newLength++] = (uint)digit; 64 | } 65 | } 66 | } 67 | 68 | return newLength; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /060.boo: -------------------------------------------------------------------------------- 1 | /* 2 | Brute force solution. Precalculates all the primes and the possible relations 3 | they have. Uses Miller-Rabin primality test since the numbers can get really 4 | big. 5 | 6 | Caches PP(i,j) "does the pair P(i),P(j) have the property" 7 | Caches LOG10(i) "log10(P(i))+1" 8 | 9 | What remains is pure brute force. With some pruning, but brute force. 10 | */ 11 | import System 12 | import System.Linq.Enumerable 13 | 14 | primes = PrimeNumbers() 15 | L = 1051 16 | D = (1, 10**1, 10**2, 10**3, 10**4, 10**5) 17 | 18 | P = primes.Take(L).ToArray() 19 | LOG10 = P.Select({x|D[cast(int, Math.Log10(x))+1]}).ToArray() 20 | 21 | PP = matrix(bool, L, L) 22 | 23 | def pow(a as int, n as int, mod as int): 24 | r, p = (1L, cast(long, a)) 25 | while(n): 26 | if n%2: r=(r*p)%mod 27 | p=(p*p)%mod 28 | n/=2 29 | 30 | return r 31 | 32 | 33 | def witness(a as int, n as int): 34 | u,t= (n/2, 1) 35 | while(u%2==0): u,t = (u/2, t+1) 36 | 37 | prev = pow(a,u,n); 38 | 39 | for i in range(t): 40 | curr=(prev*prev)%n 41 | if curr==1 and prev!=1 and prev!=n-1: return true 42 | prev=curr 43 | 44 | return curr != 1 45 | 46 | 47 | def is_prime(n as int): 48 | if n in (2, 7, 61): return true 49 | if witness(2,n): return false 50 | if witness(7,n): return false 51 | if witness(61,n): return false 52 | return true 53 | 54 | 55 | for i in range(L): 56 | for j in range(i+1,L): 57 | PP[i,j] = is_prime(P[i] * LOG10[j] + P[j]) and is_prime(P[j] * LOG10[i] + P[i]) 58 | PP[j,i] = PP[i,j] 59 | 60 | answer = int.MaxValue 61 | for a in range(L): 62 | if answer < int.MaxValue: break 63 | for b in range(a+1,L): 64 | if answer < int.MaxValue: break 65 | if not PP[a,b] or P[a]+P[b] >= answer: continue 66 | for c in range(b+1, L): 67 | if answer < int.MaxValue: break 68 | if not PP[c,b] or not PP[c,a] or P[a]+P[b]+P[c] >= answer: continue 69 | for d in range(c+1, L): 70 | if answer < int.MaxValue: break 71 | if not PP[d,c] or not PP[d,b] or not PP[d,a] or P[a]+P[b]+P[c]+P[d] >= answer: continue 72 | for e in range(d+1, L): 73 | if answer < int.MaxValue: break 74 | if not PP[e,d] or not PP[e,c] or not PP[e,b] or not PP[e,a] or P[a]+P[b]+P[c]+P[d]+P[e] >= answer: continue 75 | answer = P[a]+P[b]+P[c]+P[d]+P[e] 76 | 77 | print answer 78 | assert answer == 26033 -------------------------------------------------------------------------------- /108.boo: -------------------------------------------------------------------------------- 1 | /* 2 | First, we have to know some things: 3 | 4 | This solution applies both to 108 and 110. There is a simpler solution that 5 | solves 108 in desired time, but would never be good for 110. So I made this one. 6 | 7 | The number of solutions for the specified equation is defined by factorizing 8 | the "n". If n = p1^a1*p2^a2...pn^an, then, the solution is given by 9 | (2*a1+1) * (2*a2+1) ... (2*an+1)/2 +1. But, calculating it is not easy. For the 10 | problem 108, it would be good enough, but for 110, it would never finish 11 | 12 | We know that the solution is among the highly composite numbers, so we start by 13 | defining the limits of the problem. That is, the first product of primes 14 | 2*3*5*7*11... the 3*3*3*3*3... of the solution reaches what we want, ie, the 15 | double of the desired number 10**3*2 or 4*10**6*2. This is just to define upper bound 16 | limits for the future backtrack. In this preprocessing, we achieve K, T and N, 17 | that means the upper bound number of solutions K for the upper bound n=T using 18 | at most the prime indexed by N. 19 | 20 | e.g. K=3^6, T=2*3*5*7*11*13, N=6 21 | 22 | With these numbers in hand, we write a backtrack function to generate all the 23 | combination of the prime powers, ensuring the decreasing order, ie, if the 24 | answer contains 2^a1, for example, the power of 3 would never exceed a1. We can 25 | prove that is right by ensuring we will always try to get the minimum number 26 | with highest number of factors. 27 | 28 | We don't try to generate a vector and regenerate the two products everytime. 29 | Instead, we keep track of the current k and t, relative to the upper bounds K 30 | and T. As K involves sum of products, each prime index uses a temporary kk to 31 | hold the 2*i+1 32 | 33 | Every time k*kk is lesser than K, but greater the number we want (L), we 34 | register a new minimum K with a new answer T. 35 | 36 | At the end of the backtrack, we hope T is the desired answer. 37 | */ 38 | import System 39 | import System.Linq.Enumerable 40 | 41 | primes = PrimeNumbers() 42 | 43 | L = 10**3 * 2 44 | K, T = BigInteger(1), BigInteger(1) 45 | N = 0 46 | 47 | for p in primes: 48 | K,T = (K*3, T*p) 49 | N++ 50 | if K >= L: break 51 | 52 | P = primes.Take(N).ToArray() 53 | 54 | def backtrack(p as int, last as BigInteger, k as BigInteger, t as BigInteger): 55 | if p >= N: return 56 | prime = P[p] 57 | i, kk = 0, 1 58 | while k*kk < K and t < T and i < last: 59 | i, kk = i+1, kk+2 60 | t *= prime 61 | 62 | if k*kk >= L and k*kk= L: break 51 | 52 | P = primes.Take(N).ToArray() 53 | 54 | def backtrack(p as int, last as BigInteger, k as BigInteger, t as BigInteger): 55 | if p >= N: return 56 | prime = P[p] 57 | i, kk = 0, 1 58 | while k*kk < K and t < T and i < last: 59 | i, kk = i+1, kk+2 60 | t *= prime 61 | 62 | if k*kk >= L and k*kk action) 22 | { 23 | using (var stream = new MemoryStream()) 24 | { 25 | var writer = new StreamWriter(stream); 26 | var defOut = Console.Out; 27 | Console.SetOut(writer); 28 | 29 | Exception ex; 30 | string[] lines; 31 | var sw = Stopwatch.StartNew(); 32 | try 33 | { 34 | ex = RunAction(action, timeout); 35 | } 36 | finally 37 | { 38 | lines = FinishStream(stream, writer); 39 | Console.SetOut(defOut); 40 | } 41 | return new RunnerResult(file, sw.Elapsed, lines, ex); 42 | } 43 | } 44 | 45 | private string[] FinishStream(MemoryStream stream, StreamWriter writer) 46 | { 47 | writer.Flush(); 48 | stream.Seek(0, SeekOrigin.Begin); 49 | var reader = new StreamReader(stream); 50 | return Enumerate(reader).ToArray(); 51 | } 52 | 53 | private static Exception RunAction(Action action, int timeout) 54 | { 55 | Exception threadEx = null; 56 | var t = new Thread(() => 57 | { 58 | try 59 | { 60 | action(null); 61 | } 62 | catch (Exception e) 63 | { 64 | threadEx = e; 65 | } 66 | }); 67 | var timeoutEx = JoinWithTimeout(t, timeout); 68 | threadEx = timeoutEx ?? threadEx; 69 | return threadEx; 70 | } 71 | 72 | private static Exception JoinWithTimeout(Thread t, int timeout) 73 | { 74 | t.Start(); 75 | if (!t.Join(timeout)) 76 | { 77 | t.Abort(); 78 | return new TimeoutException(); 79 | } 80 | return null; 81 | } 82 | 83 | IEnumerable Enumerate(StreamReader reader) 84 | { 85 | string line; 86 | while ((line = reader.ReadLine()) != null) 87 | yield return line; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Utils/Enums.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | #region enum DivModResults 6 | 7 | /// 8 | /// divide results to return. 9 | /// 10 | [Flags] 11 | internal enum DivModResultFlags 12 | { 13 | /// 14 | /// Divident is returned. 15 | /// 16 | Div = 1, 17 | /// 18 | /// Remainder is returned. 19 | /// 20 | Mod = 2 21 | } 22 | 23 | #endregion enum DivModResults 24 | 25 | #region enum MultiplyMode 26 | 27 | /// 28 | /// Big integers multiply mode used in . 29 | /// 30 | public enum MultiplyMode 31 | { 32 | /// 33 | /// FHT (Fast Hartley Transform) is used for really big integers. 34 | /// Time estimate is O(n * log n). 35 | /// Default mode. 36 | /// 37 | AutoFht, 38 | /// 39 | /// Classic method is used. 40 | /// Time estimate is O(n ^ 2). 41 | /// 42 | Classic 43 | } 44 | 45 | #endregion enum MultiplyMode 46 | 47 | #region enum DivideMode 48 | 49 | /// 50 | /// Big integers divide mode used in . 51 | /// 52 | public enum DivideMode 53 | { 54 | /// 55 | /// Newton approximation algorithm is used for really big integers. 56 | /// Time estimate is same as for multiplication. 57 | /// Default mode. 58 | /// 59 | AutoNewton, 60 | /// 61 | /// Classic method is used. 62 | /// Time estimate is O(n ^ 2). 63 | /// 64 | Classic 65 | } 66 | 67 | #endregion enum DivideMode 68 | 69 | #region enum ParseMode 70 | 71 | /// 72 | /// Big integers parsing mode used in . 73 | /// 74 | public enum ParseMode 75 | { 76 | /// 77 | /// Fast method which uses divide-by-two approach and fast multiply to parse numbers. 78 | /// Time estimate is O(n * [log n]^2). 79 | /// Default mode. 80 | /// 81 | Fast, 82 | /// 83 | /// Classic method is used (using multiplication). 84 | /// Time estimate is O(n ^ 2). 85 | /// 86 | Classic 87 | } 88 | 89 | #endregion enum ParseMode 90 | 91 | #region enum ToStringMode 92 | 93 | /// 94 | /// Big integers to string conversion mode used in . 95 | /// 96 | public enum ToStringMode 97 | { 98 | /// 99 | /// Fast method which uses divide-by-two approach to convert numbers. 100 | /// Default mode. 101 | /// 102 | Fast, 103 | /// 104 | /// Classic method is used (using division). 105 | /// Time estimate is O(n ^ 2). 106 | /// 107 | Classic 108 | } 109 | 110 | #endregion enum ToStringMode 111 | } 112 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Parsers/Pow2Parser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace BooRunner.Tools 4 | { 5 | /// 6 | /// Provides special fast (with linear time) parsing if base is pow of 2. 7 | /// 8 | sealed internal class Pow2Parser : IParser 9 | { 10 | // Not needed in this implementation 11 | public BigInteger Parse(string value, uint numberBase, IDictionary charToDigits, bool checkFormat) 12 | { 13 | return null; 14 | } 15 | 16 | /// 17 | /// Parses provided string representation of object. 18 | /// 19 | /// Number as string. 20 | /// Index inside string from which to start. 21 | /// Index inside string on which to end. 22 | /// Number base. 23 | /// Char->digit dictionary. 24 | /// Resulting digits. 25 | /// Parsed integer length. 26 | public uint Parse(string value, int startIndex, int endIndex, uint numberBase, IDictionary charToDigits, uint[] digitsRes) 27 | { 28 | // Calculate length of input string 29 | int bitsInChar = Bits.Msb(numberBase); 30 | uint valueLength = (uint)(endIndex - startIndex + 1); 31 | ulong valueBitLength = (ulong)valueLength * (ulong)bitsInChar; 32 | 33 | // Calculate needed digits length and first shift 34 | uint digitsLength = (uint)(valueBitLength / Constants.DigitBitCount) + 1; 35 | uint digitIndex = digitsLength - 1; 36 | int initialShift = (int)(valueBitLength % Constants.DigitBitCount); 37 | 38 | // Probably correct digits length 39 | if (initialShift == 0) 40 | { 41 | --digitsLength; 42 | } 43 | 44 | // Do parsing in big cycle 45 | uint digit; 46 | for (int i = startIndex; i <= endIndex; ++i) 47 | { 48 | digit = StrRepHelper.GetDigit(charToDigits, value[i], numberBase); 49 | 50 | // Correct initial digit shift 51 | if (initialShift == 0) 52 | { 53 | // If shift is equals to zero then char is not on digit elemtns bounds, 54 | // so just go to the previous digit 55 | initialShift = Constants.DigitBitCount - bitsInChar; 56 | --digitIndex; 57 | } 58 | else 59 | { 60 | // Here shift might be negative, but it's okay 61 | initialShift -= bitsInChar; 62 | } 63 | 64 | // Insert new digit in correct place 65 | digitsRes[digitIndex] |= initialShift < 0 ? digit >> -initialShift : digit << initialShift; 66 | 67 | // In case if shift was negative we also must modify previous digit 68 | if (initialShift < 0) 69 | { 70 | initialShift += Constants.DigitBitCount; 71 | digitsRes[--digitIndex] |= digit << initialShift; 72 | } 73 | } 74 | 75 | if (digitsRes[digitsLength - 1] == 0) 76 | { 77 | --digitsLength; 78 | } 79 | return digitsLength; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/StringConverters/Pow2StringConverter.cs: -------------------------------------------------------------------------------- 1 | namespace BooRunner.Tools 2 | { 3 | /// 4 | /// Provides special fast (with linear time) ToString converting if base is pow of 2. 5 | /// 6 | sealed internal class Pow2StringConverter : IStringConverter 7 | { 8 | // Not needed in this implementation 9 | public string ToString(BigInteger intX, uint numberBase, char[] alphabet) 10 | { 11 | return null; 12 | } 13 | 14 | /// 15 | /// Converts digits from internal representaion into given base. 16 | /// 17 | /// Big integer digits. 18 | /// Big integer length. 19 | /// Base to use for output. 20 | /// Calculated output length (will be corrected inside). 21 | /// Conversion result (later will be transformed to string). 22 | public uint[] ToString(uint[] digits, uint length, uint numberBase, ref uint outputLength) 23 | { 24 | // Calculate real output length 25 | int bitsInChar = Bits.Msb(numberBase); 26 | ulong digitsBitLength = (ulong)(length - 1) * Constants.DigitBitCount + (ulong)Bits.Msb(digits[length - 1]) + 1UL; 27 | uint realOutputLength = (uint)(digitsBitLength / (ulong)bitsInChar); 28 | if (digitsBitLength % (ulong)bitsInChar != 0) 29 | { 30 | ++realOutputLength; 31 | } 32 | 33 | // Prepare shift variables 34 | int nextDigitShift = Constants.DigitBitCount - bitsInChar; // after this shift next digit must be used 35 | int initialShift = 0; 36 | 37 | // We will also need bitmask for copying digits 38 | uint digitBitMask = numberBase - 1; 39 | 40 | // Create an output array for storing of number in other base 41 | uint[] outputArray = new uint[realOutputLength]; 42 | 43 | // Walk thru original digits and fill output 44 | uint outputDigit; 45 | for (uint outputIndex = 0, digitIndex = 0; outputIndex < realOutputLength; ++outputIndex) 46 | { 47 | // Get part of current digit 48 | outputDigit = digits[digitIndex] >> initialShift; 49 | 50 | // Maybe we need to go to the next digit 51 | if (initialShift >= nextDigitShift) 52 | { 53 | // Go to the next digit 54 | ++digitIndex; 55 | 56 | // Maybe we also need a part of the next digit 57 | if (initialShift != nextDigitShift && digitIndex < length) 58 | { 59 | outputDigit |= digits[digitIndex] << (Constants.DigitBitCount - initialShift); 60 | } 61 | 62 | // Modify shift so that it will be valid for the next digit 63 | initialShift = (initialShift + bitsInChar) % Constants.DigitBitCount; 64 | } 65 | else 66 | { 67 | // Modify shift as usual 68 | initialShift += bitsInChar; 69 | } 70 | 71 | // Write masked result to the output 72 | outputArray[outputIndex] = outputDigit & digitBitMask; 73 | } 74 | 75 | outputLength = realOutputLength; 76 | return outputArray; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /145.boo: -------------------------------------------------------------------------------- 1 | /* 2 | We'll split this problem by the number of digits. 3 | 4 | Almost every digit have another associated digit that we call a pair. 12345's 5 | reverse is 54321. So (1,5), (4,2) (3,3) as groups of numbers. Please note that 6 | if a pair sums more than 9, we must treat the carry. Every carry comes in pairs, 7 | as the numbers. 33337+73333 will generate two carries for the same pair, for 8 | example. Note also that a carry always affects two different pairs, as it goes 9 | always from right to left. 10 | 11 | So, if you have ABCDE+EDCBA, a carry with B+D will affect either C+C and A+E, 12 | but only one of them, that's why 5 digit solutions cannot exist. 13 | 14 | Essentially, we have, 2 kinds of numbers, odd and even. 15 | 16 | The even are easy, as the carries always goes in pairs, they are the most 17 | affected, because there is no central piece to to deposit the carry from the 18 | right half. So, all their pairs must sum less than 10 and be odd. The outer 19 | digits must also be different of 0 (because it must have exactly n digits). 20 | 20 possible pairs in outer numbers, 30 in the inner. Final formula: 21 | 22 | 20*30^((n-1)/2) 23 | 24 | The odd are a little more complicated. The center is always even, so we must 25 | force a carry from nearest digit of the right side. But it'll cause a carry on 26 | the nearest digit on the left side, and it is dangerous. We must play with odd 27 | and even pairs to make this happen. I mean, we must have always one non-carry 28 | even pair to deposit the carry odd pair that comes before. But there's one 29 | problem. But if the sides have even number of digits, we have a number of type: 30 | 31 | 32 | EOEO C OEOE 33 | 34 | Can you spot that if we have pair-digit sides, we cannot make the center-nearest 35 | digit to be odd without making the outer digits to be even? So, the least 36 | significant digit will end up even. If we make the inverse: 37 | 38 | OEOE C EOEO 39 | 40 | This way, C will never get the carry and will endup as even. 41 | 42 | So, we can infer that for 2(2k)+1 there is no possible solution, but we can 43 | focus on 2(2k)+3, like: 44 | 45 | OEOEO C OEOEO 46 | 47 | For this to happen, like said before, the center must receive carry from the 48 | right side. But it should not carry. All odd pairs must carry and all even 49 | pairs must not carry. For odd sum with carry, 20 possibilities, for even sum 50 | without carry, 25 possibilities. The outer pair must be odd and with carry, but 51 | different of 0 (to be n-digit). 20 possibilities, as the 2n solution. The center 52 | must only not carry, as it is the same number twice, we have a 5 (0..4). 53 | 54 | So at the end, we have 55 | 56 | 20 * 5 * (20 * 25) ^ k or 57 | 20 * 5 * (20 * 25) ^ (n/4) 58 | */ 59 | 60 | import System 61 | import System.Linq.Enumerable 62 | 63 | def solution_for(n as int): 64 | if n%2 == 0: return 20*30**((n-1)/2) 65 | if n%4 == 1: return 0 66 | if n%4 == 3: return 20*5*(20*25)**(n/4) 67 | 68 | answer = range(1,10).Sum(solution_for) 69 | print answer 70 | assert answer == 608720 -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/OpHelpers/StrRepHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using BooEulerTool.Tools.IntX.Utils; 4 | 5 | namespace BooRunner.Tools 6 | { 7 | /// 8 | /// Helps to work with string representations. 9 | /// 10 | static internal class StrRepHelper 11 | { 12 | /// 13 | /// Returns digit for given char. 14 | /// 15 | /// Char->digit dictionary. 16 | /// Char which represents big integer digit. 17 | /// String representation number base. 18 | /// Digit. 19 | /// is not in valid format. 20 | static public uint GetDigit(IDictionary charToDigits, char ch, uint numberBase) 21 | { 22 | if (charToDigits == null) 23 | { 24 | throw new ArgumentNullException("charToDigits"); 25 | } 26 | 27 | // Try to identify this digit 28 | uint digit; 29 | if (!charToDigits.TryGetValue(ch, out digit)) 30 | { 31 | throw new FormatException(Strings.ParseInvalidChar); 32 | } 33 | if (digit >= numberBase) 34 | { 35 | throw new FormatException(Strings.ParseTooBigDigit); 36 | } 37 | return digit; 38 | } 39 | 40 | /// 41 | /// Verfies string alphabet provider by user for validity. 42 | /// 43 | /// Alphabet. 44 | /// String representation number base. 45 | static public void AssertAlphabet(string alphabet, uint numberBase) 46 | { 47 | if (alphabet == null) 48 | { 49 | throw new ArgumentNullException("alphabet"); 50 | } 51 | 52 | // Ensure that alphabet has enough characters to represent numbers in given base 53 | if (alphabet.Length < numberBase) 54 | { 55 | throw new ArgumentException(string.Format(Strings.AlphabetTooSmall, numberBase), "alphabet"); 56 | } 57 | 58 | // Ensure that all the characters in alphabet are unique 59 | char[] sortedChars = alphabet.ToCharArray(); 60 | Array.Sort(sortedChars); 61 | for (int i = 0; i < sortedChars.Length; i++) 62 | { 63 | if (i > 0 && sortedChars[i] == sortedChars[i - 1]) 64 | { 65 | throw new ArgumentException(Strings.AlphabetRepeatingChars, "alphabet"); 66 | } 67 | } 68 | } 69 | 70 | /// 71 | /// Generates char->digit dictionary from alphabet. 72 | /// 73 | /// Alphabet. 74 | /// String representation number base. 75 | /// Char->digit dictionary. 76 | static public IDictionary CharDictionaryFromAlphabet(string alphabet, uint numberBase) 77 | { 78 | AssertAlphabet(alphabet, numberBase); 79 | Dictionary charToDigits = new Dictionary((int)numberBase); 80 | for (int i = 0; i < numberBase; i++) 81 | { 82 | charToDigits.Add(alphabet[i], (uint)i); 83 | } 84 | return charToDigits; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Dividers/IDivider.cs: -------------------------------------------------------------------------------- 1 | namespace BooRunner.Tools 2 | { 3 | /// 4 | /// Divider class interface. 5 | /// 6 | internal interface IDivider 7 | { 8 | /// 9 | /// Divides one by another. 10 | /// 11 | /// First big integer. 12 | /// Second big integer. 13 | /// Remainder big integer. 14 | /// Which operation results to return. 15 | /// Divident big integer. 16 | BigInteger DivMod(BigInteger int1, BigInteger int2, out BigInteger modRes, DivModResultFlags resultFlags); 17 | 18 | /// 19 | /// Divides two big integers. 20 | /// Also modifies and (it will contain remainder). 21 | /// 22 | /// First big integer digits. 23 | /// Buffer for first big integer digits. May also contain remainder. Can be null - in this case it's created if necessary. 24 | /// First big integer length. 25 | /// Second big integer digits. 26 | /// Buffer for second big integer digits. Only temporarily used. Can be null - in this case it's created if necessary. 27 | /// Second big integer length. 28 | /// Resulting big integer digits. 29 | /// Which operation results to return. 30 | /// Big integers comparsion result (pass -2 if omitted). 31 | /// Resulting big integer length. 32 | uint DivMod( 33 | uint[] digits1, 34 | uint[] digitsBuffer1, 35 | ref uint length1, 36 | uint[] digits2, 37 | uint[] digitsBuffer2, 38 | uint length2, 39 | uint[] digitsRes, 40 | DivModResultFlags resultFlags, 41 | int cmpResult); 42 | 43 | /// 44 | /// Divides two big integers. 45 | /// Also modifies and (it will contain remainder). 46 | /// 47 | /// First big integer digits. 48 | /// Buffer for first big integer digits. May also contain remainder. 49 | /// First big integer length. 50 | /// Second big integer digits. 51 | /// Buffer for second big integer digits. Only temporarily used. 52 | /// Second big integer length. 53 | /// Resulting big integer digits. 54 | /// Which operation results to return. 55 | /// Big integers comparsion result (pass -2 if omitted). 56 | /// Resulting big integer length. 57 | unsafe uint DivMod( 58 | uint* digitsPtr1, 59 | uint* digitsBufferPtr1, 60 | ref uint length1, 61 | uint* digitsPtr2, 62 | uint* digitsBufferPtr2, 63 | uint length2, 64 | uint* digitsResPtr, 65 | DivModResultFlags resultFlags, 66 | int cmpResult); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /tools/src/BooRunner/RunnerResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Reflection; 6 | using System.IO; 7 | 8 | namespace BooEulerTool 9 | { 10 | public class RunnerResult 11 | { 12 | string file; 13 | Exception exception; 14 | string[] lines; 15 | TimeSpan? elapsed; 16 | 17 | public TimeSpan Elapsed { get { return elapsed ?? TimeSpan.Zero; } } 18 | public Exception Exception { get { return exception; } } 19 | 20 | public bool HasTime { get { return elapsed != null; } } 21 | public bool HasException { get { return exception != null; } } 22 | 23 | public string LastLine { get { return lines.LastOrDefault() ?? ""; } } 24 | public bool HasMoreThanOneLine { get { return lines.Length > 1; } } 25 | public int RecommendedWidth { get { return Path.GetFileName(file).Length + 1; } } 26 | 27 | 28 | public RunnerResult(string file) : this(file, null) { } 29 | public RunnerResult(string file, Exception exception) : this(file, null, new string[0], exception) { } 30 | public RunnerResult(string file, TimeSpan? elapsed, string[] lines, Exception exception) 31 | { 32 | this.file = file; 33 | this.lines = lines; 34 | 35 | while (exception is TargetInvocationException) 36 | exception = exception.InnerException; 37 | 38 | this.exception = exception; 39 | this.elapsed = elapsed; 40 | } 41 | 42 | public RunnerResult PrintFile(int columns) 43 | { 44 | Console.ForegroundColor = ConsoleColor.Gray; 45 | Console.Write("{0,-" + columns + "}", Path.GetFileName(file)); 46 | return this; 47 | } 48 | 49 | public RunnerResult PrintResult() 50 | { 51 | if (HasTime) 52 | Console.Write(" {0,6}ms", (long)Elapsed.TotalMilliseconds); 53 | 54 | if (HasException) 55 | { 56 | Console.ForegroundColor = ConsoleColor.Red; 57 | Console.Write(" ({0}) {1}: {2}", LastLine, Exception.GetType().Name, Exception.Message); 58 | } 59 | else 60 | { 61 | Console.Write(" {0}", LastLine); 62 | Console.ForegroundColor = ConsoleColor.Yellow; 63 | Console.Write(" {0}", HasMoreThanOneLine ? "(+)" : ""); 64 | } 65 | Console.WriteLine(new string(' ', Console.WindowWidth - Console.CursorLeft - 1)); 66 | Console.ForegroundColor = ConsoleColor.Gray; 67 | return this; 68 | } 69 | 70 | public RunnerResult RunWith(BooEulerCompiler compiler, TimeoutRunner runner) 71 | { 72 | try 73 | { 74 | return runner.Run(file, compiler.Compile(file)); 75 | } 76 | catch (Exception e) 77 | { 78 | return new RunnerResult(file, e); 79 | } 80 | } 81 | 82 | public RunnerResult PrintSilent() 83 | { 84 | if (HasException) 85 | Console.Error.Write("F"); 86 | else 87 | Console.Error.Write("."); 88 | return this; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tools/src/BooRunner/Tools/IntX/Multipliers/MultiplierBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using BooEulerTool.Tools.IntX.Utils; 3 | 4 | namespace BooRunner.Tools 5 | { 6 | /// 7 | /// Base class for multipliers. 8 | /// Contains default implementation of multiply operation over instances. 9 | /// 10 | abstract internal class MultiplierBase : IMultiplier 11 | { 12 | /// 13 | /// Multiplies two big integers. 14 | /// 15 | /// First big integer. 16 | /// Second big integer. 17 | /// Resulting big integer. 18 | /// or is a null reference. 19 | /// or is too big for multiply operation. 20 | virtual public BigInteger Multiply(BigInteger int1, BigInteger int2) 21 | { 22 | // Exceptions 23 | if (ReferenceEquals(int1, null)) 24 | { 25 | throw new ArgumentNullException("int1", Strings.CantBeNull); 26 | } 27 | else if (ReferenceEquals(int2, null)) 28 | { 29 | throw new ArgumentNullException("int2", Strings.CantBeNull); 30 | } 31 | 32 | // Special behavior for zero cases 33 | if (int1._length == 0 || int2._length == 0) return new BigInteger(); 34 | 35 | // Get new big integer length and check it 36 | ulong newLength = (ulong)int1._length + int2._length; 37 | if (newLength >> 32 != 0) 38 | { 39 | throw new ArgumentException(Strings.IntegerTooBig); 40 | } 41 | 42 | // Create resulting big int 43 | BigInteger newInt = new BigInteger((uint)newLength, int1._negative ^ int2._negative); 44 | 45 | // Perform actual digits multiplication 46 | newInt._length = Multiply(int1._digits, int1._length, int2._digits, int2._length, newInt._digits); 47 | 48 | // Normalization may be needed 49 | newInt.TryNormalize(); 50 | 51 | return newInt; 52 | } 53 | 54 | /// 55 | /// Multiplies two big integers represented by their digits. 56 | /// 57 | /// First big integer digits. 58 | /// First big integer real length. 59 | /// Second big integer digits. 60 | /// Second big integer real length. 61 | /// Where to put resulting big integer. 62 | /// Resulting big integer real length. 63 | virtual unsafe public uint Multiply(uint[] digits1, uint length1, uint[] digits2, uint length2, uint[] digitsRes) 64 | { 65 | fixed (uint* digitsPtr1 = digits1, digitsPtr2 = digits2, digitsResPtr = digitsRes) 66 | { 67 | return Multiply(digitsPtr1, length1, digitsPtr2, length2, digitsResPtr); 68 | } 69 | } 70 | 71 | /// 72 | /// Multiplies two big integers using pointers. 73 | /// 74 | /// First big integer digits. 75 | /// First big integer length. 76 | /// Second big integer digits. 77 | /// Second big integer length. 78 | /// Resulting big integer digits. 79 | /// Resulting big integer length. 80 | abstract unsafe public uint Multiply(uint* digitsPtr1, uint length1, uint* digitsPtr2, uint length2, uint* digitsResPtr); 81 | } 82 | } 83 | --------------------------------------------------------------------------------