├── 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 |
--------------------------------------------------------------------------------