Решаю следующую проблему на сайте кодирования. В некоторых крайних случаях в тестах (скрытые тесты) он не работает, но я не уверен, что это такое. Кто-нибудь видит какие-либо проблемы с этим?
Проблема: пусть A
будет строкой всех простых чисел, последовательно сжатых вместе (т. Е. 235711131719...
). Учитывая индекс n
, вернуть строку из 5 цифр, где первая цифра находится в индексе n
в A.
Например foo(0) => 23571
и foo(10) => 19232
Вот мой код:
def gen_primes():
A = {}
i = 2
while True:
if i not in A:
yield i
A[i * i] = [i]
else:
for p in A[i]:
A.setdefault(p + i, []).append(p)
del A[i]
i += 1
def answer(n):
counter = 0
prime_string = ""
for p in gen_primes():
if (counter >= n):
prime_string += str(p)
counter += len(str(p))
if len(prime_string) >= 5:
break
return prime_string[:5]
3 ответа
Я думаю, что это может сломаться для простых чисел с более чем одной цифрой:
Предположим, что мы пришли к простым числам с тремя цифрами, например 103. Counter
равно 10, а n
равно 11 (это всего лишь пример, я не знаю, появится ли это точное созвездие)
Тогда нам нужно будет использовать цифры «03» из «103». Но поскольку counter
меньше, чем n
, все простое число пропускается. Программа продолжится с 107.
Вы можете исправить это, полностью удалив counter
: всегда добавляйте простые числа к строке, выходите из цикла, если длина строки равна n+5
или больше.
РЕДАКТИРОВАТЬ:
Я проверил ваш код: например, answer(5)
и answer(6)
. С вашим кодом оба вызова приводят к «13171». Вторая цифра «11» пропускается.
С этим кодом:
def answer(n):
counter = 0
prime_string = ""
for p in gen_primes():
prime_string += str(p)
if len(prime_string) >= n+5:
break
return prime_string[n:n+5]
Они приводят к
11317 # answer(5)
13171 # answer(6)
Вот мой ответ; он похож на @lhk, но использует скользящее окно вместо сохранения всей строки:
phil@haydn ~ $ python
Python 2.7.5+ (default, Sep 17 2013, 15:31:50)
[GCC 4.8.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def primegen(): # http://stackoverflow.com/a/20660551
... yield 2; yield 3 # prime (!) the pump
... ps = primegen() # sieving primes
... p = next(ps) and next(ps) # first sieving prime
... D, q, c = {}, p*p, p # initialize
... def add(x, s): # insert multiple/stride
... while x in D: x += s # find unused multiple
... D[x] = s # save multiple/stride
... while True: # infinite list
... c += 2 # next odd candidate
... if c in D: # c is composite
... s = D.pop(c) # fetch stride
... add(c+s, s) # add next multiple
... elif c < q: yield c # c is prime; yield it
... else: # (c == q) # add sqrt(c) to sieve
... add(c+p+p, p+p) # insert in sieve
... p = next(ps) # next sieving prime
... q = p * p # ... and its square
...
>>> def primeSubstr(n): # nth character in concatenated primes
... ps = primegen() # sequence of prime numbers
... i, s = 0, '' # current index, sliding window
... while True: # do ... until i == n
... if len(s) < 5: # sliding window too small
... s+=str(next(ps)) # add next prime to window
... elif i < n: # not yet to target index
... i, s = i+1, s[1:] # slide window to right
... else: return s[:5] # return desired substring
...
>>> primeSubstr(0)
'23571'
>>> primeSubstr(5)
'11317'
>>> primeSubstr(10)
'19232'
>>> primeSubstr(15)
'93137'
>>> primeSubstr(20)
'41434'
>>> primeSubstr(1000)
'98719'
>>> CTRL-D
Я буду обсуждать эту проблему завтра в моем блоге.
Это похоже на работу для itertools, как насчет этого
>>> from sympy import sieve
>>> from itertools import islice, chain
>>> def primeSubStr(n):
primes=iter(sieve)
next(primes)
return "".join( islice( chain.from_iterable(map(str,primes)), n, n+5))
>>> primeSubStr(0)
'23571'
>>> primeSubStr(10)
'19232'
>>> primeSubStr(5)
'11317'
>>> primeSubStr(15)
'93137'
>>> primeSubStr(20)
'41434'
>>> primeSubStr(1000)
'98719'
>>> primeSubStr(2000)
'98940'
>>>
Для простоты я использую sympy.sieve для получения простых чисел, но любой метод получения простых чисел будет работать нормально, например, здесь < / a> например.
Теперь самое интересное: карта достаточно очевидна: мы получаем поток "2", "3", "5", "7", "11", "13", ... "101", "103", ...
, а затем chain.from_iterable
этот поток выводится из потока одиночных цифр "2", "3", "5", "7", "1","1", "1","3", ... "1","0","1", "1","0","3", ...
и, наконец, с помощью islice
мы берем ту часть, которую хотим, и присоединяемся к ней для получения окончательного результата
Похожие вопросы
Связанные вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.