## Project Euler个人解答(Problem 51~60)

2013年12月28日 发表评论 阅读评论

# Problem 51:Prime digit replacements

By replacing the 1st digit of the 2-digit number *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.

 1 2 3 4 5 6 7 8 9 10 0 6 6 0 6 6 0 6 6 0 6 1 7 7 10 7 7 10 7 7 10 7 2 7 7 10 7 7 10 7 7 10 7

• 最后一位必须是1,3,7,9其中之一
• 除去最后一位，剩余位数至少有3个0或者三个1或者三个2
• 这个数本身是个质数【顺便保证了这个数不可能被3整除】

[0, 1, 1, 1, 0]，[1, 0, 1, 1, 0]
[1, 1, 0, 1, 0]，[1, 1, 1, 0, 0]

[0, 0, 1, 1, 1, 0]，[0, 1, 0, 1, 1, 0]
[0, 1, 1, 0, 1, 0]，[0, 1, 1, 1, 0, 0]
[1, 0, 0, 1, 1, 0]，[1, 0, 1, 0, 1, 0]
[1, 0, 1, 1, 0, 0]，[1, 1, 0, 0, 1, 0]
[1, 1, 0, 1, 0, 0]，[1, 1, 1, 0, 0, 0]

### Code：Python

#判断是否是质数
def PrimeQ(n):
for i in range(2,int(sqrt(n))+1):
if n%i == 0:
return False;
return True;

#生成n挑k个数的模板，比如bits=5,k=3，返回会类似[1,0,1,0,1]
def NPickK(bits,k):
if k == 0:
yield [0]*bits
elif k == bits:
yield [1]*k
else:
for first in [0,1]:
for sub in NPickK(bits-1,k-first):
yield [first]+sub

#生成实际可用的模板，比如bit=7
#那么会生成NPickK(6,3)和NPickK(6,6)的模板，然后最后一位补零

#判断模板内是不是同一个数
return len(set(num)) == 1

