Skip to content

Commit

Permalink
Reimport from new repo
Browse files Browse the repository at this point in the history
  • Loading branch information
mippolito committed Feb 14, 2017
1 parent 19d3d95 commit 52cc360
Show file tree
Hide file tree
Showing 11 changed files with 408 additions and 0 deletions.
70 changes: 70 additions & 0 deletions numberphile_coins_puzzle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import itertools
import random
from collections import deque

H = True
T = False
HT = (H, T)


def _to_letters(seq):
return ''.join("H" if s else "T" for s in seq)


def counter_seq(seq):
"""
Returns the counter-sequence for the given sequence
"""
assert len(seq) == 3
return not seq[1], seq[0], seq[1]


def play_match(seqA, seqB):
"""
Plays a single match between two sequences.
Returns the winner.
"""
seq = deque(maxlen=3)

for _ in xrange(3):
seq.append(random.choice(HT))

while True:
lseq = tuple(seq)
if seqA == lseq: return seqA
if seqB == lseq: return seqB

seq.append(random.choice(HT))


def evaluate_prob(seqA, seqB, N=10000):
"""
Plays N matches between the two sequencies returning the total amount of won rounds
"""
victories = {seqA: 0, seqB: 0}
for _ in xrange(N):
winner = play_match(seqA, seqB)
victories[winner] += 1

return victories


all_starts = itertools.product(HT, repeat=3)
counters = {s: counter_seq(s) for s in all_starts}


if __name__ == '__main__':

N = int(1e6)
for expected_loser, expected_winner in counters.iteritems():

victories = evaluate_prob(expected_loser, expected_winner, N)
prob = float(victories[expected_winner]) / N

print "{} lost to {} {}% of the time".format(
_to_letters(expected_loser),
_to_letters(expected_winner),
prob * 100)
34 changes: 34 additions & 0 deletions problem1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"""
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
Answer:
233168
"""


import itertools
from utilities import lower_than


LIMIT=1000
ANSWER=233168


def multiples(n):
"""
Yields all the multiples of n (to infinity)
"""
for i in itertools.count(start=1):
yield i*n

threes = itertools.takewhile(lower_than(LIMIT), multiples(3))
fives = itertools.takewhile(lower_than(LIMIT), multiples(5))

# It's important to have a set here as there are numbers that are divisible by both 3 and 5
# If you don't use a set these numbers are counted twice and the answer is not correct
answer = sum(set(itertools.chain(threes, fives)))
assert answer == ANSWER

print answer

22 changes: 22 additions & 0 deletions problem14.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from utilities import lower_than
from itertools import count, imap, takewhile

from functools import lru_cache

limit = 1e6


@lru_cache
def collatz_len(n):

if n == 1:
return 1
else:
return 1 + collatz_len((3*n + 1) if (n % 2) else (n / 2))


answer = max(imap(collatz_len, takewhile(lower_than(limit), count(start=1))), key=lambda t: t[1])
print(answer)
19 changes: 19 additions & 0 deletions problem2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
"""

import itertools
from utilities import lower_than, fibonacci


LIMIT = 4e6

seq = itertools.takewhile(lower_than(LIMIT), fibonacci())
answer = sum(itertools.ifilter(lambda n: (n % 2) == 0, seq))

print answer

51 changes: 51 additions & 0 deletions problem23.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
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.
"""

import utilities

smallest_abn = 12
upper_limit = 28123

cache = {n: (n == smallest_abn) for n in xrange(smallest_abn + 1)}


def is_abundant(n):
try:
return cache[n]
except KeyError:
retval = (sum(utilities.divisors(n, only_proper=True)) > n)
cache[n] = retval
return retval


def is_sum_of_abundants(n):
for a in xrange(smallest_abn, (n + 1)):
if not is_abundant(a):
continue
elif is_abundant(n - a):
return True
else:
return False


if __name__ == '__main__':
numbers = xrange(upper_limit + 1)
print sum(n for n in numbers if not is_sum_of_abundants(n))
14 changes: 14 additions & 0 deletions problem25.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from utilities import fibonacci

n_digits = 1000
M = 10**(n_digits - 1)

for i, f in enumerate(fibonacci()):
if f >= M:
break

# The +1 is necessary because we index from 0, math starts from 1
print i + 1
23 changes: 23 additions & 0 deletions problem3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
"""

import itertools
import math

from utilities import primes, lower_than

number = 600851475143
limit = int(math.floor(math.sqrt(number)))

answer = 1
for p in itertools.takewhile(lower_than(limit), primes()):
if not number % p:
answer = p

print answer
42 changes: 42 additions & 0 deletions problem35.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

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

from collections import deque

import utilities

pc = utilities.PrimeCache()


def rotate(s, n):
d = deque(s)
d.rotate(n)
return ''.join(d)


def rotations(s):
for n in xrange(len(s)):
yield rotate(s, n)


def is_circular_prime(n):
retval = all(pc.is_prime(int(r)) for r in rotations(str(n)))
return retval


if __name__ == '__main__':
count = 0
for n in xrange(2, int(1e6)):
if is_circular_prime(n):
count += 1
print count
12 changes: 12 additions & 0 deletions problem7.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import itertools
from utilities import primes


N = int(1e4)
answer = next(itertools.islice(primes(), N, N + 1))

print answer

35 changes: 35 additions & 0 deletions problem9.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from utilities import lower_than
import itertools
import math


N = 1000


def is_perfect_square(n):
s = math.sqrt(n)
return s == int(s)


def find_tuple():

for a in itertools.takewhile(lower_than(N-1), itertools.count(1)):
for b in itertools.takewhile(lower_than(N-a), itertools.count(a+1)):
c = math.sqrt(a*a + b*b)
if a + b + c == N:
return a, b, int(c)
else:
raise ArithmeticError("Not found!")


a, b, c = find_tuple()

assert a*a + b*b == c*c
assert a + b + c == N

print a, b, c
print a * b * c

Loading

0 comments on commit 52cc360

Please sign in to comment.