Решаю следующую проблему на сайте кодирования. В некоторых крайних случаях в тестах (скрытые тесты) он не работает, но я не уверен, что это такое. Кто-нибудь видит какие-либо проблемы с этим?

Проблема: пусть 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]    
6
user7373175 4 Янв 2017 в 11:36
Мне нравится. Может быть, это медленно для крайних случаев, и сайт, который вы используете, работает в режиме "тайм-аута"? В so.
 – 
Matthias
4 Янв 2017 в 11:48
Мой ответ решил ваш вопрос?
 – 
lhk
17 Янв 2017 в 16:43

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)
3
lhk 4 Янв 2017 в 15:28

Вот мой ответ; он похож на @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

Я буду обсуждать эту проблему завтра в моем блоге.

0
user448810 10 Янв 2017 в 05:35

Это похоже на работу для 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 мы берем ту часть, которую хотим, и присоединяемся к ней для получения окончательного результата

0
Community 23 Май 2017 в 14:53