#计算根据模板替换后质数的个数
counter = 0;
strlist = [str(dig) if mask[x]==1 else strlist[x]
counter += PrimeQ(int(''.join(strlist)))
return counter

#测试这个数是否有符合条件
def template_test(n):
strlist = list(str(n))
return True
return False

#main
num = 1000
while True:
#是否是1,3,7,9结尾
if not mod(num,10) in [1,3,7,9]:
pass
#是不是有超过3个的0,1,2
elif not (list(str(num)).count('0')>=3 or \
list(str(num)).count('1')>=3 or \
list(str(num)).count('2')>=3):
pass
elif not PrimeQ(num):
pass
elif not template_test(num):
pass
else:
print num;
break
num += 1


# Problem 52:Permuted multiples

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.

125874和它的二倍，251748, 包含着同样的数字，只是顺序不同。

### Code：Python

def sortchar(n):
L = list(str(n))
L.sort()
return L

def QQ(n):
if sortchar(n)==\
sortchar(2*n)==\
sortchar(3*n)==\
sortchar(4*n)==\
sortchar(5*n)==\
sortchar(6*n):
return True
return False

bit = 3
k = 102
while True:
if QQ(k):
print k
break
k += 3
if k*6 > 10**bit:
k = 10**bit+2
bit += 1


# Problem 53:Combinatoric selections

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, $^5C_3=10$.

In general,

$^nC_r=\dfrac{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: $^{23}C_{10}= 1144066$ .

How many, not necessarily distinct, values of $^nC_r$, for 1 ≤ n ≤ 100, are greater than one-million?

123, 124, 125, 134, 135, 145, 234, 235, 245, and 345

$^nC_r=\dfrac{n!}{r!(n-r)!}$,其中 r ≤ n, n! = n×(n−1)×...×3×2×1, 并且0! = 1.
n = 23时产生第一个超过一百万的数:$^{23}C_{10}= 1144066$ .

$\dfrac{^nC_{r+1}}{^nC_r}=\dfrac{n-r}{r+1}$

### Code：Python

counter = 0;
for n in range(23,101):
d = n;
r = 1;
while d < 1000000 and r <= int(n/2):
d = d * (n-r)/(r+1)
r += 1
counter += n-2*r+1
print counter


# Problem 54:Poker hands

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

The file, 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?

• High Card: 最高值的牌.
• One Pair: 两张面值一样的牌.
• Two Pairs: 两个值不同的One Pair.
• Three of a Kind: 三张面值一样的牌.
• Straight: 所有的牌面值为连续数值.
• Flush: 所有的牌花色相同.
• Full House: Three of a Kind 加一个One Pair.
• Four of a Kind: 四张牌面值相同.
• Straight Flush: 所有的牌花色相同并且为连续数值.
• Royal Flush: 10，J，Q，K和A，并且为相同花色。

2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.

 局 玩家 1 玩家 2 胜利者 1 5H 5C 6S 7S KD 一对5 2C 3S 8S 8D TD 一对8 玩家 2 2 5D 8C 9S JS AC 最大面值牌A 2C 5C 7D 8S QH 最大面值牌Q 玩家 1 3 2D 9C AS AH AC 三个A 3D 6D 7D TD QD 方片Flush 玩家 2 4 4D 6S 9H QH QC 一对Q 最大牌9 3D 6D 7H QD QS 一对Q 最大牌7 玩家 1 5 2H 2D 4C 4D 4S 三个4的Full House 3C 3D 3S 9S 9D 三个3的Full House 玩家 1

### Code：Mathematica

PokeInfo = Import["poker.txt", "Table"];

GetWinner[game_] := Block[{p1p, p2p, p1c, p2c, lv1, lv2},
(*替换成数字，并排序*)
p1p = ToExpression[(StringTake[#, 1] & /@ game[[1 ;; 5]]) /.
{"A" ->14, "K" -> 13, "Q" -> 12, "J" -> 11, "T" -> 10}] // Sort;
p2p = ToExpression[(StringTake[#, 1] & /@ game[[6 ;; 10]]) /.
{"A" -> 14, "K" -> 13, "Q" -> 12,"J" -> 11, "T" -> 10}] // Sort;
(*分别获取玩家的牌*)
p1c = StringTake[#, {2}] & /@ game[[1 ;; 5]];
p2c = StringTake[#, {2}] & /@ game[[6 ;; 10]];
(*获得玩家的牌的类型*)
lv1 = GetLevel[p1p, p1c];
lv2 = GetLevel[p2p, p2c];
WHOWIN[lv1, lv2]]

GetLevel[p_, c_] := Block[{},
Which[
(*等级1000，同花顺*)
Length@Union@c == 1 && Differences[p] === {1, 1, 1, 1},{100,Reverse[p]},
(*等级99，四带一*)
Sort[Tally[p][[All, 2]]] === {1,4},
{99, {Select[Tally[p], #[[2]] == 4 &][[1, 1]],
Select[Tally[p], #[[2]] == 1 &][[1, 1]]}},
(*等级98，三带二*)
Sort[Tally[p][[All, 2]]] === {2,3},
{98, {Select[Tally[p], #[[2]] == 3 &][[1, 1]],
Select[Tally[p], #[[2]] == 2 &][[1, 1]]}},
(*等级97，一色*)
Length@Union@c == 1 , {97, Reverse[p]},
(*等级96，一条龙*)
Differences[p] === {1, 1, 1, 1}, {96, Reverse[p]},
(*等级95，三张一样*)
Sort[Tally[p][[All, 2]]] === {1, 1,3},{95, {Select[Tally[p], #[[2]] == 3 &][[1, 1]],
Select[Tally[p], #[[2]] == 1 &][[All, 1]] // Sort // Reverse} //Flatten},
(*等级94，两对*)
Sort[Tally[p][[All, 2]]] === {1, 2, 2},
{94, {Select[Tally[p], (#[[2]] == 2 &)][[All, 1]]//Sort//Reverse,
Select[Tally[p], #[[2]] == 1 &][[1, 1]]} // Flatten},
(*等级93，一对*)
Sort[Tally[p][[All, 2]]] === {1, 1, 1, 2},
{93, {Select[Tally[p], (#[[2]] == 2 &)][[All, 1]],
Select[Tally[p], #[[2]] == 1 &][[All, 1]] // Sort // Reverse} //Flatten},
(*啥都没有，等级为最大那张牌的点*)
True, {Max[p], Reverse[p]}]
]

(*判断胜负*)
WHOWIN[v1_, v2_] := Block[{},
Which[v1[[1]] > v2[[1]], 1,
v1[[1]] < v2[[1]], 2,
v1[[2, 1]] > v2[[2, 1]], 1,
v1[[2, 1]] < v2[[2, 1]], 2,
v1[[2, 2]] > v2[[2, 2]], 1,
v1[[2, 2]] < v2[[2, 2]], 2,
v1[[2, 3]] > v2[[2, 3]], 1,
v1[[2, 3]] < v2[[2, 3]], 2,
v1[[2, 4]] > v2[[2, 4]], 1,
v1[[2, 4]] < v2[[2, 4]], 2,
v1[[2, 5]] > v2[[2, 5]], 1,
v1[[2, 5]] < v2[[2, 5]], 2,
True, 0
]]

(*计算A胜了多少场*)
Select[PokeInfo, GetWinner[#] == 1 &] // Length


# Problem 55:Lychrel numbers

If we take 47, reverse and add, 47 + 74 = 121, which is palindromic.

Not all numbers produce palindromes so quickly. For example,

349 + 943 = 1292,
1292 + 2921 = 4213
4213 + 3124 = 7337

That is, 349 took three iterations to arrive at a palindrome.

Although no one has proved it yet, it is thought that some numbers, like 196, never produce a palindrome. A number that never forms a palindrome through the reverse and add process is called a Lychrel number. Due to the theoretical nature of these numbers, and for the purpose of this problem, we shall assume that a number is Lychrel until proven otherwise. In addition you are given that for every number below ten-thousand, it will either (i) become a palindrome in less than fifty iterations, or, (ii) no one, with all the computing power that exists, has managed so far to map it to a palindrome. In fact, 10677 is the first number to be shown to require over fifty iterations before producing a palindrome: 4668731596684224866951378664 (53 iterations, 28-digits).

Surprisingly, there are palindromic numbers that are themselves Lychrel numbers; the first example is 4994.

How many Lychrel numbers are there below ten-thousand?

NOTE: Wording was modified slightly on 24 April 2007 to emphasise the theoretical nature of Lychrel numbers.

349 + 943 = 1292,
1292 + 2921 = 4213
4213 + 3124 = 7337

10000以下一共有多少个Lychrel数？

### Code：Python

def GetPalindromic(n):
return int(''.join(list(str(n))[::-1]))

def IsPalindromic(n):
return n == GetPalindromic(n)

def IsLychrel(n):
cc = 0
n = n + GetPalindromic(n)
while cc <= 50:
if IsPalindromic(n):
return False
n = n + GetPalindromic(n)
cc += 1
return True

result = filter(IsLychrel,range(10001))
print len(result)


### Code：Mathematica

GetHW[x_] := FromDigits@Reverse@IntegerDigits[x]
IsNotHW[x_] := FromDigits@Reverse@IntegerDigits[x] != x

IsLychrel[t_] := Block[{x = t + GetHW[t], Result = True},
For[i = 1, i < = 50, i += 1,
If[IsNotHW[x], x = x + GetHW[x], Result = False; Break]];
Result]

Select[Range[1, 10000], IsLychrel] // Length


# Problem 56:Powerful digit sum

A googol (10100) is a massive number: one followed by one-hundred zeros; 100100 is almost unimaginably large: one followed by two-hundred zeros. Despite their size, the sum of the digits in each number is only 1.

Considering natural numbers of the form, ab, where a, b < 100, what is the maximum digital sum?

Python表示不甘示弱。。

### Code：Mathematica

Max@Table[Total@IntegerDigits@(a^b), {a, 1, 99}, {b, 1, 99}]


### Code：Python

print max([sum(map(int,list(str(a**b))))
for a in range(1,100)
for b in range(1,100)])


# Problem 57:Square root convergents

It is possible to show that the square root of two can be expressed as an infinite continued fraction.

$\sqrt{2}=1+\dfrac{1}{2+\dfrac{1}{2+\dfrac{1}{2+...}}}=1.414213...$

By expanding this for the first four iterations, we get:

1 + $\dfrac{1}{2}$ = 3/2 = 1.5
1 + $\dfrac{1}{2+\dfrac{1}{2}}$ = 7/5 = 1.4
1 + $\dfrac{1}{2+\dfrac{1}{2+\dfrac{1}{2}}}$= 17/12 = 1.41666...
1 + $\dfrac{1}{2+\dfrac{1}{2+\dfrac{1}{2+\dfrac{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?

2的平方根可以被表示为无限延伸的分数：

$\sqrt{2}=1+\dfrac{1}{2+\dfrac{1}{2+\dfrac{1}{2+...}}}=1.414213...$

1 + $\dfrac{1}{2}$ = 3/2 = 1.5
1 + $\dfrac{1}{2+\dfrac{1}{2}}$ = 7/5 = 1.4
1 + $\dfrac{1}{2+\dfrac{1}{2+\dfrac{1}{2}}}$= 17/12 = 1.41666...
1 + $\dfrac{1}{2+\dfrac{1}{2+\dfrac{1}{2+\dfrac{1}{2}}}}$ = 41/29 = 1.41379...

### Code：Python

a = 2
b = 3
counter = 0
for i in range(1,1001):
a,b = b+a,2*a+b
if len(str(b)) > len(str(a)):
counter += 1
print counter


### Code：Mathematica

Select[NestList[{2 #[[2]] + #[[1]], #[[2]] + #[[1]]} &, {3, 2}, 1000],
Length[IntegerDigits[#[[1]]]] > Length[IntegerDigits[#[[2]]]] &] // Length


# Problem 58:Spiral primes

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%?

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

### Code：Python

def PrimeQ(n):
if n <= 1:
return False
for i in xrange(2,int(n**0.5+1)):
if n%i == 0:
return False;
return True;

k = 1
dif = 2
prime_counter = 0
while True:
k += dif * 4
dif += 2
prime_counter += PrimeQ(k+dif)
prime_counter += PrimeQ(k+2*dif)
prime_counter += PrimeQ(k+3*dif)
if prime_counter*10<(2*dif+1):
print dif+1
break


# Problem 59:XOR decryption

Each character on a computer is assigned a unique code and the preferred standard is ASCII (American Standard Code for Information Interchange). For example, uppercase A = 65, asterisk (*) = 42, and lowercase k = 107.

A modern encryption method is to take a text file, convert the bytes to ASCII, then XOR each byte with a given value, taken from a secret key. The advantage with the XOR function is that using the same encryption key on the cipher text, restores the plain text; for example, 65 XOR 42 = 107, then 107 XOR 42 = 65.

For unbreakable encryption, the key is the same length as the plain text message, and the key is made up of random bytes. The user would keep the encrypted message and the encryption key in different locations, and without both "halves", it is impossible to decrypt the message.

Unfortunately, this method is impractical for most users, so the modified method is to use a password as a key. If the password is shorter than the message, which is likely, the key is repeated cyclically throughout the message. The balance for this method is using a sufficiently long password key for security, but short enough to be memorable.

Your task has been made easy, as the encryption key consists of three lower case characters. Using cipher1.txt (right click and 'Save Link/Target As...'), a file containing the encrypted ASCII codes, and the knowledge that the plain text must contain common English words, decrypt the message and find the sum of the ASCII values in the original text.

### Code：Mathematica

(*读取文件，转为数字*)
cipher = ToExpression@StringSplit[ToLowerCase@Import["cipher1.txt"], ","];

(*获得加密原文*)
decodetext[key_, ci_] := Block[{test, result},
(*循环密钥使之与密文等长*)
test = Table[key[[Mod[i - 1, 3] + 1]], {i, 1, Length[ci]}];

(*译码，key是密钥，ci是密文,返回a,e,i,s的词频数*)
decode[key_, ci_] := Total[
Count[decodetext[key, ci], #]&/@(ToCharacterCode/@{"e", "a", "i", "s"}//Flatten)]

(*测试所有加密方案*)
ParallelTable[{{a, b, c}, decode[{a, b, c}, cipher]},
{a, 97, 122}, {b, 97, 122}, {c, 97, 122}];

(*找出加密方案中最佳的那个*)
(Reverse@SortBy[Flatten[%, 2], Last])//First

(*获得原文全部ASCII码之和*)
decodetext[First@%, cipher] // Total

(*统计the*)
decode2[key_, ci_]:=StringCount[FromCharacterCode@decodetext[key, ci], "the"]

(*获取原文*)
decodetext[First@%, cipher]//FromCharacterCode


# Problem 60:Prime pair sets

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.

### Code：C++

#define T 100000000

int IsPrime[T] = {1};
int* primelist = NULL;

//初始化质数表
void init()
{
for(int i = 0;i < T;i++)
IsPrime[i] = 1;

IsPrime[0] = -1;
IsPrime[1] = -1;
}

//筛选法找质数
void Seive()
{
int counter = T-2;
for(int i = 2;i <= T/2;i++)
{
if(IsPrime[i] != 1)
continue;
int j = 2*i;
while(j < T)
{
if(IsPrime[j] == 1)
counter--;
IsPrime[j] = -1;
j += i;
}
}

primelist =new int[counter];
int cc = 0;
for(int i = 0;i < T;i++)
if(IsPrime[i] == 1)
primelist[cc++] = i;
}

//数字拼接，673+123=673123
int join(int a,int b)
{
int k = int(log10(double(a))+1);
return int(b*pow(10.0,k)+a);
}

//判断两个数连接起来后是不是质数
bool Judge(int i,int j)
{
return IsPrime[join(i,j)] == 1 && IsPrime[join(j,i)] == 1;
}

//判断list里面最后一个数和前面每个数连接起来后都是质数
int JudgeList(int list[],int num)
{
for(int i = 0;i < num-1;i++)
if(!Judge(list[i],list[num-1]))
return 0;
return 1;
}

//递归求解，i是前一个数，idx是现在算到第几个数了
void figure(int i,int list[],int idx)
{
if(idx == 6)
{
for(int d = 0;d < 5;d++)
cout<<list[d]<<"  ";
system("pause");
}
for(int j = i-1;j >= 5-idx;j--)
{
list[idx-1] = primelist[j];
if (!JudgeList(list,idx))
continue;
figure(j,list,idx+1);
}
}

int main(int argc,char* argv[])
{
init();
Seive();

int list[5];
for(int i = 4;i < T;i++)
{
list[0] = primelist[i];
figure(i,list,2);
}
return 0;
}


【完】

1. 2013年12月28日13:26 | #1

看起来好高端，啊哈哈

• 2013年12月28日13:29 | #2

其实一点也不。。只是练练算法题和编程。。。防止头脑老化。。

• 2013年12月28日13:30 | #3

真上进

• 2013年12月28日13:33 | #4

爱好而已。。。将来找工作希望有点用。。

2. 2014年1月5日21:07 | #5

pe57：Count[NestList[{2 #2 + #, #2 + #} & @@ # &, {3, 2}, 1000], {a_, b_} /; IntegerLength@a > IntegerLength@b]

• 2014年1月6日00:04 | #6

研读完您的留言代码，获益良多，学会了很多新函数和思想，非常感谢！

3. 2014年11月10日17:55 | #7

打扰了！， 关于PE51，我找到个11113，替换三个数之后得{11113, 19993, 22123, 31333, 41443, 77713, 81883, 88813}都是质数，一共刚好8个，，这样行不？

• 2014年11月10日18:00 | #8

对于56**3，两个星号替换的数字必须一样

• 2014年11月11日08:45 | #9

哈哈，，有道理，，看题不仔细

4. 2014年11月11日23:22 | #10