commit 198b8d0fd3632dbbd649ca8f732e4579e76fb4da Author: Yann Esposito (Yogsototh) Date: Tue May 31 17:31:13 2011 +0200 Initial submit diff --git a/002.rb b/002.rb new file mode 100644 index 0000000..ae1c6b0 --- /dev/null +++ b/002.rb @@ -0,0 +1,24 @@ +def fib (n) + return 1 if n < 2 + x=y=i=1 + while i < n + z = x+y + x = y + y = z + i+=1 + end + return z +end + +j=1 +sum=0 +x=fib(1) +while x<4000000 + x = fib(j) + if x%2 == 0 + sum += x + end + j += 1 +end + +puts sum diff --git a/003.rb b/003.rb new file mode 100644 index 0000000..3eb87fa --- /dev/null +++ b/003.rb @@ -0,0 +1,13 @@ +def prime_factor(x) + i=2 + while i<=Math.sqrt(x) + if x % i == 0 + return [i] << prime_factor( x / i ) + end + i += 1 + end + return [x] +end + +puts prime_factor(600851475143) +# puts prime_factor(13195) diff --git a/004.rb b/004.rb new file mode 100644 index 0000000..6794ba5 --- /dev/null +++ b/004.rb @@ -0,0 +1,19 @@ +def palindrome + palin=[] + x=999 + while x>100 + y=999 + while y>x + z=x*y + s=z.to_s + if s == s.reverse + palin <<= s + end + y -= 1 + end + x -= 1 + end + palin.sort +end + +puts palindrome diff --git a/005.rb b/005.rb new file mode 100644 index 0000000..5663fd7 --- /dev/null +++ b/005.rb @@ -0,0 +1,23 @@ +def check(n) + (2..20).each do |x| + return false if n % x != 0 + end + return true +end + +def prime_factor(x) + i=2 + while i<= Math.sqrt(x) + if x%i == 0 + if check(x/i) + return prime_factor(x/i) + end + end + i += 1 + end + return x +end + +n=2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20 +puts n +puts prime_factor(n) diff --git a/006.rb b/006.rb new file mode 100644 index 0000000..b99f3e3 --- /dev/null +++ b/006.rb @@ -0,0 +1,17 @@ +def sum_of_square(n) + sum=0 + (1..n).each do |x| + sum+=x**2 + end + sum +end + +def square_of_sum(n) + sum=0 + (1..n).each do |x| + sum+=x + end + sum**2 +end + +puts square_of_sum(100) - sum_of_square(100) diff --git a/007.rb b/007.rb new file mode 100644 index 0000000..d15c38b --- /dev/null +++ b/007.rb @@ -0,0 +1,27 @@ +class NthPrime + def initialize + @t=[] + end + def is_prime(n) + @t.each do |x| + return false if n % x == 0 + end + return true + end + + def findXthPrime(x) + i=2 + while @t.length 5 + t=t[1..6] + end + mul=1 + t.each { |x| mul=mul*x } + if mul > max + max=mul + puts max + end +end +puts max diff --git a/009.rb b/009.rb new file mode 100644 index 0000000..e177cf4 --- /dev/null +++ b/009.rb @@ -0,0 +1,27 @@ +def check (a,b,c) + puts %{#{a} #{b} #{c} = #{a**2 + b**2 + c**2}} + return ( a**2 + b**2 == c**2 ) +end + +# a < b < c +a=1000 +b=0 +c=0 +while not check(c,b,a) + if c +#include +#include + +#define YES 1 +#define NO 0 + +int main(int argc, char *argv[]) { + int limit=2000000; + int i,m; + int crosslimit=sqrt(2000000); + char *sieve=(char *)malloc(sizeof(char)*limit); + double sum; + + for (i=0;i +#include + +#define YES 1 +#define NO 0 + +int t[300000]; +int tlen=0; + +char is_prime(int n) { + int i; + for (i=0; imax + max=prod + end + end + # print "\n" + end +end + +# Vertical +(0..matrix.length-size).each do |ligne| + (0..(matrix[ligne].length - 1)).each do |col| + prod=1 + (0..size-1).each do |i| + prod = prod * matrix[ligne+i][col] + # print matrix[ligne][col+i].to_s + " " + if prod>max + max=prod + end + end + end +end + +# Diagonal positive +(0..matrix.length-size).each do |ligne| + (0..(matrix[ligne].length - size)).each do |col| + prod=1 + (0..size-1).each do |i| + prod = prod * matrix[ligne+i][col+i] + # print matrix[ligne][col+i].to_s + " " + if prod>max + max=prod + end + end + end +end + +# Diagonal negative +(0..matrix.length-size).each do |ligne| + (size..(matrix[ligne].length - 1)).each do |col| + prod=1 + (0..size-1).each do |i| + prod = prod * matrix[ligne+i][col-i] + # print matrix[ligne][col+i].to_s + " " + if prod>max + max=prod + end + end + end +end + +puts max diff --git a/012.rb b/012.rb new file mode 100644 index 0000000..54fe7f8 --- /dev/null +++ b/012.rb @@ -0,0 +1,157 @@ +# The sequence of triangle numbers is generated by adding the natural numbers. So the 7^(th) triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be: +# +# 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... +# +# Let us list the factors of the first seven triangle numbers: +# +# 1: 1 +# 3: 1,3 +# 6: 1,2,3,6 +# 10: 1,2,5,10 +# 15: 1,3,5,15 +# 21: 1,3,7,21 +# 28: 1,2,4,7,14,28 +# +# We can see that 28 is the first triangle number to have over five divisors. +# +# What is the value of the first triangle number to have over five hundred divisors? +# +# ---- +# +# k = n(n+1)/2 +# p != 2 && p|n => p|k +# p != 2 && p|n+1 => p|k +# +# p|k => p|n v p|n+1 +# +# ex: k=1+2+3+4+5+6+7 = 7x8/2 = 7*2^2 => 1, 2,2^2,7,2*7, 2*2*7 +# all possible combinations +# +# 0, {2}, {7}, {2,2}, {2,7}, {2,2,7} +# +# see : https://secure.wikimedia.org/wikipedia/en/wiki/Multiset +# for and explanation of multiset coefficients +# +# Méthode: 1 trouver la decomposition en nombre premiers de n puis de n+1 +# enlever une puissance de deux à celui des deux qui est pair +# +# puis le nombre d'élément est une combinaison +# +# + +number=500 +nbprimes=200000 + +class PrimeGenerator + attr_accessor :limit + attr_accessor :primes + + def initialize(limit=100000) + @limit=limit + self.generate + end + + def generate + crosslimit=Math.sqrt(limit); + sieve=[0]*limit; + i=0; + while in + + j=1 # powerfactor + while ( n % (p**j) == 0 ) + j+=1 + end + res[i]=j-1 + + i+=1 + end + return res +end + +def nb_multi_subset( multiset ) + nb=1 + multiset.each do |n| + nb *= n+1 + end + return nb +end + +def nbdiv(n) + if n%2 == 0 + x=n/2 + y=n+1 + else + x=n + y=(n+1)/2 + end + + res=decomposition_prime(x) + res2=decomposition_prime(y) + + # puts "==" + # puts x + # puts res.to_s + # puts y + # puts res2.to_s + # puts "==" + + i=0 + while i= number + notfound=false + break + end + n+=1 +end +puts n*(n+1)/2 diff --git a/013.rb b/013.rb new file mode 100644 index 0000000..844f00f --- /dev/null +++ b/013.rb @@ -0,0 +1,109 @@ +data=%{37107287533902102798797998220837590246510135740250 +46376937677490009712648124896970078050417018260538 +74324986199524741059474233309513058123726617309629 +91942213363574161572522430563301811072406154908250 +23067588207539346171171980310421047513778063246676 +89261670696623633820136378418383684178734361726757 +28112879812849979408065481931592621691275889832738 +44274228917432520321923589422876796487670272189318 +47451445736001306439091167216856844588711603153276 +70386486105843025439939619828917593665686757934951 +62176457141856560629502157223196586755079324193331 +64906352462741904929101432445813822663347944758178 +92575867718337217661963751590579239728245598838407 +58203565325359399008402633568948830189458628227828 +80181199384826282014278194139940567587151170094390 +35398664372827112653829987240784473053190104293586 +86515506006295864861532075273371959191420517255829 +71693888707715466499115593487603532921714970056938 +54370070576826684624621495650076471787294438377604 +53282654108756828443191190634694037855217779295145 +36123272525000296071075082563815656710885258350721 +45876576172410976447339110607218265236877223636045 +17423706905851860660448207621209813287860733969412 +81142660418086830619328460811191061556940512689692 +51934325451728388641918047049293215058642563049483 +62467221648435076201727918039944693004732956340691 +15732444386908125794514089057706229429197107928209 +55037687525678773091862540744969844508330393682126 +18336384825330154686196124348767681297534375946515 +80386287592878490201521685554828717201219257766954 +78182833757993103614740356856449095527097864797581 +16726320100436897842553539920931837441497806860984 +48403098129077791799088218795327364475675590848030 +87086987551392711854517078544161852424320693150332 +59959406895756536782107074926966537676326235447210 +69793950679652694742597709739166693763042633987085 +41052684708299085211399427365734116182760315001271 +65378607361501080857009149939512557028198746004375 +35829035317434717326932123578154982629742552737307 +94953759765105305946966067683156574377167401875275 +88902802571733229619176668713819931811048770190271 +25267680276078003013678680992525463401061632866526 +36270218540497705585629946580636237993140746255962 +24074486908231174977792365466257246923322810917141 +91430288197103288597806669760892938638285025333403 +34413065578016127815921815005561868836468420090470 +23053081172816430487623791969842487255036638784583 +11487696932154902810424020138335124462181441773470 +63783299490636259666498587618221225225512486764533 +67720186971698544312419572409913959008952310058822 +95548255300263520781532296796249481641953868218774 +76085327132285723110424803456124867697064507995236 +37774242535411291684276865538926205024910326572967 +23701913275725675285653248258265463092207058596522 +29798860272258331913126375147341994889534765745501 +18495701454879288984856827726077713721403798879715 +38298203783031473527721580348144513491373226651381 +34829543829199918180278916522431027392251122869539 +40957953066405232632538044100059654939159879593635 +29746152185502371307642255121183693803580388584903 +41698116222072977186158236678424689157993532961922 +62467957194401269043877107275048102390895523597457 +23189706772547915061505504953922979530901129967519 +86188088225875314529584099251203829009407770775672 +11306739708304724483816533873502340845647058077308 +82959174767140363198008187129011875491310547126581 +97623331044818386269515456334926366572897563400500 +42846280183517070527831839425882145521227251250327 +55121603546981200581762165212827652751691296897789 +32238195734329339946437501907836945765883352399886 +75506164965184775180738168837861091527357929701337 +62177842752192623401942399639168044983993173312731 +32924185707147349566916674687634660915035914677504 +99518671430235219628894890102423325116913619626622 +73267460800591547471830798392868535206946944540724 +76841822524674417161514036427982273348055556214818 +97142617910342598647204516893989422179826088076852 +87783646182799346313767754307809363333018982642090 +10848802521674670883215120185883543223812876952786 +71329612474782464538636993009049310363619763878039 +62184073572399794223406235393808339651327408011116 +66627891981488087797941876876144230030984490851411 +60661826293682836764744779239180335110989069790714 +85786944089552990653640447425576083659976645795096 +66024396409905389607120198219976047599490197230297 +64913982680032973156037120041377903785566085089252 +16730939319872750275468906903707539413042652315011 +94809377245048795150954100921645863754710598436791 +78639167021187492431995700641917969777599028300699 +15368713711936614952811305876380278410754449733078 +40789923115535562561142322423255033685442488917353 +44889911501440648020369068063960672322193204149535 +41503128880339536053299340368006977710650566631954 +81234880673210146739058568557934581403627822703280 +82616570773948327592232845941706525094512325230608 +22918802058777319719839450180888072429661980811197 +77158542502016545090413245809786882778948721859617 +72107838435069186155435662884062257473692284509516 +20849603980134001723930671666823555245252804609722 +53503534226472524250874054075591789781264330331690} + +numbers=data.split("\n").collect! { |x| x.to_i } + +sum=0 +numbers.each do |c| + sum+=c +end + +puts sum.to_s[0..9] diff --git a/014.rb b/014.rb new file mode 100644 index 0000000..027eeea --- /dev/null +++ b/014.rb @@ -0,0 +1,61 @@ +description=%{ + The following iterative sequence is defined for the set of positive integers: + + n → n/2 (n is even) + n → 3n + 1 (n is odd) + + Using the rule above and starting with 13, we generate the following sequence: + 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 + + It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1. + + Which starting number, under one million, produces the longest chain? + + NOTE: Once the chain starts the terms are allowed to go above one million. +} + +num=1000000 +$seq={} + +$seq[1]=1 + +def u(n) + # puts %{u(#{n})*} + if not $seq[n].nil? + # puts %{n=#{n} len=#{$seq[n]}*} + return $seq[n] + end + + if n%2 == 0 + $seq[n]=u(n/2)+1 + else + $seq[n]=u((3*n) + 1)+ 1 + end + # puts %{n=#{n} len=#{$seq[n]}} + return $seq[n] +end + +(1..num).each do |n| + # puts "====== u(#{n}) ========" + u(n) +end +max=0 +number=0 +$seq.each do |k,v| + if k<=1000000 and v>max + max=v + number=k + end +end + +x=number +while number != 1 do + puts number + if number%2 == 0 + number=number/2 + else + number=(3*number)+1 + end +end + +puts "First number = #{x}, length of sequence = #{max}" diff --git a/015.rb b/015.rb new file mode 100644 index 0000000..33b4c95 --- /dev/null +++ b/015.rb @@ -0,0 +1,60 @@ +descr=%{ + Starting in the top left corner of a 2×2 grid, there are 6 routes (without backtracking) to the bottom right corner. + + 1) 00 01 02 12 22 + 2) 00 01 11 12 22 + 3) 00 01 11 21 22 + 4) 00 10 11 12 22 + 5) 00 10 11 21 22 + 6) 00 10 20 21 22 + + How many routes are there through a 20×20 grid? +} + +reflexion=%# + coordinates at time t are (x_t,y_t) + We have: + 0 <= x_t <= n + 0 <= y_t <= n + x_{t+1} + y_{t+1} = x_t + y_t + 1 + x_{t+1} >= x_t + y_{t+1} >= y_t + + In order to have a computable recursive content, we need to extend + this reasonment to rectangles nxm. + + nb(0,n)=1 + nb(n,0)=1 + nb( 1,1 ) = nb(0,1) + nb(1,0) + + nb(n,m)=nb(m,n) +# + +number=20 +$mem=[] +(0..number).each do |i| + $mem <<= [] + (0..number).each do |j| + $mem[i] <<= 0 + end +end + +def nb(n,m) + if (m>n) + tmp=n + n=m + m=tmp + end + if $mem[n][m] != 0 + return $mem[n][m] + end + if n==0 or m==0 + $mem[n][m]=1 + return 1 + end + $mem[n][m] = nb(n-1,m) + nb(n,m-1) + return $mem[n][m] +end + +puts nb(number,number) +p $mem diff --git a/017.rb b/017.rb new file mode 100644 index 0000000..2a19fbb --- /dev/null +++ b/017.rb @@ -0,0 +1,85 @@ +descr=%{ + If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total. + + If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used? + + NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of "and" when writing out numbers is in compliance with British usage. +} + +reflexion=%{ + let n be the number of letter used to write number from 1 to 99 + then the number of letter used to write 1 to 1000 would be: + + one hundred and * n + two hundred and * n + ... + ninety nine hundred and * n + + that would be +} + +def write_tenth(name,n) + if n%10 == 0 + return name + else + return name + "-" + write_natural(n%10) + end +end + +def write_natural(n) + # print "write_natural: #{n}" + if n<100 + case n + when 1 then return "one" + when 2 then return "two" + when 3 then return "three" + when 4 then return "four" + when 5 then return "five" + when 6 then return "six" + when 7 then return "seven" + when 8 then return "eight" + when 9 then return "nine" + when 10 then return "ten" + when 11 then return "eleven" + when 12 then return "twelve" + when 13 then return "thirteen" + when 14 then return "fourteen" + when 15 then return "fifteen" + when 16..17 then return write_natural(n-10) + "teen" + when 18 then return "eighteen" + when 19 then return "nineteen" + when 20..29 then return write_tenth("twenty" , n) + when 30..39 then return write_tenth("thirty" , n) + when 40..49 then return write_tenth("forty" , n) + when 50..59 then return write_tenth("fifty" , n) + when 60..69 then return write_tenth("sixty" , n) + when 70..79 then return write_tenth("seventy", n) + when 80..89 then return write_tenth("eighty", n) + when 90..99 then return write_tenth("ninety" , n) + else return "" + end + elsif n<1000 + m=(n/100).floor + if n%100 == 0 + return write_natural(m) + " hundred" + else + return write_natural(m * 100) + " and " + write_natural( n % 100 ) + end + elsif n == 1000 + m=(n/1000).floor + if n%1000 == 0 + return write_natural((n/1000).floor) + " thousand " + else + return write_natural(m * 1000) + " and " + write_natural( n % 1000 ) + end + end +end + +res="" +(1..1000).each do |i| + print i.to_s+" " + puts write_natural(i) + res<<=write_natural(i) +end + +puts res.gsub(/[ -]/,"").length diff --git a/018.rb b/018.rb new file mode 100644 index 0000000..f731119 --- /dev/null +++ b/018.rb @@ -0,0 +1,88 @@ +description=%{ + By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23. + + 3 + 7 4 + 2 4 6 + 8 5 9 3 + + That is, 3 + 7 + 4 + 9 = 23. + + Find the maximum total from top to bottom of the triangle below: + + 75 + 95 64 + 17 47 82 + 18 35 87 10 + 20 04 82 47 65 + 19 01 23 75 03 34 + 88 02 77 73 07 63 67 + 99 65 04 28 06 16 70 92 + 41 41 26 56 83 40 80 70 33 + 41 48 72 33 47 32 37 16 94 29 + 53 71 44 65 25 43 91 52 97 51 14 + 70 11 33 28 77 73 17 78 39 68 17 57 + 91 71 52 38 17 14 91 43 58 50 27 29 48 + 63 66 04 68 89 53 67 30 73 16 69 87 40 31 + 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23 + + NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, Problem 67, is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o) + +} + +reflexion=%{ + use bottom to top method + + z + x y chose max(x,y) path for z, new triangle = z + max(x,y) +} + +data_test=%{3 +7 4 +2 4 6 +8 5 9 3} +data=%{75 +95 64 +17 47 82 +18 35 87 10 +20 04 82 47 65 +19 01 23 75 03 34 +88 02 77 73 07 63 67 +99 65 04 28 06 16 70 92 +41 41 26 56 83 40 80 70 33 +41 48 72 33 47 32 37 16 94 29 +53 71 44 65 25 43 91 52 97 51 14 +70 11 33 28 77 73 17 78 39 68 17 57 +91 71 52 38 17 14 91 43 58 50 27 29 48 +63 66 04 68 89 53 67 30 73 16 69 87 40 31 +04 62 98 27 23 09 70 98 73 93 38 53 60 04 23} + +triangle=data.split("\n").collect! { |line| line.split(" ").collect! {|n| n.to_i} }.reverse! + +p triangle + + +def max(x,y) + return x if x>y + return y +end + +nbline=0 +triangle.each do |line| + if nbline==0 + nbline +=1 + next + end + col=0 + line.each do |n| + triangle[nbline][col] = + n + max( triangle[nbline-1][col], + triangle[nbline-1][col+1] ) + col +=1 + end + nbline+=1 + puts '===' + p triangle +end +p triangle +puts triangle[-1][0] diff --git a/019.rb b/019.rb new file mode 100644 index 0000000..1db8b9a --- /dev/null +++ b/019.rb @@ -0,0 +1,44 @@ +descr=%{ +You are given the following information, +but you may prefer to do some research for yourself. + + * 1 Jan 1900 was a Monday. + * Thirty days has September, + April, June and November. + All the rest have thirty-one, + Saving February alone, + Which has twenty-eight, rain or shine. + And on leap years, twenty-nine. + * A leap year occurs on any year evenly divisible by 4, + but not on a century unless it is divisible by 400. + +How many Sundays fell on the first of the month during the +twentieth century (1 Jan 1901 to 31 Dec 2000)? +} + +nbdaysbymonth=[31,28,31,30,31,30,31,31,30,31,30,31] + +# 0 Monday, ... , 6 Sunday +day_of_month=0 +nb_sunday=0 +(1900..2000).each do |year| + is_leap = ( year % 4 == 0 ) + if ( year % 100 == 0 ) && ( year % 400 != 0 ) + is_leap = false + end + if is_leap + nbdaysbymonth[1]=29 + else + nbdaysbymonth[1]=28 + end + (0..11).each do |month| + # puts "1st #{month+1}/#{year} = #{day_of_month}" + if day_of_month == 6 && year >= 1901 + puts "* #{month+1}/#{year}" + nb_sunday += 1 + end + day_of_month = ( day_of_month + nbdaysbymonth[month] ) % 7 + end +end + +puts nb_sunday diff --git a/020.rb b/020.rb new file mode 100644 index 0000000..5441dc3 --- /dev/null +++ b/020.rb @@ -0,0 +1,6 @@ +def fact(x) + return 1 if x<=1 + return x*fact(x-1) +end +puts fact(100).to_s.split("").collect! { |x| x.to_i }.inject(0) {|sum,v| sum+v} + diff --git a/021.rb b/021.rb new file mode 100644 index 0000000..67f88ac --- /dev/null +++ b/021.rb @@ -0,0 +1,32 @@ +descr=%{ + Let d(n) be defined as the sum of proper divisors of n (numbers less than n which divide evenly into n). + If d(a) = b and d(b) = a, where a ≠ b, then a and b are an amicable pair and each of a and b are called amicable numbers. + + For example, the proper divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110; therefore d(220) = 284. The proper divisors of 284 are 1, 2, 4, 71 and 142; so d(284) = 220. + + Evaluate the sum of all the amicable numbers under 10000. +} + +def d(n) + sum=0 + (1..n/2).each do |i| + if n % i == 0 + sum += i + end + end + return sum +end + +h={} +(1..10000).each do |n| + h[n]=d(n) +end + +sum=0 +h.each do |n,m| + if h[m] == n && n != m + puts "#{m}\t#{n}" + sum+=n + end +end +puts sum diff --git a/022.rb b/022.rb new file mode 100644 index 0000000..1790c7d --- /dev/null +++ b/022.rb @@ -0,0 +1,26 @@ +%{ + Using names.txt (right click and 'Save Link/Target As...'), a 46K text file containing over five-thousand first names, begin by sorting it into alphabetical order. Then working out the alphabetical value for each name, multiply this value by its alphabetical position in the list to obtain a name score. + + For example, when the list is sorted into alphabetical order, COLIN, which is worth 3 + 15 + 12 + 9 + 14 = 53, is the 938th name in the list. So, COLIN would obtain a score of 938 × 53 = 49714. + + What is the total of all the name scores in the file? +} + +v=File.read("names.txt") +list=v.sub(/\n/,'').gsub('"','').split(',').sort + +i=0 +sum=0 +list.each do |name| + i+=1 + val=0 + name.each_byte do |letter| + val += letter + 1 - 'A'[0] + end + score = val * i + sum+=score + puts "#{name} (#{i}) * #{val} = #{score}" +end + +puts sum + diff --git a/023.rb b/023.rb new file mode 100644 index 0000000..8a92cf2 --- /dev/null +++ b/023.rb @@ -0,0 +1,69 @@ +descr=%{ + A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number. + + A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n. + + As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit. + + Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers. +} + +def sum_of_divisors(n) + sum=1 + p=2 + while p**2 <= n and n>1 + if n % p == 0 + j=p**2 + n = n/p + while n%p == 0 + j = j*p + n = n / p + end + sum=sum*(j-1) + sum=sum / (p-1) + end + if p == 2 + p=3 + else + p=p+2 + end + end + if n>1 + sum *= n+1 + end + return sum +end + +def sum_of_proper_divisors(n) + return sum_of_divisors(n) - n +end + +abd_numbers=[] +is_abd={} +(1..28123).each do |n| + d=sum_of_proper_divisors(n) + if d>n + abd_numbers <<= n + is_abd[n]=d + end +end + +sum=0 +(1..28123).each do |n| + skip=false + abd_numbers.each do |i| + if i>=n + break + end + if not is_abd[ n-i ].nil? + skip=true + next + end + end + if skip + next + end + puts n + sum += n +end +puts sum diff --git a/024.rb b/024.rb new file mode 100644 index 0000000..79f3ad7 --- /dev/null +++ b/024.rb @@ -0,0 +1,36 @@ +descr=%{ + A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are: + + 012 021 102 120 201 210 + + What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9? +} + +numbers=[] +(0..9).each do |n| + numbers <<= n +end + +$nb = 0 +$target = 1000000 + +def permute( tab, pref) + if tab.length == 0 + $nb += 1 + if $nb % 10000 == 0 + puts %{#{$nb}: #{pref.join(" ")}} + end + if $nb == $target + puts %{RESULT: #{$nb}: #{pref.join(" ")}} + exit + end + return + end + tab.each do |e| + subtab=tab.clone + subtab.delete(e) + permute( subtab, pref + [e] ) + end +end + +permute( numbers,[] ) diff --git a/025.rb b/025.rb new file mode 100644 index 0000000..f2b44ff --- /dev/null +++ b/025.rb @@ -0,0 +1,38 @@ +descr=%{ + The Fibonacci sequence is defined by the recurrence relation: + + F_(n) = F_(n−1) + F_(n−2), where F_(1) = 1 and F_(2) = 1. + + Hence the first 12 terms will be: + + F_(1) = 1 + F_(2) = 1 + F_(3) = 2 + F_(4) = 3 + F_(5) = 5 + F_(6) = 8 + F_(7) = 13 + F_(8) = 21 + F_(9) = 34 + F_(10) = 55 + F_(11) = 89 + F_(12) = 144 + + The 12th term, F_(12), is the first term to contain three digits. + + What is the first term in the Fibonacci sequence to contain 1000 digits? +} + +n=3 +i=1 +j=1 +f=i+j +while f.to_s.length<1000 +# while n<5 + n+=1 + i=j + j=f + f=i+j + # puts %{#{n}, #{f}} +end +puts n diff --git a/026.rb b/026.rb new file mode 100644 index 0000000..11029b4 --- /dev/null +++ b/026.rb @@ -0,0 +1,62 @@ +descr=%{ + A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given: + + ^(1)/_(2) = 0.5 + ^(1)/_(3) = 0.(3) + ^(1)/_(4) = 0.25 + ^(1)/_(5) = 0.2 + ^(1)/_(6) = 0.1(6) + ^(1)/_(7) = 0.(142857) + ^(1)/_(8) = 0.125 + ^(1)/_(9) = 0.(1) + ^(1)/_(10) = 0.1 + + Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that ^(1)/_(7) has a 6-digit recurring cycle. + + Find the value of d < 1000 for which ^(1)/_(d) contains the longest recurring cycle in its decimal fraction part. +} + +reflexion=%{ + simulate the manual division + + 10 | 7 + 30 |----------- + 20 | 0,142... + ... +} + +def _rec_cycle_frac(n,m,rests,i) + return 0 if n==0 + # print "\t_rec_cycle_frac " + # p [n, m, rests, i] + + if n < m + rests[n*10]=i + return _rec_cycle_frac(n*10,m,rests,i+1) + end + + num=(n%m) * 10 + if not rests[num].nil? + # puts "[RES] not rest[#{num}].nil? => #{rests[num]}; #{i}-#{rests[num]}=#{i- rests[num]}" + return i - rests[num] + end + rests[num]=i + return _rec_cycle_frac( num, m, rests, i+1 ) +end + +def size_of_rec_cycle_of_frac(n,m) + return _rec_cycle_frac(n,m,{},0) +end + +max=0 +best=0 +(1..1000).each do |m| + n=size_of_rec_cycle_of_frac(1,m) + if n>max + best=m + max=n + end + puts "1/#{m}: #{n}" +end + +puts "#{best} #{max}" diff --git a/027.rb b/027.rb new file mode 100644 index 0000000..bd049cb --- /dev/null +++ b/027.rb @@ -0,0 +1,60 @@ +descr=%{ + Euler published the remarkable quadratic formula: + + n² + n + 41 + + It turns out that the formula will produce 40 primes for the consecutive values n = 0 to 39. However, when n = 40, 40^(2) + 40 + 41 = 40(40 + 1) + 41 is divisible by 41, and certainly when n = 41, 41² + 41 + 41 is clearly divisible by 41. + + Using computers, the incredible formula n² − 79n + 1601 was discovered, which produces 80 primes for the consecutive values n = 0 to 79. The product of the coefficients, −79 and 1601, is −126479. + + Considering quadratics of the form: + + n² + an + b, where |a| < 1000 and |b| < 1000 + + where |n| is the modulus/absolute value of n + e.g. |11| = 11 and |−4| = 4 + + Find the product of the coefficients, a and b, for the quadratic expression that produces the maximum number of primes for consecutive values of n, starting with n = 0. +} + +thoughts=%{ + compute a huge number of prime and test using it +} + +puts "read prime numbers" +prime=File.read('firsts_10MM_primes.txt').split.collect! { |i| i.to_i } +is_prime={} +prime.each do |p| + is_prime[p]=true +end + +puts "begin computation" + +max=0 +besta=0 +bestb=0 + +def is_prime_number(num,is_prime) + if num>10000000 + puts "may an error for #{num}" + end + return is_prime[num] +end + +(-1000..1000).each do |a| + (-1000..1000).each do |b| + n=0 + while is_prime_number( n**2 + a*n + b , is_prime) + n+=1 + end + if n>max + max=n + besta=a + bestb=b + puts "#{besta} #{bestb} => #{max}" + end + end +end + +puts "#{besta} #{bestb} => #{max}" +puts "product= #{besta * bestb}" diff --git a/028.rb b/028.rb new file mode 100644 index 0000000..6e077d5 --- /dev/null +++ b/028.rb @@ -0,0 +1,41 @@ +descr=%{ + Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is formed as follows: + + 21 22 23 24 25 + 20 7 8 9 10 + 19 6 1 2 11 + 18 5 4 3 12 + 17 16 15 14 13 + + It can be verified that the sum of the numbers on the diagonals is 101. + + What is the sum of the numbers on the diagonals in a 1001 by 1001 spiral formed in the same way? +} + +reflexion=%{ + We can remark: + + 1 + + + (1+2) + (1+2*2) + (1+3*2) + (1+4*2) + + // let x be the last calulcated number (1+4*2) + (x+4) + (x+2*4) + (x+3*4) + (x+4*4) + + // let y be the last calulcated number (x+4*4) + (y+6) + (y+2*6) + (y+3*6) + (y+4*6) + + ... +} + +size=1001 +max=size**2 +n=1 +sum=0 +step=2 +while n 9^4 + ... + 9^4 < 33000 + and as number is an exponential function depending on the number of digits and power function is less (in the end) than this function. For each n there is always a maximal value. + + now using the same reasonment for the power 5 we see the maximal value will have at most 6 digits (9^5 * 6 < 999999) +} + +pow=5 +list=[] +(10..1000000).each do |n| + sum=0 + n.to_s.each_byte do |b| + sum+=( b - "0"[0] )**pow + end + if n == sum + puts "#{n}" + list<<=n + end +end + +puts "Sum=" + list.inject(0) { |sum,x| sum+x }.to_s diff --git a/031.rb b/031.rb new file mode 100644 index 0000000..b0d5527 --- /dev/null +++ b/031.rb @@ -0,0 +1,40 @@ +descr=%{ +In England the currency is made up of pound, £, and pence, p, and there are eight coins in general circulation: + + 1p, 2p, 5p, 10p, 20p, 50p, £1 (100p) and £2 (200p). + +It is possible to make £2 in the following way: + + 1×£1 + 1×50p + 2×20p + 1×5p + 1×2p + 3×1p + +How many different ways can £2 be made using any number of coins? +} + +def _nb_case(n,choices) + # print "#{n}, " + # p choices + if n<0 + return 0 + end + if n==0 + return 1 + end + + sum=0 + subchoice=choices.clone + choices.each do |p| + break if p>n + sum += _nb_case(n-p, subchoice) + subchoice.shift + end + return sum +end + +def nb_case(n) + return _nb_case(n,[1,2,5,10,20,50,100,200]) +end + +(200..200).each do |n| + print "# #{n}: " + puts nb_case(n) +end diff --git a/032.rb b/032.rb new file mode 100644 index 0000000..9cccf4f --- /dev/null +++ b/032.rb @@ -0,0 +1,42 @@ +descr=%{ + We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital. + + The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital. + + Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital. + HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum. +} + +pand={} + +$numbers=%q(123456789).split('').sort + +def is_pandigital(str) + return str.split('').sort == $numbers +end + +(1..10000).each do |n| + (n..10000).each do |m| + str=n.to_s+m.to_s+(n*m).to_s + # puts "#{n} x #{m} = #{n*m}" + # puts str + if str.length > 9 + break + end + if str.length == 9 + if is_pandigital(str) + puts "# #{n*m}" + pand[n*m]=true + end + end + end +end + +sum=0 +puts "solution" +pand.each do |p,v| + puts p + sum+=p +end + +puts "Sum: " + sum.to_s diff --git a/033.rb b/033.rb new file mode 100644 index 0000000..9d34c8f --- /dev/null +++ b/033.rb @@ -0,0 +1,36 @@ +descr=%{ + The fraction ^(49)/_(98) is a curious fraction, as an inexperienced mathematician in attempting to simplify it may incorrectly believe that ^(49)/_(98) = ^(4)/_(8), which is correct, is obtained by cancelling the 9s. + + We shall consider fractions like, ^(30)/_(50) = ^(3)/_(5), to be trivial examples. + + There are exactly four non-trivial examples of this type of fraction, less than one in value, and containing two digits in the numerator and denominator. + + If the product of these four fractions is given in its lowest common terms, find the value of the denominator. +} + +# n/m +res=[] +(10..99).each do |n| + (n+1..99).each do |m| + next if n%10 == 0 and m%10 == 0 + next if n%11 == 0 and m%11 == 0 + nb_first=0 + n.to_s.split('').each do |c| + newn=c.to_i + nb_first+=1 + nb_second=0 + m.to_s.split('').each do |d| + nb_second += 1 + next if nb_first == nb_second + newm=d.to_i + if newm == 0 + next + end + if n.to_f/m == newn.to_f/newm + res <<= [n,m,newn,newm] + puts %{#{n}/#{m} = #{newn}/#{newm}} + end + end + end + end +end diff --git a/034.rb b/034.rb new file mode 100644 index 0000000..9959421 --- /dev/null +++ b/034.rb @@ -0,0 +1,45 @@ +descr=%{ + 145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145. + + Find the sum of all numbers which are equal to the sum of the factorial of their digits. + + Note: as 1! = 1 and 2! = 2 are not sums they are not included. +} + +thoughts=%{ + the difficulty remains in finding a maximum number after which + + n>N => n cannot be written as the sum of a factorial of its digits. + + the max is attained by number containing only 9 + + limit is obtained when: n*9! > 10^n +} + +def fact(n) + return 1 if n <= 1 + return n*fact(n-1) +end + + +def sum_of_facts_of_digits(n) + sum=0 + n.to_s.split('').collect { |i| sum += fact(i.to_i) } + return sum +end + +n=1 +while sum_of_facts_of_digits(('9'*n).to_i) > 10**n + n+=1 +end +n-=1 + +sum=0 +(10..10**n).each do |i| + if sum_of_facts_of_digits(i) == i + puts i + sum+=i + end +end + +puts "Solution: #{sum}" diff --git a/035.rb b/035.rb new file mode 100644 index 0000000..22e3b91 --- /dev/null +++ b/035.rb @@ -0,0 +1,39 @@ +descr=%{ + The number, 197, is called a circular prime because all rotations of the digits: 197, 971, and 719, are themselves prime. + + There are thirteen such primes below 100: 2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79, and 97. + + How many circular primes are there below one million? +} + +puts "Read primes" +primes=File.read("firsts_1MM_primes.txt").split().collect! { |p| p.to_i } +is_prime={} + +puts "Init datastructure" +primes.each do |p| + is_prime[p]=true +end + +puts "search circulars" +circular=[] +primes.each do |p| + arr=p.to_s.split('') + len=arr.length + number=arr.join('').to_i + i=0 + # puts "#{len} #{number} #{i}" + while i #{number}" + i+=1 + end + if i==len + puts "circular #{p}" + circular <<= p + end +end + +puts "NB: #{circular.length}" diff --git a/036.rb b/036.rb new file mode 100644 index 0000000..27cd0aa --- /dev/null +++ b/036.rb @@ -0,0 +1,16 @@ +descr=%{ + The decimal number, 585 = 1001001001_(2) (binary), is palindromic in both bases. + + Find the sum of all numbers, less than one million, which are palindromic in base 10 and base 2. + + (Please note that the palindromic number, in either base, may not include leading zeros.) +} +sum=0 +(0..1000000).each do |n| + if n.to_s == n.to_s.reverse && n.to_s(2) == n.to_s(2).reverse + sum+=n + puts n + end +end + +puts "\nSum: #{sum}" diff --git a/037.rb b/037.rb new file mode 100644 index 0000000..bc9bbf1 --- /dev/null +++ b/037.rb @@ -0,0 +1,55 @@ +descr=%{ + The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3. + + Find the sum of the only eleven primes that are both truncatable from left to right and right to left. + + NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes. +} + + +puts "Read primes" +primes=File.read("firsts_1MM_primes.txt").split().collect! { |p| p.to_i } +is_prime={} + +puts "Init datastructure" +primes.each do |p| + is_prime[p]=true +end + +puts "search truncatable left to right and right to left" +truncatable=[] +primes.each do |p| + # verify if it is truncatable + next if p<10 + # puts p + not_truncatable=false + str=p.to_s.split('') + while str.length > 1 + str.pop + num=str.join('').to_i + # puts "> #{num}" + if not is_prime[num] + not_truncatable=true + break + end + end + next if not_truncatable + str=p.to_s.split('') + while str.length > 1 + str.shift() + num=str.join('').to_i + # puts "> #{num}" + if not is_prime[num] + not_truncatable=true + break + end + end + next if not_truncatable + puts "Trunkatable: #{p}" + truncatable<<=p + if truncatable.length == 11 + break + end +end + +puts "NB: #{truncatable.inject(0){|sum,n| sum+n}}" diff --git a/038.rb b/038.rb new file mode 100644 index 0000000..cd998ef --- /dev/null +++ b/038.rb @@ -0,0 +1,38 @@ +descr=%{ +Take the number 192 and multiply it by each of 1, 2, and 3: + + 192 × 1 = 192 + 192 × 2 = 384 + 192 × 3 = 576 + +By concatenating each product we get the 1 to 9 pandigital, 192384576. We will call 192384576 the concatenated product of 192 and (1,2,3) + +The same can be achieved by starting with 9 and multiplying by 1, 2, 3, 4, and 5, giving the pandigital, 918273645, which is the concatenated product of 9 and (1,2,3,4,5). + +What is the largest 1 to 9 pandigital 9-digit number that can be formed as the concatenated product of an integer with (1,2, ... , n) where n > 1? +} + +$numbers=%q(123456789).split('').sort +def is_pandigital(str) + return str.split('').sort == $numbers +end + +best=(123456789) +(2..10).each do |n| + concat_prod="" + base=1 + while concat_prod.length < 10 + concat_prod="" + (1..n).each do |i| + concat_prod <<= (base*i).to_s + end + if is_pandigital(concat_prod) + puts %{base=#{base} n=#{n} #{concat_prod}} + if concat_prod.to_i > best + best=concat_prod.to_i + puts %{* base=#{base} n=#{n} #{best}} + end + end + base += 1 + end +end diff --git a/039.rb b/039.rb new file mode 100644 index 0000000..e66fd9d --- /dev/null +++ b/039.rb @@ -0,0 +1,42 @@ +descr=%# + If p is the perimeter of a right angle triangle with integral length sides, {a,b,c}, there are exactly three solutions for p = 120. + + {20,48,52}, {24,45,51}, {30,40,50} + + For which value of p ≤ 1000, is the number of solutions maximised? +# + +best=0 +maxsol=0 +(5..1000).each do |p| + # find all {a,b,c} + # such that + # a<=b and a^2 + b^2 = c^2 + # and a+b+c = p + + nbsol=0 + # sqrtp=Math.sqrt(p).floor + (1..p).each do |a| + # a^2 + b^2 = c^2 => b^2 = c^2 - a^2 + # => b = sqrt( c^2 - a^2 ) + # + # a + b + c = p => b = p - c - a + # + (a..p).each do |b| + tmp=a**2 + b**2 + c = Math.sqrt(tmp) + break if a + b + c > p + next if a + b + c < p + next if c**2 != tmp + puts "#{p}: (#{a},#{b},#{c})" + nbsol += 1 + end + end + + if nbsol > maxsol + maxsol=nbsol + best=p + end +end + +puts "Best p = #{best} => #{maxsol}" diff --git a/040.rb b/040.rb new file mode 100644 index 0000000..7c6c666 --- /dev/null +++ b/040.rb @@ -0,0 +1,25 @@ +descr=%{ + An irrational decimal fraction is created by concatenating the positive integers: + + 0.123456789101112131415161718192021... + + It can be seen that the 12^(th) digit of the fractional part is 1. + + If d_(n) represents the n^(th) digit of the fractional part, find the value of the following expression. + + d_(1) × d_(10) × d_(100) × d_(1000) × d_(10000) × d_(100000) × d_(1000000) +} + +str="" +(1..(1000000)).each do |i| + str.concat(i.to_s) +end + +prod=1 +(0..6).each do |p| + digit=str[10**p - 1]-"0"[0] + puts digit + prod *= digit +end + +puts "Product = #{prod}" diff --git a/041.rb b/041.rb new file mode 100644 index 0000000..e8d8489 --- /dev/null +++ b/041.rb @@ -0,0 +1,43 @@ +descr=%{ + We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once. For example, 2143 is a 4-digit pandigital and is also prime. + + What is the largest n-digit pandigital prime that exists? +} + +thoughts=%{ + remark that all 9-digit pandigital number are not prime. + + 1 + ... + 9 = 45 which is divisible by 3 + + We don't need to search for prime pandigital superior to 10**8 + Also + + 1 = 1 + 1+2 = 3 => divisible by 3 + 1+2+3 = 6 => divisible by 3 + 1+2+3+4 = 10 + 1+2+3+4+5 = 15 => divisible by 3 + 1+ ... +6 = 21 => divisible by 3 + 1+ ... +7 = 28 + 1+ ... +8 = 36 => divisible by 3 + 1+ ... +9 = 45 => divisible by 3 + + Therefore at max there exists a 7-digit pandigital prime + if not only a 4-digit pandigital prime +} + +puts "Read primes" +primes=File.read("firsts_10MM_primes.txt").split() + +$numbers=%q(1234567).split('').sort +def is_pandigital(str) + return str.split('').sort == $numbers +end + +puts "Search pandigitals" +primes.each do |str| + next if str.length != 7 + if is_pandigital(str) + puts str + end +end diff --git a/042.rb b/042.rb new file mode 100644 index 0000000..46c607e --- /dev/null +++ b/042.rb @@ -0,0 +1,42 @@ +descr=%{ + The n^(th) term of the sequence of triangle numbers is given by, t_(n) = ½n(n+1); so the first ten triangle numbers are: + + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... + + By converting each letter in a word to a number corresponding to its alphabetical position and adding these values we form a word value. For example, the word value for SKY is 19 + 11 + 25 = 55 = t_(10). If the word value is a triangle number then we shall call the word a triangle word. + + Using words.txt (right click and 'Save Link/Target As...'), a 16K text file containing nearly two-thousand common English words, how many are triangle words? +} + +def is_triangle_number(k) + # k = n * (n+1) / 2 + # 2k = n * (n+1) + # n**2 + n - 2k = 0 + + # a=1 b=1 c=-2k + + delta=Math.sqrt(1 + 8*k) + sol1=( 1 + delta)/2 + sol2=( -1 + delta)/2 + + return true if sol1 == sol1.floor && sol1 > 0 + return true if sol2 == sol2.floor && sol2 > 0 + return false +end + +def is_triangle_word(w) + is_triangle_number( w.split('').inject(0) {|sum,c| sum += c[0] +1- "A"[0]} ) +end + +# test +# (1..55).each { |x| puts x.to_s + ": " + is_triangle_word(x).to_s } + +# puts is_triangle_word("SKY") + +words=File.read("words.txt").sub(/\n/,'').gsub('"','').split(',') +sum=0 +words.each do |w| + sum += 1 if is_triangle_word(w) +end + +puts sum diff --git a/043.rb b/043.rb new file mode 100644 index 0000000..9f06684 --- /dev/null +++ b/043.rb @@ -0,0 +1,95 @@ +descr=%{ + The number, 1406357289, is a 0 to 9 pandigital number because it is made up of each of the digits 0 to 9 in some order, but it also has a rather interesting sub-string divisibility property. + + Let d_(1) be the 1^(st) digit, d_(2) be the 2^(nd) digit, and so on. In this way, we note the following: + + * d_(2)d_(3)d_(4)=406 is divisible by 2 + * d_(3)d_(4)d_(5)=063 is divisible by 3 + * d_(4)d_(5)d_(6)=635 is divisible by 5 + * d_(5)d_(6)d_(7)=357 is divisible by 7 + * d_(6)d_(7)d_(8)=572 is divisible by 11 + * d_(7)d_(8)d_(9)=728 is divisible by 13 + * d_(8)d_(9)d_(10)=289 is divisible by 17 + + Find the sum of all 0 to 9 pandigital numbers with this property. +} + +def ok(str) + return false if str[0] == str[1] + return false if str[0] == str[2] + return false if str[1] == str[2] + return true +end + +$potential={} + +[2,3,5,7,11,13,17].each do |p| + $potential[p]=[] + # We first limit d8d9d10 + ((10/p).ceil .. (1000/p).floor).each do |i| + str_num=(p*i).to_s + str_num = "0#{str_num}" if p*i<100 + if ok( str_num ) + $potential[p] <<= str_num.split('') + end + end +end + +[2,3,5,7,11,13,17].each do |p| + puts "====" + $potential[p].each do |t| + print t.join + ", " + end +end +puts + +# now we have limited greatly the search space for pandigital numbers +$list=[] + +def pandigit( tab, t, str) + # p [ tab, t, str ] + table=tab.clone + p = table.pop() + if p.nil? + # puts "* "+t.join()+str + $list <<= t.join()+str + return + end + $potential[p].each do |num| + next if t[0] != num[1] or t[1] != num[2] + # puts "exists: #{num.join}" + pandigit( table, num, t[2]+str); + end +end + +$numbers=%q(0123456789).split('').sort +def is_pandigital(str) + return str.split('').sort == $numbers +end + +# $potential[17]=[ ["7","8","9"], ["4","5","6"] ] +# $potential[13]=[ ["6","7","8"] ] +# $potential[11]=[ ["5","6","7"] ] +# $potential[7] =[ ["4","5","6"] ] +# $potential[5] =[ ["3","4","5"] ] +# $potential[3] =[ ["2","3","4"] ] +# $potential[2] =[ ["1","2","3"] ] + +sum=0 +$potential[17].each do |t| + pandigit( [2,3,5,7,11,13], t, "") + + # pandigit( [13], t, "") +end + +$list.each do |str| + (1..9).each do |d| + number=d.to_s+str + if is_pandigital( number ) + puts "OK: "+number + sum += number.to_i + end + end +end + +puts "Sum: #{sum}" diff --git a/044.rb b/044.rb new file mode 100644 index 0000000..920c193 --- /dev/null +++ b/044.rb @@ -0,0 +1,61 @@ +descr=%{ + Pentagonal numbers are generated by the formula, P_(n)=n(3n−1)/2. The first ten pentagonal numbers are: + + 1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ... + + It can be seen that P_(4) + P_(7) = 22 + 70 = 92 = P_(8). However, their difference, 70 − 22 = 48, is not pentagonal. + + Find the pair of pentagonal numbers, P_(j) and P_(k), for which their sum and difference is pentagonal and D = |P_(k) − P_(j)| is minimised; what is the value of D? +} + +thoughts=%{ + We can make a fast test to know whether a number is pentagonal. + + We can also remark that this function is strictly growing. + If P(k+1) - P(k) > P(j) then we should no more try to use the index j. +} + +def P(n) + return n*(3*n - 1)/2 +end + +def is_pentagonal(k) + # k = n(3n - 1)/2 + # 2k = n(3n - 1) + # 3n^2 - n - 2k = 0 + # + a=3.0; b=-1; c=-2.0*k + # delta = sqrt( b^2 - 4ac ) + delta=Math.sqrt( b**2 - 4*a*c ) + sol1=( -b + delta )/(2*a) + sol2=( -b - delta )/(2*a) + + # renvoie vrai s'il existe une solution entiere positive + return true if sol1 == sol1.floor && sol1 > 0 + return true if sol2 == sol2.floor && sol2 > 0 + return false +end + +# (1..117).each do |x| +# puts x if is_pentagonal(x) +# end +j=1 +k=2 +while true + pk=P(k) + pj=P(j) + diff=pk-pj + sum=pk+pj + # puts %{P(#{k})=#{pk}, P(#{j})=#{pj}, Pk-Pj=#{diff}#{"*" if is_pentagonal(diff)}, Pk+Pj=#{sum}#{"*" if is_pentagonal(sum)}} + if is_pentagonal( sum ) && is_pentagonal( diff ) + puts %{P(#{k})=#{pk}, P(#{j})=#{pj}, Pk-Pj=#{diff}#{"*" if is_pentagonal(diff)}, Pk+Pj=#{sum}#{"*" if is_pentagonal(sum)}} + puts diff + break + end + if P(k+1) - pk > pj + k += 1 + j = k-1 + else + j -= 1 + end +end diff --git a/045.rb b/045.rb new file mode 100644 index 0000000..37971be --- /dev/null +++ b/045.rb @@ -0,0 +1,46 @@ +descr=%{ +Triangle, pentagonal, and hexagonal numbers are generated by the following formulae: +Triangle T_(n)=n(n+1)/2 1, 3, 6, 10, 15, ... +Pentagonal P_(n)=n(3n−1)/2 1, 5, 12, 22, 35, ... +Hexagonal H_(n)=n(2n−1) 1, 6, 15, 28, 45, ... + +It can be verified that T_(285) = P_(165) = H_(143) = 40755. + +Find the next triangle number that is also pentagonal and hexagonal. +} + +# number[n]=1,2 or 3 if 3 triangular, pentagonal and hexagonal +$number={} +def save_and_verif(t) + if $number[t].nil? + $number[t]=1 + else + $number[t] += 1 + if $number[t] == 3 + puts t + exit 0 + end + end +end + +def T(n) + t=n*(n+1)/2 + save_and_verif(t) +end +def P(n) + t=n*(3*n-1)/2 + save_and_verif(t) +end +def H(n) + t=n*(2*n-1) + save_and_verif(t) +end + +n=144 +while true + T(n) + P(n) + H(n) + + n+=1 +end diff --git a/046.rb b/046.rb new file mode 100644 index 0000000..c70cd9a --- /dev/null +++ b/046.rb @@ -0,0 +1,48 @@ +descr=%{ +It was proposed by Christian Goldbach that every odd composite number can be written as the sum of a prime and twice a square. + +9 = 7 + 2×1^(2) +15 = 7 + 2×2^(2) +21 = 3 + 2×3^(2) +25 = 7 + 2×3^(2) +27 = 19 + 2×2^(2) +33 = 31 + 2×1^(2) + +It turns out that the conjecture was false. + +What is the smallest odd composite that cannot be written as the sum of a prime and twice a square? +} + +puts "Read primes and init data structure" +primes=File.read("firsts_1MM_primes.txt").split().collect{|x| x.to_i } +is_prime={} +primes.each do |p| + is_prime[p]=true +end + +puts "search" +k=1 +while true + n=2*k+1 + k+=1 + next if is_prime[n] + puts "* "+n.to_s if k%100 == 0 + found=false + primes.each do |p| + break if p>n + i=0 + while p + 2*(i**2) <= n + if p + 2*(i**2) == n + # puts "#{n} = #{p} + 2.#{i}^2" + found=true + break + end + i+=1 + end + break if found + end + if not found + puts n + exit 0 + end +end diff --git a/047.rb b/047.rb new file mode 100644 index 0000000..101825a --- /dev/null +++ b/047.rb @@ -0,0 +1,63 @@ +descr=%{ + The first two consecutive numbers to have two distinct prime factors are: + + 14 = 2 × 7 + 15 = 3 × 5 + + The first three consecutive numbers to have three distinct prime factors are: + + 644 = 2² × 7 × 23 + 645 = 3 × 5 × 43 + 646 = 2 × 17 × 19. + + Find the first four consecutive integers to have four distinct primes factors. + What is the first of these numbers? +} + +thoughts=%{ + Loop for each number and find it's prime number decomposition (there is no shortcut doing this) +} + + +puts "Read primes" +$primes=File.read("firsts_1MM_primes.txt").split().collect! { |p| p.to_i } + +# the uniq is to transform [2,2,3] into [2,3] +def prime_decomposition(n) + if n <= 1 + return [] + end + $primes.each do |p| + if n % p == 0 + return ( prime_decomposition(n/p) << p ).uniq + end + end +end + +size=4 +buff=[] +(2..size).each do |n| + buff <<= prime_decomposition(n).length +end +n=size+1 +while true + buff <<= prime_decomposition(n).length + + found=true + buff.each do |l| + if l != size + found=false + break + end + end + + if n%1000 == 0 + print "** #{n}: " + p buff + end + + break if found + buff.shift + n+=1 +end +puts "Solution = #{n+1-size}" diff --git a/048.rb b/048.rb new file mode 100644 index 0000000..2728ddc --- /dev/null +++ b/048.rb @@ -0,0 +1,12 @@ +descr=%{ + The series, 1^1 + 2^2 + 3^3 + ... + 10^10 = 10405071317. + + Find the last ten digits of the series, 1^1 + 2^2 + 3^3 + ... + 1000^1000. +} + +sum=0 +(1..1000).each do |n| + sum += n**n +end + +puts sum.to_s[-10..-1] diff --git a/049.rb b/049.rb new file mode 100644 index 0000000..529c04b --- /dev/null +++ b/049.rb @@ -0,0 +1,45 @@ +descr=%{ +The arithmetic sequence, 1487, 4817, 8147, in which each of the terms increases +by 3330, is unusual in two ways: (i) each of the three terms are prime, and, +(ii) each of the 4-digit numbers are permutations of one another. + +There are no arithmetic sequences made up of three 1-, 2-, or 3-digit primes, +exhibiting this property, but there is one other 4-digit increasing sequence. + +What 12-digit number do you form by concatenating the three terms in this + sequence? +} + + +puts "Read primes" +$primes=File.read("firsts_1MM_primes.txt").split() + +fdprimes=[] +$primes.each do |p| + if p.length == 4 + fdprimes <<= p + end +end + +is_prime={} +fdprimes.each do |p| + is_prime[p]=true +end + +fdprimes.each do |p| + next if p == "1487" + puts p + sigp=p.split('').sort + fdprimes.each do |q| + next if q<=p + sigq=q.split('').sort + if sigp == sigq + r = ( 2*q.to_i-p.to_i ).to_s + sigr=r.split('').sort + if sigp == sigr and is_prime[r] + puts "#{p}#{q}#{r}" + exit 0 + end + end + end +end diff --git a/050.rb b/050.rb new file mode 100644 index 0000000..0ab7f16 --- /dev/null +++ b/050.rb @@ -0,0 +1,49 @@ +descr=%{ + The prime 41, can be written as the sum of six consecutive primes: + + 41 = 2 + 3 + 5 + 7 + 11 + 13 + This is the longest sum of consecutive primes that adds to a prime below one-hundred. + + The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms, and is equal to 953. + + Which prime, below one-million, can be written as the sum of the most consecutive primes? +} + +require "primes" +po = Primes.new(1) + +primes = po.primes + +maxnb=0 +best=0 +min=0 +max=0 +limit=1000000 + +initsum=primes.inject(0) {|sum,p| sum+p} +initnb=primes.length +primes.reverse.each do |maxp| + initsum -= maxp + sum=initsum + initnb -= 1 + nb = initnb + next if maxp>limit/21 + primes.each do |minp| + sum -= minp + nb -= 1 + next if minp>limit/21 + break if maxp <= minp + next if sum>limit + if po.is_prime(sum) + if nb>maxnb + best=sum + maxnb=nb + min=minp + max=maxp + puts %{#{best} #{min}->#{max} (#{maxnb})} + end + end + end +end + +puts %{BEST: #{best} #{min}->#{max} (#{maxnb})} diff --git a/051.rb b/051.rb new file mode 100644 index 0000000..2700cfd --- /dev/null +++ b/051.rb @@ -0,0 +1,75 @@ +descr=%{ + By replacing the 1st digit of *3, it turns out that six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime. + + By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit number is the first example having seven primes among the ten generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993. Consequently 56003, being the first member of this family, is the smallest prime with this property. + + Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime value family. +} + +require 'primes' + +$po = Primes.new +$curnumber +$dynamic = {} + +def rec_test_all_cases(tab,min,n) + # puts "#{tab.join} min: #{min} n: #{n}" + if n==0 + if $dynamic[tab.join()] + return + end + nb=0 + (0..9).each do |k| + tmp=tab.map do |x| + x=='X'?k:x + end + if tmp[0] == 0 + next + end + if $po.is_prime( tmp.join().to_i ) + # puts tmp.join() + nb += 1 + end + end + if nb == 8 + (0..9).each do |k| + tmp=tab.map do |x| + x=='X'?k:x + end + if tmp[0] == 0 + next + end + if $po.is_prime( tmp.join().to_i ) + puts tmp.join() + nb += 1 + end + end + puts "FOUND! #{$curnumber} #{tab.join()}" + exit + else + $dynamic[ tab.join() ]=nb + puts "##{nb} => #{$curnumber} #{tab.join()}" + end + return + end + (min..tab.length-1).each do |i| + tmp=tab.clone + tmp[i]='X' + # puts "tmp: #{tmp.join}" + rec_test_all_cases(tmp, i,0) + if n-1>0 + rec_test_all_cases(tmp, i+1, n-1) + end + end +end + +def test_all_cases_for(p) + tab=p.to_s.split('') + rec_test_all_cases(tab, 0, tab.length - 1) +end + +$po.primes.each do |p| + next if p<10 + $curnumber=p + test_all_cases_for(p) +end diff --git a/052.rb b/052.rb new file mode 100644 index 0000000..76ce2dd --- /dev/null +++ b/052.rb @@ -0,0 +1,23 @@ +descr=%{ +It can be seen that the number, 125874, and its double, 251748, contain exactly the same digits, but in a different order. + +Find the smallest positive integer, x, such that 2x, 3x, 4x, 5x, and 6x, contain the same digits. +} + +n=1 +while true + l=n.to_s.split('').sort + find=true + (2..6).each do |m| + v=(n*m).to_s.split('').sort + if v != l + find=false + break + end + end + if find + puts "FOUND: #{n}" + exit 0 + end + n+=1 +end diff --git a/053.rb b/053.rb new file mode 100644 index 0000000..269d3cf --- /dev/null +++ b/053.rb @@ -0,0 +1,55 @@ +descr=%{ + There are exactly ten ways of selecting three from five, 12345: + + 123, 124, 125, 134, 135, 145, 234, 235, 245, and 345 + + In combinatorics, we use the notation, 5C3 = 10. + + In general, + nCr = + n! + r!(n−r)! + ,where r ≤ n, n! = n×(n−1)×...×3×2×1, and 0! = 1. + + It is not until n = 23, that a value exceeds one-million: 23C10 = 1144066. + + How many, not necessarily distinct, values of nCr, for 1 ≤ n ≤ 100, are greater than one-million? +} + +remarks=%{ + C(n,r) == C(n,n-r) + C(n,r) > X => forall m>n C(m,r)>X + suppose r <= n-r + + 5 x 4 x 3 x 2 x 1 5x4 + ----------------------- = ------- = 10 + ( 3 x 2 x 1 ) ( 2 x 1 ) 2x1 + + C(n,r) = n x (n-1) x ... x (n-(n-r)+1) / r x (r-1) x ... x 1 + = n x (n-1) x ... x (r+1) / r x (r-1) x ... x 1 +} + +def C(n,r) + if (r > n-r) + r = n-r + end + top=1 + (n-r+1..n).each do |x| + top *= x + end + down=1 + (2..r).each do |x| + down *= x + end + return top/down +end + +sum=0 +(1..100).each do |n| + (1..n).each do |r| + if C(n,r)>10**6 + sum+=1 + end + end +end +puts sum diff --git a/054.rb b/054.rb new file mode 100644 index 0000000..270cbd4 --- /dev/null +++ b/054.rb @@ -0,0 +1,322 @@ +descr=%{ +In the card game poker, a hand consists of five cards and are ranked, from lowest to highest, in the following way: + + * High Card: Highest value card. + * One Pair: Two cards of the same value. + * Two Pairs: Two different pairs. + * Three of a Kind: Three cards of the same value. + * Straight: All cards are consecutive values. + * Flush: All cards of the same suit. + * Full House: Three of a kind and a pair. + * Four of a Kind: Four cards of the same value. + * Straight Flush: All cards are consecutive values of same suit. +* Royal Flush: Ten, Jack, Queen, King, Ace, in same suit. + +The cards are valued in the order: +2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace. + +If two players have the same ranked hands then the rank made up of the highest value wins; for example, a pair of eights beats a pair of fives (see example 1 below). But if two ranks tie, for example, both players have a pair of queens, then highest cards in each hand are compared (see example 4 below); if the highest cards tie then the next highest cards are compared, and so on. + +Consider the following five hands dealt to two players: +Hand Player 1 Player 2 Winner +1 5H 5C 6S 7S KD + Pair of Fives + 2C 3S 8S 8D TD + Pair of Eights + Player 2 +2 5D 8C 9S JS AC + Highest card Ace + 2C 5C 7D 8S QH + Highest card Queen + Player 1 +3 2D 9C AS AH AC + Three Aces + 3D 6D 7D TD QD + Flush with Diamonds + Player 2 +4 4D 6S 9H QH QC + Pair of Queens + Highest card Nine + 3D 6D 7H QD QS + Pair of Queens + Highest card Seven + Player 1 +5 2H 2D 4C 4D 4S + Full House + With Three Fours + 3C 3D 3S 9S 9D + Full House + with Three Threes + Player 1 + +poker.txt, contains one-thousand random hands dealt to two players. +Each line of the file contains ten cards (separated by a single space): +the first five are Player 1's cards and the last five are Player 2's cards. +You can assume that all hands are valid (no invalid characters or +repeated cards), each player's hand is in no specific order, +and in each hand there is a clear winner. + +How many hands does Player 1 win? +} + +hands=File.read("poker.txt").split("\n").collect { |line| x=line.split; [x[0..4],x[5..9]] } + +class Category + attr_accessor :cat + attr_accessor :value + attr_accessor :subvalue + def to_s + res=@numbers.join(" ") << " : " + case @cat + when 10 then res<<="royal_flush" + when 9 then res<<="straight_flush" + when 8 then res<<="four_of_a_kind" + when 7 then res<<="full_house" + when 6 then res<<="flush" + when 5 then res<<="straight" + when 4 then res<<="three_of_a_kind" + when 3 then res<<="two_pairs" + when 2 then res<<="one_pair" + when 1 then res<<="high_card" + end + res <<= " V(#{@value}" + if @subvalue + res <<= ":#{@subvalue}" + end + res <<= ")" + end + def initialize(hand) + @rawhand=hand + @hand=hand.map do |str| + c = str.split('') + case c[0] + when /[2-9]/ then { c[0].to_i => c[1] } + when 'T' then { 10 => c[1] } + when 'J' then { 11 => c[1] } + when 'Q' then { 12 => c[1] } + when 'K' then { 13 => c[1] } + when 'A' then { 14 => c[1] } + else exit 1 + end + end + @numbers=@hand.map {|x| x.keys[0]}.sort + @nb={} + @numbers.each do |n| + if @nb[n] + @nb[n]+=1 + else + @nb[n]=1 + end + end + @nbcolors={} + @hand.each do |x| + if @nbcolors[x.values[0]].nil? + @nbcolors[x.values[0]]=1 + else + @nbcolors[x.values[0]]+=1 + end + end + # print "@hand: " + # p @hand + # print "@nb: " + # p @nb + # print "@numbers: " + # p @numbers + # print "@nbcolors: " + # p @nbcolors + @cat=nil + @value=nil + @subvalue=nil + return if is_royal_flush + return if is_straight_flush + return if is_four_of_a_kind + return if is_full_house + return if is_flush + return if is_straight + return if is_three_of_a_kind + return if is_two_pairs + return if is_one_pair + return is_high_card + end + + def is_royal_flush + if is_straight_flush and @value==14 + @cat=10 + return true + end + return false + end + def is_straight_flush + if is_flush and is_straight + @cat=9 + return true + else + return false + end + end + def is_four_of_a_kind + carre = @nb.select{|k,v| v>=4}.map {|x| x[0]} + if carre.empty? + return false + end + @cat=8 + @value=carre[0] + end + def is_full_house + brelan = @nb.select{|k,v| v==3}.map {|x| x[0]} + + pair = @nb.select{|k,v| v==2}.map {|x| x[0]} + + + if brelan.empty? or pair.empty? + return false + end + + @cat=7 + @value=brelan[0] + @subvalue=pair[0] + end + def is_flush + if @nbcolors.size != 1 + return false + end + @cat=6 + @value=@numbers[-1] + @subvalue=@numbers[-2] + end + def is_straight + last=nil + if @numbers == [2,3,4,5,14] + @cat=5 + @value=5 + return true + end + @numbers.each do |n| + if last.nil? + last=n + next + end + if n != last+1 + return false + end + last=n + end + @cat=5 + @value=@numbers[-1] + return true + end + def is_three_of_a_kind + brelan = @nb.select{|k,v| v>=3}.map {|x| x[0]} + + if brelan.empty? + return false + end + @cat=4 + @value=brelan[0] + end + def is_two_pairs + pairs = @nb.select{|k,v| v>=2}.map {|x| x[0]} + + if pairs.size < 2 + return false + end + @cat=3 + @value = pairs.max + @subvalue = pairs.min + return true + end + def is_one_pair + pair = @nb.select{|k,v| v>=2}.map {|x| x[0]} + + if pair.empty? + return false + end + @cat=2 + @value = pair[0] + return true + end + def is_high_card + @cat=1 + @value=@numbers[-1] + @subvalue=@numbers[-2] + return true + end +end + +def tonumber(hand) + hand.map do |str| + c = str.split('') + case c[0] + when /[2-9]/ then c[0].to_i + when 'T' then 10 + when 'J' then 11 + when 'Q' then 12 + when 'K' then 13 + when 'A' then 14 + end + end +end + +def highest_card(hand1,hand2) + numbers1=tonumber(hand1).reverse + numbers2=tonumber(hand2).reverse + i=0 + numbers1.each do |c| + if c > numbers2[i] + return true + end + if c < numbers2[i] + return false + end + i+=1 + end + return true +end + +def win(h) + hand1=h[0] + hand2=h[1] + + cat1=Category.new(hand1) + puts "HAND1: #{cat1.to_s}" + cat2=Category.new(hand2) + puts "HAND2: #{cat2.to_s}" + + # Best category win + if cat1.cat > cat2.cat + return true + elsif cat1.cat < cat2.cat + return false + end + + # same category? Best value win + if cat1.value > cat2.value + return true + elsif cat1.value < cat2.value + return false + end + + # same value? Best subvalue win (if it exists) + if not cat1.subvalue.nil? + if cat1.subvalue > cat2.subvalue + return true + elsif cat1.subvalue < cat2.subvalue + return false + end + end + + # Nothing less? Highest card are compared + return highest_card(hand1, hand2) +end + +sum=0 +hands.each do |h| + if win(h) + puts "PLAYER 1 (WIN)" + sum+=1 + else + puts "PLAYER 2 (LOSE)" + end +end + +puts sum diff --git a/055.hs b/055.hs new file mode 100644 index 0000000..5fb5a99 --- /dev/null +++ b/055.hs @@ -0,0 +1,18 @@ +-- num_reverse :: Num a -> Num a +num_reverse = read . reverse . show + +-- num_palindrom :: Num a -> Bool +num_palindrom n = (show n) == (reverse $ show n) + +-- lychrel :: Num a -> Num a -> Bool +lychrel 0 n = False +lychrel depth n = ( num_palindrom number ) || lychrel (depth - 1) number + where number = n + (num_reverse n) + +-- nblychrel :: Num a -> Num a +nblychrel n = length $ filter (not . lychrel 50) [1..n] + +main = do + putStrLn $ show ( lychrel 50 196 ) + putStrLn $ show ( nblychrel n ) + where n = 10000 diff --git a/056.hs b/056.hs new file mode 100644 index 0000000..0d9bfd6 --- /dev/null +++ b/056.hs @@ -0,0 +1,11 @@ +to_list x = [x] + +char_to_int c = read $ to_list c :: Integer + +digital_sum :: Integer -> Integer +digital_sum n = sum $ map ( char_to_int ) ( show n ) + +find_max n m = foldr max 0 [ digital_sum (a^b) | a <- [1..n], b <- [1..m]] + +main = do + putStrLn $ show $ find_max 100 100 diff --git a/057.hs b/057.hs new file mode 100644 index 0000000..f70fc56 --- /dev/null +++ b/057.hs @@ -0,0 +1,49 @@ +-- It is possible to show that the square root of two +-- can be expressed as an infinite continued fraction. +-- +-- √ 2 = 1 + 1/(2 + 1/(2 + 1/(2 + ... ))) = 1.414213... +-- +-- By expanding this for the first four iterations, we get: +-- +-- 1 + 1/2 = 3/2 = 1.5 +-- 1 + 1/(2 + 1/2) = 7/5 = 1.4 +-- 1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666... +-- 1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379... +-- +-- The next three expansions are 99/70, 239/169, and 577/408, +-- but the eighth expansion, 1393/985, +-- is the first example where the number of digits in the numerator exceeds +-- the number of digits in the denominator. +-- +-- In the first one-thousand expansions, +-- how many fractions contain a numerator with more digits than denominator? +-- + +-- Thoughts : +-- 1 + 1/2 = 3/2 +-- 1 + 1/(2 + 1/2) = 1 + 1/(5/2) +-- = 1 + 2/5 +-- = 5 + 2 / 5 +-- = 7/5 +-- F_n = p/q +-- F_{n+1} +-- +-- 1 + 1/( 1 + p/q ) = 1 + 1/( q+p / q) +-- = 1 + q / q+p +-- = 2q+p / q+p +-- + +next (p,q) = (2*q + p , p+q) + +nb_digits n = length $ show n + +digits 0 x = [] +digits n x = y:(digits (n-1) y) + where y = next x + +greater_numerator (p,q) = (nb_digits p) > (nb_digits q) + +nb_greater_numerator n = length $ filter (greater_numerator) (digits n (1,1)) + +main = do + putStrLn $ show $ nb_greater_numerator 1000 diff --git a/058.hs b/058.hs new file mode 100644 index 0000000..932710a --- /dev/null +++ b/058.hs @@ -0,0 +1,66 @@ +-- Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed. +-- +-- 37 36 35 34 33 32 31 +-- 38 17 16 15 14 13 30 +-- 39 18 5 4 3 12 29 +-- 40 19 6 1 2 11 28 +-- 41 20 7 8 9 10 27 +-- 42 21 22 23 24 25 26 +-- 43 44 45 46 47 48 49 +-- +-- It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%. +-- +-- If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%? +-- +-- Reflexion: +-- if n is the side length of the square spiral. The numbers at each 'coin' are +-- +-- 1 -> 1 +-- 2 -> 3 5 7 9 +-- 3 -> 13 17 21 25 +-- ... +-- +-- The rule is +-- (last_max_number + n.(size-1) | n in [1..4]) +-- examples: +-- last_max_number=1 +-- size = 3 +-- 1+2 = 3, 1+2*2=5, 1+3*2=7, 1+4*2=9 +-- +-- last_max_number=9 +-- size=5 +-- 9+4=13, 9+2*4=17, 9+3*4=21, 9+4*4=25 + +import Prime + +next_four_numbers :: (Num a) => a -> a -> [a] +next_four_numbers n size = map (\p -> n + p*(size-1)) [1,2,3,4] +nextState (prev,size) = (next_four_numbers (last prev) size, size+2) +spiral = concat $ map fst $ iterate nextState ([1],3) +diag_primes = map is_prime spiral + +ratio_func (x:xs) (p,q) = (p,q):(ratio_func xs b) + where b = if x then (p+1,q+1) else (p,q+1) + +ratios = ratio_func diag_primes (0,0) + +takeNth n p (x:xs) = if n == p + then x:takeNth n 1 xs + else takeNth n (p+1) xs + +-- takeWhile (>0.1) (map fst $ takeNth 4 4 ratios) + +main = do + -- putStrLn $ show $ firsts_spiral_numbers n + putStrLn $ show $ take (4*n+1) spiral + putStrLn $ show $ take (4*n+1) diag_primes + putStrLn $ show $ take 10 $ takeNth 4 4 spiral + -- putStrLn $ show $ tmp + putStrLn $ show $ res + putStrLn $ show $ ((res-1)/2) + 1 + 2 + where + n=3 + rat=0.1 + tmp = takeWhile (\(p,q) -> (q < 2) || (p/q > rat) ) $ takeNth 4 3 ratios + (_,res) = last $ tmp + diff --git a/058.rb b/058.rb new file mode 100644 index 0000000..1300186 --- /dev/null +++ b/058.rb @@ -0,0 +1,56 @@ +problem=%{ +-- Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed. +-- +-- 37 36 35 34 33 32 31 +-- 38 17 16 15 14 13 30 +-- 39 18 5 4 3 12 29 +-- 40 19 6 1 2 11 28 +-- 41 20 7 8 9 10 27 +-- 42 21 22 23 24 25 26 +-- 43 44 45 46 47 48 49 +-- +-- It is interesting to note that the odd squares lie along the bottom right diagonal, but what is more interesting is that 8 out of the 13 numbers lying along both diagonals are prime; that is, a ratio of 8/13 ≈ 62%. +-- +-- If one complete new layer is wrapped around the spiral above, a square spiral with side length 9 will be formed. If this process is continued, what is the side length of the square spiral for which the ratio of primes along both diagonals first falls below 10%? +-- +-- Reflexion: +-- if n is the side length of the square spiral. The numbers at each 'coin' are +-- +-- 1 -> 1 +-- 2 -> 3 5 7 9 +-- 3 -> 13 17 21 25 +-- ... +-- +-- The rule is +-- (last_max_number + n.(size-1) | n in [1..4]) +-- examples: +-- last_max_number=1 +-- size = 3 +-- 1+2 = 3, 1+2*2=5, 1+3*2=7, 1+4*2=9 +-- +-- last_max_number=9 +-- size=5 +-- 9+4=13, 9+2*4=17, 9+3*4=21, 9+4*4=25 +} +require 'primes' +$po = Primes.new(100) + +size=1 +ratio=1 +last_max_number=1 +nb_prime=0.0 +nb_numbers_on_diag=1 + +while ratio > 0.1 do + size +=2 + (1..4).each do |n| + last_max_number += (size-1) + puts last_max_number + nb_prime += 1 if $po.is_prime(last_max_number) + nb_numbers_on_diag += 1 + end + ratio= nb_prime / nb_numbers_on_diag + puts ratio +end + +puts "size = #{size}" diff --git a/059.c b/059.c new file mode 100644 index 0000000..f53848f --- /dev/null +++ b/059.c @@ -0,0 +1,129 @@ +#include "dictionnary.c" +#define FILE_SIZE 2030 + +static Tree dictionnary; + +char is_small_letter(char c) { + return ('a' <= c) && (c <= 'z'); +} +char is_letter(char c) { + return (('A' <= c) && (c <= 'Z')) || is_small_letter(c); +} + +char to_upper(char c) { + if ( is_small_letter(c) ) + return 'A' - 'a' + c; + return c; +} + +void upper_str(char *str) { + while (*str) { + *str=to_upper(*str); + } +} + +char contains_english(char *decoded, int length) { + int i; + char tmpword[FILE_SIZE]; + int maxwordlen=0; + int len=0; + int badlen=0; + int w=0; + int nb_english_word=0; + + for (i=0; i5) { + fprintf(stderr,"%s\n",tmpword); + } + if (is_element(dictionnary,tmpword)) { + fprintf(stderr,"WORD: %s\n",tmpword); + nb_english_word++; + } + w=0; + } + } + return nb_english_word > 0; +} + +void decode(char *src, char *decoded, int code[], int length) { + int i,j; + for (i=0,j=0;i %s\n", tst_str); + + for (i='z'; i>='a'; i--) { + fprintf(stderr,"\n%c: ", i); + code[0]=i; + for (j='a'; j<='z'; j++) { + code[1]=j; + for (k='a'; k<='z'; k++) { + code[2]=k; + decode(src,decoded,code,length); + if (contains_english(decoded, length)) { + printf("\ncode = %c,%c,%c", code[0],code[1],code[2]); + printf("decoded message: %s",decoded); + printf("Sum = ", sum(decoded)); + } + } + } + } + + return 0; +} diff --git a/059.rb b/059.rb new file mode 100644 index 0000000..5e0536f --- /dev/null +++ b/059.rb @@ -0,0 +1,27 @@ +codes = File.read("cipher1.txt").split(",").map { |x| x.to_i } +# words = File.read("words.txt").split(",").map { |s| s[1..-2] } +# $is_word={} +# $potential_codes=[] +# words.each do |w| +# $is_word[w]=true +# end + +def to_ascii (l) + res="" + l.each do |c| + res <<= c.chr + end + res +end + +# (0..255).each do |x| +# puts "#{x}:\n" +# (0..255).each do |y| +# (0..255).each do |z| +# to_ascii(codes,[x,y,z]) +# end +# end +# end + +puts to_ascii(codes) + diff --git a/060 b/060 new file mode 100755 index 0000000..02eb239 Binary files /dev/null and b/060 differ diff --git a/060-old.hs b/060-old.hs new file mode 100644 index 0000000..f8ba783 --- /dev/null +++ b/060-old.hs @@ -0,0 +1,76 @@ +-- +-- The primes 3, 7, 109, and 673, are quite remarkable. +-- By taking any two primes and concatenating them in any order the result will always be prime. +-- For example, taking 7 and 109, both 7109 and 1097 are prime. +-- The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property. +-- +-- Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime. +-- + +-- Should use the following property +-- [x,y,z,t] special <=> [x,y,z] & [x,y,t] & [x,z,t] & [y,z,t] special + + +import Debug.Trace +import Data.List +import Prime + +is_couple_prime x y = ( is_prime $ read $ strx ++ stry ) && (is_prime $ read $ stry ++ strx) + where + strx = show x + stry = show y + +first_concat_prime_with_list x [] = True +first_concat_prime_with_list x (y:ys) = is_couple_prime x y && first_concat_prime_with_list x ys + +-- are_concat_primes [3,7,109,673] return true if number are primes +-- even with concat +are_concat_primes [] = True +are_concat_primes (x:xs) = (are_concat_primes xs) && first_concat_prime_with_list x xs + +nb_elements=4 + +-- n=5 max=5 -> 12345 +-- n=5 max=6 -> 12346, 12356, 12456, 13456, 23456 +-- n=5 max=7 -> 12347, 12357, 12367, 12457, 12467... + +-- n=1 max=1 -> 1 +-- n=1 max=2 -> 2 +-- n=1 max=3 -> 3 +-- +-- n=2 max=2 -> 12 +-- n=2 max=3 -> 13, 23 +-- n=2 max=4 -> 14, 24, 34 +-- n=2 max=5 -> 15, 26, 35, 45 +-- +-- n=3 max=3 -> 123 +-- n=3 max=4 -> 124, 134, 234 +-- n=3 max=5 -> 125, 135, 235, 145, 245, 345 (n=2,max=2 ; n=2,max=3 ; n=2,max=4)++[5] + +combination :: (Ord a) => Int -> a -> [a] -> [[a]] +combination 0 max list = [] +combination n max (x:xs@(y:ys)) + | x>max = [] + | n==1 && + x<=max && y>max = [[x]] + | otherwise = ( map (\z -> x:z) $ combination (n-1) max xs ) + ++ combination n max xs + +all_combinations n xs = foldr (++) [] $ map (\i -> traceShow i combination n (xs!!i) xs) [(n-1)..] + +special_numbers 1 = primes +special_numbers n = nub $ flatten $ filter are_concat_primes $ all_combinations n $ special_numbers (n-1) + where + flatten [] = [] + flatten ([]:ys) = flatten ys + flatten ((x:xs):ys) = x:(flatten ((xs):ys) ) + +main = do + -- putStrLn $ show $ are_concat_primes [3,7,109,673] + -- putStrLn $ show $ are_concat_primes [3,7,19,673] + -- putStrLn $ show $ combination 5 5 [1..] + -- putStrLn $ show $ take 40 $ all_combinations 5 primes + putStrLn $ show $ result + -- putStrLn ( "sum: " ++ (show $ sum result)) + where + result = take 1 $ filter (\x -> traceShow x are_concat_primes [3,7,109,673,x]) primes diff --git a/060.hi b/060.hi new file mode 100644 index 0000000..2226923 Binary files /dev/null and b/060.hi differ diff --git a/060.hs b/060.hs new file mode 100644 index 0000000..7a7c252 --- /dev/null +++ b/060.hs @@ -0,0 +1,50 @@ +-- +-- The primes 3, 7, 109, and 673, are quite remarkable. +-- By taking any two primes and concatenating them in any order the result will always be prime. +-- For example, taking 7 and 109, both 7109 and 1097 are prime. +-- The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property. +-- +-- Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime. +-- + +-- Should use the following property +-- [x,y,z,t] special <=> [x,y,z] & [x,y,t] & [x,z,t] & [y,z,t] special + + +import Debug.Trace +import Data.List +import Prime + +is_couple_prime x y = ( is_prime $ read $ strx ++ stry ) && (is_prime $ read $ stry ++ strx) + where + strx = show x + stry = show y + +first_concat_prime_with_list x [] = True +first_concat_prime_with_list x (y:ys) = is_couple_prime x y && first_concat_prime_with_list x ys + +-- are_concat_primes [3,7,109,673] return true if number are primes +-- even with concat +are_concat_primes [] = True +are_concat_primes (x:xs) = (are_concat_primes xs) && first_concat_prime_with_list x xs + +special_numbers 1 = take 300 primes +-- special_numbers n = nub $ flatten $ filter (\x -> traceShow x are_concat_primes x) $ subsets n (special_numbers (n-1)) +special_numbers n = nub $ flatten $ filter are_concat_primes $ subsets n (special_numbers (n-1)) + where + flatten [] = [] + flatten ([]:ys) = flatten ys + flatten ((x:xs):ys) = x:flatten (xs:ys) + +subsets :: Integer -> [a] -> [[a]] +subsets 0 _ = [[]] +subsets n [] = [] +subsets n (x:xs) = [x:ys | ys <- subsets (n-1) xs ] ++ subsets n xs + +main = do + putStrLn $ show $ are_concat_primes [3,7,109,673] + putStrLn $ show $ numbers + putStrLn $ show $ result + where + numbers = take 5 $ special_numbers 5 + result = sum numbers diff --git a/060.o b/060.o new file mode 100644 index 0000000..b7926fd Binary files /dev/null and b/060.o differ diff --git a/Prime.hi b/Prime.hi new file mode 100644 index 0000000..558ddbb Binary files /dev/null and b/Prime.hi differ diff --git a/Prime.hs b/Prime.hs new file mode 100644 index 0000000..77b9c0a --- /dev/null +++ b/Prime.hs @@ -0,0 +1,33 @@ +module Prime +( primes +, is_prime +) +where + data Wheel = Wheel Integer [Integer] + roll (Wheel n rs) = [n*k+r| k<-[0..], r<-rs] + + nextSize (Wheel n rs) p = + Wheel (p*n) [r' | k <- [0..(p-1)], r <- rs, + let r' = n*k+r, r' `mod` p /= 0] + w0 = Wheel 1 [1] + + mkWheel ds = foldl nextSize w0 ds + + primes :: [Integer] + primes = small ++ large + where + 1:p:candidates = roll $ mkWheel small + small = [2,3,5,7] + large = p : filter isPrime candidates + isPrime n = all (not . divides n) + $ takeWhile (\p -> p*p <= n) large + divides n p = n `mod` p == 0 + + is_prime n = n > 1 && n == head (primeFactors n) + primeFactors 1 = [] + primeFactors n = go n primes + where + go n ps@(p:pt) + | p*p > n = [n] + | n `rem` p == 0 = p : go (n `quot` p) ps + | otherwise = go n pt diff --git a/Prime.o b/Prime.o new file mode 100644 index 0000000..d312344 Binary files /dev/null and b/Prime.o differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..adc7e37 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +This repository contains my solutions for Project Euler + +Actually I am level 1. +I resolved problem 16 without using a program (I believe I simply used `irb`). diff --git a/cipher1-line.txt b/cipher1-line.txt new file mode 100644 index 0000000..fad38ff --- /dev/null +++ b/cipher1-line.txt @@ -0,0 +1,1201 @@ +79 +59 +12 +2 +79 +35 +8 +28 +20 +2 +3 +68 +8 +9 +68 +45 +0 +12 +9 +67 +68 +4 +7 +5 +23 +27 +1 +21 +79 +85 +78 +79 +85 +71 +38 +10 +71 +27 +12 +2 +79 +6 +2 +8 +13 +9 +1 +13 +9 +8 +68 +19 +7 +1 +71 +56 +11 +21 +11 +68 +6 +3 +22 +2 +14 +0 +30 +79 +1 +31 +6 +23 +19 +10 +0 +73 +79 +44 +2 +79 +19 +6 +28 +68 +16 +6 +16 +15 +79 +35 +8 +11 +72 +71 +14 +10 +3 +79 +12 +2 +79 +19 +6 +28 +68 +32 +0 +0 +73 +79 +86 +71 +39 +1 +71 +24 +5 +20 +79 +13 +9 +79 +16 +15 +10 +68 +5 +10 +3 +14 +1 +10 +14 +1 +3 +71 +24 +13 +19 +7 +68 +32 +0 +0 +73 +79 +87 +71 +39 +1 +71 +12 +22 +2 +14 +16 +2 +11 +68 +2 +25 +1 +21 +22 +16 +15 +6 +10 +0 +79 +16 +15 +10 +22 +2 +79 +13 +20 +65 +68 +41 +0 +16 +15 +6 +10 +0 +79 +1 +31 +6 +23 +19 +28 +68 +19 +7 +5 +19 +79 +12 +2 +79 +0 +14 +11 +10 +64 +27 +68 +10 +14 +15 +2 +65 +68 +83 +79 +40 +14 +9 +1 +71 +6 +16 +20 +10 +8 +1 +79 +19 +6 +28 +68 +14 +1 +68 +15 +6 +9 +75 +79 +5 +9 +11 +68 +19 +7 +13 +20 +79 +8 +14 +9 +1 +71 +8 +13 +17 +10 +23 +71 +3 +13 +0 +7 +16 +71 +27 +11 +71 +10 +18 +2 +29 +29 +8 +1 +1 +73 +79 +81 +71 +59 +12 +2 +79 +8 +14 +8 +12 +19 +79 +23 +15 +6 +10 +2 +28 +68 +19 +7 +22 +8 +26 +3 +15 +79 +16 +15 +10 +68 +3 +14 +22 +12 +1 +1 +20 +28 +72 +71 +14 +10 +3 +79 +16 +15 +10 +68 +3 +14 +22 +12 +1 +1 +20 +28 +68 +4 +14 +10 +71 +1 +1 +17 +10 +22 +71 +10 +28 +19 +6 +10 +0 +26 +13 +20 +7 +68 +14 +27 +74 +71 +89 +68 +32 +0 +0 +71 +28 +1 +9 +27 +68 +45 +0 +12 +9 +79 +16 +15 +10 +68 +37 +14 +20 +19 +6 +23 +19 +79 +83 +71 +27 +11 +71 +27 +1 +11 +3 +68 +2 +25 +1 +21 +22 +11 +9 +10 +68 +6 +13 +11 +18 +27 +68 +19 +7 +1 +71 +3 +13 +0 +7 +16 +71 +28 +11 +71 +27 +12 +6 +27 +68 +2 +25 +1 +21 +22 +11 +9 +10 +68 +10 +6 +3 +15 +27 +68 +5 +10 +8 +14 +10 +18 +2 +79 +6 +2 +12 +5 +18 +28 +1 +71 +0 +2 +71 +7 +13 +20 +79 +16 +2 +28 +16 +14 +2 +11 +9 +22 +74 +71 +87 +68 +45 +0 +12 +9 +79 +12 +14 +2 +23 +2 +3 +2 +71 +24 +5 +20 +79 +10 +8 +27 +68 +19 +7 +1 +71 +3 +13 +0 +7 +16 +92 +79 +12 +2 +79 +19 +6 +28 +68 +8 +1 +8 +30 +79 +5 +71 +24 +13 +19 +1 +1 +20 +28 +68 +19 +0 +68 +19 +7 +1 +71 +3 +13 +0 +7 +16 +73 +79 +93 +71 +59 +12 +2 +79 +11 +9 +10 +68 +16 +7 +11 +71 +6 +23 +71 +27 +12 +2 +79 +16 +21 +26 +1 +71 +3 +13 +0 +7 +16 +75 +79 +19 +15 +0 +68 +0 +6 +18 +2 +28 +68 +11 +6 +3 +15 +27 +68 +19 +0 +68 +2 +25 +1 +21 +22 +11 +9 +10 +72 +71 +24 +5 +20 +79 +3 +8 +6 +10 +0 +79 +16 +8 +79 +7 +8 +2 +1 +71 +6 +10 +19 +0 +68 +19 +7 +1 +71 +24 +11 +21 +3 +0 +73 +79 +85 +87 +79 +38 +18 +27 +68 +6 +3 +16 +15 +0 +17 +0 +7 +68 +19 +7 +1 +71 +24 +11 +21 +3 +0 +71 +24 +5 +20 +79 +9 +6 +11 +1 +71 +27 +12 +21 +0 +17 +0 +7 +68 +15 +6 +9 +75 +79 +16 +15 +10 +68 +16 +0 +22 +11 +11 +68 +3 +6 +0 +9 +72 +16 +71 +29 +1 +4 +0 +3 +9 +6 +30 +2 +79 +12 +14 +2 +68 +16 +7 +1 +9 +79 +12 +2 +79 +7 +6 +2 +1 +73 +79 +85 +86 +79 +33 +17 +10 +10 +71 +6 +10 +71 +7 +13 +20 +79 +11 +16 +1 +68 +11 +14 +10 +3 +79 +5 +9 +11 +68 +6 +2 +11 +9 +8 +68 +15 +6 +23 +71 +0 +19 +9 +79 +20 +2 +0 +20 +11 +10 +72 +71 +7 +1 +71 +24 +5 +20 +79 +10 +8 +27 +68 +6 +12 +7 +2 +31 +16 +2 +11 +74 +71 +94 +86 +71 +45 +17 +19 +79 +16 +8 +79 +5 +11 +3 +68 +16 +7 +11 +71 +13 +1 +11 +6 +1 +17 +10 +0 +71 +7 +13 +10 +79 +5 +9 +11 +68 +6 +12 +7 +2 +31 +16 +2 +11 +68 +15 +6 +9 +75 +79 +12 +2 +79 +3 +6 +25 +1 +71 +27 +12 +2 +79 +22 +14 +8 +12 +19 +79 +16 +8 +79 +6 +2 +12 +11 +10 +10 +68 +4 +7 +13 +11 +11 +22 +2 +1 +68 +8 +9 +68 +32 +0 +0 +73 +79 +85 +84 +79 +48 +15 +10 +29 +71 +14 +22 +2 +79 +22 +2 +13 +11 +21 +1 +69 +71 +59 +12 +14 +28 +68 +14 +28 +68 +9 +0 +16 +71 +14 +68 +23 +7 +29 +20 +6 +7 +6 +3 +68 +5 +6 +22 +19 +7 +68 +21 +10 +23 +18 +3 +16 +14 +1 +3 +71 +9 +22 +8 +2 +68 +15 +26 +9 +6 +1 +68 +23 +14 +23 +20 +6 +11 +9 +79 +11 +21 +79 +20 +11 +14 +10 +75 +79 +16 +15 +6 +23 +71 +29 +1 +5 +6 +22 +19 +7 +68 +4 +0 +9 +2 +28 +68 +1 +29 +11 +10 +79 +35 +8 +11 +74 +86 +91 +68 +52 +0 +68 +19 +7 +1 +71 +56 +11 +21 +11 +68 +5 +10 +7 +6 +2 +1 +71 +7 +17 +10 +14 +10 +71 +14 +10 +3 +79 +8 +14 +25 +1 +3 +79 +12 +2 +29 +1 +71 +0 +10 +71 +10 +5 +21 +27 +12 +71 +14 +9 +8 +1 +3 +71 +26 +23 +73 +79 +44 +2 +79 +19 +6 +28 +68 +1 +26 +8 +11 +79 +11 +1 +79 +17 +9 +9 +5 +14 +3 +13 +9 +8 +68 +11 +0 +18 +2 +79 +5 +9 +11 +68 +1 +14 +13 +19 +7 +2 +18 +3 +10 +2 +28 +23 +73 +79 +37 +9 +11 +68 +16 +10 +68 +15 +14 +18 +2 +79 +23 +2 +10 +10 +71 +7 +13 +20 +79 +3 +11 +0 +22 +30 +67 +68 +19 +7 +1 +71 +8 +8 +8 +29 +29 +71 +0 +2 +71 +27 +12 +2 +79 +11 +9 +3 +29 +71 +60 +11 +9 +79 +11 +1 +79 +16 +15 +10 +68 +33 +14 +16 +15 +10 +22 +73 diff --git a/cipher1.enc b/cipher1.enc new file mode 100644 index 0000000..6c9dd8a Binary files /dev/null and b/cipher1.enc differ diff --git a/cipher1.txt b/cipher1.txt new file mode 100644 index 0000000..08cee2d --- /dev/null +++ b/cipher1.txt @@ -0,0 +1 @@ +79,59,12,2,79,35,8,28,20,2,3,68,8,9,68,45,0,12,9,67,68,4,7,5,23,27,1,21,79,85,78,79,85,71,38,10,71,27,12,2,79,6,2,8,13,9,1,13,9,8,68,19,7,1,71,56,11,21,11,68,6,3,22,2,14,0,30,79,1,31,6,23,19,10,0,73,79,44,2,79,19,6,28,68,16,6,16,15,79,35,8,11,72,71,14,10,3,79,12,2,79,19,6,28,68,32,0,0,73,79,86,71,39,1,71,24,5,20,79,13,9,79,16,15,10,68,5,10,3,14,1,10,14,1,3,71,24,13,19,7,68,32,0,0,73,79,87,71,39,1,71,12,22,2,14,16,2,11,68,2,25,1,21,22,16,15,6,10,0,79,16,15,10,22,2,79,13,20,65,68,41,0,16,15,6,10,0,79,1,31,6,23,19,28,68,19,7,5,19,79,12,2,79,0,14,11,10,64,27,68,10,14,15,2,65,68,83,79,40,14,9,1,71,6,16,20,10,8,1,79,19,6,28,68,14,1,68,15,6,9,75,79,5,9,11,68,19,7,13,20,79,8,14,9,1,71,8,13,17,10,23,71,3,13,0,7,16,71,27,11,71,10,18,2,29,29,8,1,1,73,79,81,71,59,12,2,79,8,14,8,12,19,79,23,15,6,10,2,28,68,19,7,22,8,26,3,15,79,16,15,10,68,3,14,22,12,1,1,20,28,72,71,14,10,3,79,16,15,10,68,3,14,22,12,1,1,20,28,68,4,14,10,71,1,1,17,10,22,71,10,28,19,6,10,0,26,13,20,7,68,14,27,74,71,89,68,32,0,0,71,28,1,9,27,68,45,0,12,9,79,16,15,10,68,37,14,20,19,6,23,19,79,83,71,27,11,71,27,1,11,3,68,2,25,1,21,22,11,9,10,68,6,13,11,18,27,68,19,7,1,71,3,13,0,7,16,71,28,11,71,27,12,6,27,68,2,25,1,21,22,11,9,10,68,10,6,3,15,27,68,5,10,8,14,10,18,2,79,6,2,12,5,18,28,1,71,0,2,71,7,13,20,79,16,2,28,16,14,2,11,9,22,74,71,87,68,45,0,12,9,79,12,14,2,23,2,3,2,71,24,5,20,79,10,8,27,68,19,7,1,71,3,13,0,7,16,92,79,12,2,79,19,6,28,68,8,1,8,30,79,5,71,24,13,19,1,1,20,28,68,19,0,68,19,7,1,71,3,13,0,7,16,73,79,93,71,59,12,2,79,11,9,10,68,16,7,11,71,6,23,71,27,12,2,79,16,21,26,1,71,3,13,0,7,16,75,79,19,15,0,68,0,6,18,2,28,68,11,6,3,15,27,68,19,0,68,2,25,1,21,22,11,9,10,72,71,24,5,20,79,3,8,6,10,0,79,16,8,79,7,8,2,1,71,6,10,19,0,68,19,7,1,71,24,11,21,3,0,73,79,85,87,79,38,18,27,68,6,3,16,15,0,17,0,7,68,19,7,1,71,24,11,21,3,0,71,24,5,20,79,9,6,11,1,71,27,12,21,0,17,0,7,68,15,6,9,75,79,16,15,10,68,16,0,22,11,11,68,3,6,0,9,72,16,71,29,1,4,0,3,9,6,30,2,79,12,14,2,68,16,7,1,9,79,12,2,79,7,6,2,1,73,79,85,86,79,33,17,10,10,71,6,10,71,7,13,20,79,11,16,1,68,11,14,10,3,79,5,9,11,68,6,2,11,9,8,68,15,6,23,71,0,19,9,79,20,2,0,20,11,10,72,71,7,1,71,24,5,20,79,10,8,27,68,6,12,7,2,31,16,2,11,74,71,94,86,71,45,17,19,79,16,8,79,5,11,3,68,16,7,11,71,13,1,11,6,1,17,10,0,71,7,13,10,79,5,9,11,68,6,12,7,2,31,16,2,11,68,15,6,9,75,79,12,2,79,3,6,25,1,71,27,12,2,79,22,14,8,12,19,79,16,8,79,6,2,12,11,10,10,68,4,7,13,11,11,22,2,1,68,8,9,68,32,0,0,73,79,85,84,79,48,15,10,29,71,14,22,2,79,22,2,13,11,21,1,69,71,59,12,14,28,68,14,28,68,9,0,16,71,14,68,23,7,29,20,6,7,6,3,68,5,6,22,19,7,68,21,10,23,18,3,16,14,1,3,71,9,22,8,2,68,15,26,9,6,1,68,23,14,23,20,6,11,9,79,11,21,79,20,11,14,10,75,79,16,15,6,23,71,29,1,5,6,22,19,7,68,4,0,9,2,28,68,1,29,11,10,79,35,8,11,74,86,91,68,52,0,68,19,7,1,71,56,11,21,11,68,5,10,7,6,2,1,71,7,17,10,14,10,71,14,10,3,79,8,14,25,1,3,79,12,2,29,1,71,0,10,71,10,5,21,27,12,71,14,9,8,1,3,71,26,23,73,79,44,2,79,19,6,28,68,1,26,8,11,79,11,1,79,17,9,9,5,14,3,13,9,8,68,11,0,18,2,79,5,9,11,68,1,14,13,19,7,2,18,3,10,2,28,23,73,79,37,9,11,68,16,10,68,15,14,18,2,79,23,2,10,10,71,7,13,20,79,3,11,0,22,30,67,68,19,7,1,71,8,8,8,29,29,71,0,2,71,27,12,2,79,11,9,3,29,71,60,11,9,79,11,1,79,16,15,10,68,33,14,16,15,10,22,73 diff --git a/combination.hs b/combination.hs new file mode 100644 index 0000000..a8399a4 --- /dev/null +++ b/combination.hs @@ -0,0 +1,30 @@ +-- n=5 max=5 -> 12345 +-- n=5 max=6 -> 12346, 12356, 12456, 13456, 23456 +-- n=5 max=7 -> 12347, 12357, 12367, 12457, 12467... + +-- n=1 max=1 -> 1 +-- n=1 max=2 -> 2 +-- n=1 max=3 -> 3 +-- +-- n=2 max=2 -> 12 +-- n=2 max=3 -> 13, 23 +-- n=2 max=4 -> 14, 24, 34 +-- n=2 max=5 -> 15, 26, 35, 45 +-- +-- n=3 max=3 -> 123 +-- n=3 max=4 -> 124, 134, 234 +-- n=3 max=5 -> 125, 135, 235, 145, 245, 345 (n=2,max=2 ; n=2,max=3 ; n=2,max=4)++[5] +combination :: (Ord a) => Int -> a -> [a] -> [[a]] +combination 0 max list = [] +combination n max (x:xs@(y:ys)) + | x>max = [] + | n==1 && + x<=max && y>max = [[x]] + | otherwise = ( map (\z -> x:z) $ combination (n-1) max xs ) + ++ combination n max xs + +all_combinations n xs = foldr (++) [] $ map (\i -> combination n (xs!!i) xs) [(n-1)..] + +main = do + putStrLn $ show $ combination 5 5 [1..] + mapM_ putStrLn (map show $ take 50 $ all_combinations 5 [1,3..]) diff --git a/dictionnary.c b/dictionnary.c new file mode 100644 index 0000000..d58bfaa --- /dev/null +++ b/dictionnary.c @@ -0,0 +1,92 @@ +#include +#include +// Dictionnaries +typedef struct _node { + char final; + struct _node *sons[26]; +} node; + +typedef struct _node *Tree; +static Tree dictionary=NULL; +#define true 1 +#define false 0 + +Tree addword(Tree d, char *word) { + // fprintf(stderr,"addword %s\n",word); + int index = word[0] - 'A'; + int i; + if (d == NULL) { + d = (Tree)malloc(sizeof(node)); + d->final=false; + for (i=0; i<26; i++) { + d->sons[i]=NULL; + } + } + if (word[0] != '\0') { + d->sons[index]=addword(d->sons[index],word+1); + } else { + d->final = true; + } + return d; +} + +void _show_tree(Tree t, int nb_tabs) { + int i,j; + if (t == NULL) { + return; + } + for (j=0; jfinal) { fprintf(stderr, "*\n"); } + for (i=0;i<26;i++) { + if (t->sons[i] != NULL) { + fprintf(stderr,"%c\n",i+'A'); + _show_tree(t->sons[i],nb_tabs+1); + } + } +} + +void show_tree(Tree t) { + _show_tree(t,0); +} + +char is_element(Tree d, char *word) { + // fprintf(stderr,"is_element: %s\n", word); + if (d==NULL) { + // fprintf(stderr,"d is NULL\n"); + return false; + } + if (*word=='\0') { + // fprintf(stderr,"End of word\n"); + return d->final; + } + return is_element(d->sons[word[0]-'A'], word+1); +} + +#define MAX_WORD_SIZE 128 +void create_dico_from_file(char *filename) { + FILE *fd=fopen(filename,"r"); + int len; + char word[MAX_WORD_SIZE]; + char *w; + + if (fd == NULL) { + fprintf(stderr,"Unable to open the file: '%s'", filename); + exit(1); + } + + while (fgets(word, MAX_WORD_SIZE, fd)) { + for (w=word; (*w != '\n') && (*w != '\0'); w++) + ; + *w='\0'; + dictionary=addword(dictionary,word); + } + close(fd); +} + +int test(char *word) { + printf("%s: %d\n", word, is_element(dictionary,word)); +} + +// int main(int argc, char **argv) { +// create_dico_from_file("words-line.txt"); +// } diff --git a/generate_primes.rb b/generate_primes.rb new file mode 100644 index 0000000..94c8079 --- /dev/null +++ b/generate_primes.rb @@ -0,0 +1,37 @@ +limit=ARGV[0].to_i; + +crosslimit=Math.sqrt(limit); +sieve=[0]*limit; + +i=0; +while i