2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 задача из Project Euler
Сообщение22.02.2012, 15:05 


28/03/10
68
В общем надо найти наибольший простой делитель числа 600851475143. В принципе задачу решил, но решение не очень нравиться. Кстати вот оно:

Используется синтаксис Python
 
from math import *
n=0
for c in range(2, int(sqrt(600851475143))):
    for i in range(2, c):
        if c%i==0:
            n=n+1
    if n==0 and 600851475143%c==0:
        print c
    n=0
 


он выдает постепенно ответы и я думал выберу наибольший и все. На первой минуте выдал 4 ответа: 71, 839,1471,6857 и дальше считал. Я попробовал 6857 в ответы ввести и ответ оказался правильным. Но удовлетворения не получил. Можно ли как нибудь оптимизировать мой код? В принципе в интернете есть много алгоритмов нахождения простых чисел, и они дают выйгрыш в более чем 1000 раз, но суть вопроса можно ли мой алгоритм оптимизировать?

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение22.02.2012, 17:19 
Заслуженный участник


31/12/05
1517
Как минимум можно при нахождении очередного делителя заменить 600851475143 на частное от деления.

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение22.02.2012, 18:37 


28/03/10
68
Цитата:
Как минимум можно при нахождении очередного делителя заменить 600851475143 на частное от деления.

так! спасибо! Что ещё?

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение22.02.2012, 19:08 
Заслуженный участник


04/05/09
4587
Alibek24 в сообщении #541631 писал(а):
Что ещё?
Проверка простоты очередного делителя занимает больше времени, чем если бы вы пробовали делить на все натуральные числа подряд. Если вы сделаете то, что сказал tolstopuz, то эта проверка не нужна - простые делители и так будут первыми. Только не забудьте, что простой делитель может встретиться несколько раз.

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение22.02.2012, 23:16 


28/03/10
68
в общем погуглил, и наткнулся на статью на хабре: http://habrahabr.ru/blogs/algorithm/122538/ там в принципе методы понятны. в общем с этой задачей пока закончил, теперь ещё одна появилась. Вот текст задачи:

2520 - самое маленькое число, которое делится без остатка на все числа от 1 до 10.
Какое самое маленькое число делится нацело на все числа от 1 до 20?

Конечно тупой алгоритм, но всё же:

Используется синтаксис Python
n=0
for i in range(1, 100000000, 2):
    for j in range(1, 21):
        if i%j==0:
            n=n+1
            if n==20:
                print i
            else:
                print "no"
    n=0


нотик не потянул таких мощностей. Может как то можно ускорить процесс, или подскажите другой алгоритм?

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение22.02.2012, 23:48 
Заслуженный участник


09/09/10
3729
Alibek24 в сообщении #541762 писал(а):
Какое самое маленькое число делится нацело на все числа от 1 до 20?
$\text{НОК}(1,2,\dots,20)$.
Как искать? Во-первых, $\text{НОК}(a_1,a_2,\dots,a_n)=\text{НОК}\left(\text{НОК}(a_1,a_2,\dots,a_{n-1}), a_n\right)$. Во-вторых, $\text{НОК}(a,b)=\dfrac{ab}{(a,b)}$.

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение23.02.2012, 06:22 


28/03/10
68
это не НОК! надо найти наименьшее число делящееся на все числа от 1 до 20

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение23.02.2012, 07:04 


24/05/09

2054
232792560

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение23.02.2012, 08:26 
Заслуженный участник


20/12/10
9062
Alibek24 в сообщении #541762 писал(а):
2520 - самое маленькое число, которое делится без остатка на все числа от 1 до 10. Какое самое маленькое число делится нацело на все числа от 1 до 20?
Это же упражнение для 6-классников: они как раз умеют составлять НОК по известному правилу.
Alibek24 в сообщении #541826 писал(а):
это не НОК!
Это именно НОК.

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение23.02.2012, 15:19 


28/03/10
68
nnosipov в сообщении #541833 писал(а):
Alibek24 в сообщении #541762 писал(а):
2520 - самое маленькое число, которое делится без остатка на все числа от 1 до 10. Какое самое маленькое число делится нацело на все числа от 1 до 20?
Это же упражнение для 6-классников: они как раз умеют составлять НОК по известному правилу.
Alibek24 в сообщении #541826 писал(а):
это не НОК!
Это именно НОК.


В общем я был не прав, признаю;)
Решил как всегда не очень красиво, может кто подскажет как можно избежать 20-кратного написания нок???

код: [ скачать ] [ спрятать ]
Используется синтаксис Python
 def nod(x, y):
    if x>y:
        for j in range(1,y+1):
            if x%j==0 and y%j==0:
                m=j
    else:
        for s in range(1,x+1):
            if y%s==0 and x%s==0:
                m=s
    return m

def nok(x1, y1):
    return (x1*y1)/(nod(x1, y1))

f=0
f=nok(2,nok(3,nok(4,nok(5,nok(6,nok(7,nok(8,nok(9,nok(10,nok(11,nok(12,nok(13,nok(14,nok(15,nok(16,nok(17,nok(18,nok(19,20))))))))))))))))))
   
print f

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение23.02.2012, 18:05 
Заслуженный участник


28/04/09
1933
Alibek24
Alibek24 в сообщении #541940 писал(а):
как можно избежать 20-кратного написания нок???
Завести временную переменную и произвести нахождение искомого числа в цикле.

Однако здесь можно относительно просто обойтись без программистских ухищрений, воспользовавшись для нахождения искомого числа очевидной формулой $f(n)=\prod\limits_{p\le n}p^{\left\lfloor\log_p n\right\rfloor}$ ($p$ $\text{---}$ простое число), с помощью которой $f(20)$ можно посчитать даже на непрограммируемом калькуляторе.

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение24.02.2012, 10:51 


28/03/10
68
EtCetera в сообщении #541985 писал(а):
Alibek24
Alibek24 в сообщении #541940 писал(а):
как можно избежать 20-кратного написания нок???
Завести временную переменную и произвести нахождение искомого числа в цикле.

Однако здесь можно относительно просто обойтись без программистских ухищрений, воспользовавшись для нахождения искомого числа очевидной формулой $f(n)=\prod\limits_{p\le n}p^{\left\lfloor\log_p n\right\rfloor}$ ($p$ $\text{---}$ простое число), с помощью которой $f(20)$ можно посчитать даже на непрограммируемом калькуляторе.


я тоже так думал, с временной переменной)))

а как это формула называется?

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение26.02.2012, 22:48 


28/03/10
68
Ещё одна задачка!
В общем вот условие:

Последовательность треугольных чисел образуется путем сложения натуральных чисел. К примеру, 7-ое треугольное число будет 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. Первые десять треугольных чисел:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...

Перечислим делители первых семи треугольных чисел:

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
Как мы видим, 28 - первое треугольное число, у которого более пяти делителей.

Каково первое треугольное число, у которого более пятисот делителей?

Вот моё топорное решение, которое при 500 делителях уже ищет долго-долго:
Код:
m=0
n=[]

x=0
y=10001
for r in range(2, 10001):
    for j in range(1, r):
        m=m+j
    n.append(m)
    m=0

for k in range(9999):
    if n[k]%2==0:
        for l in range(1,int(n[k]/2)+1):
            if n[k]%l==0:
                x+=1
    if x==500:
        break
       
    x=0
print n[k]

Как можно оптимизировать, или это задача не так решается? Нашел в интернете инфу, что надо воспользоваться факторизацией чисел. В общем математическая часть понятна, а вот как это перенести на компьютерный язык теряюсь. В общем остановился вот на этом:
Код:
m=0
n=[]


x=0
y=1001
for r in range(2, 1001):
    for j in range(1, r):
        m=m+j
    n.append(m)
    m=0

t=1000
lst=[]
a=range(t+1)
a[1]=0
i=2
while i<=t:
    if a[i]!=0:
        lst.append(a[i])
        for q in xrange(i, t+1, i):
            a[q]=0
    i+=1

l=0
d=0
h=0
w=[]
count=0
mul=1
for b in range(y-2):
    for s in range(t):
        while lst[s]<=n[b]:
            for d in range(n[b]):
                if n[b]%lst[s]==0:
                    l+=1
        w.append(l)
       
        for z in range(len(w)):
            count=w[z]+1
            mul=mul*count
       
        if mul>5:
            print n[b]
            break   
        l=0

При запускании ошибка Out of Range! Но это ладно можно подкорректировать. Тут уже видна ошибка, при делении например числа 28 на простые числа, как сделать так, что когда он делится на 2 что еще по циклу проверилось делится ли ещё раз на это простое число?

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение26.02.2012, 23:23 
Заслуженный участник


27/04/09
28128
Alibek24 в сообщении #543014 писал(а):
как сделать так, что когда он делится на 2 что еще по циклу проверилось делится ли ещё раз на это простое число?
Тут уже предлагали заменять число частным от деления на исследуемое простое. :roll:

 Профиль  
                  
 
 Re: задача из Project Euler
Сообщение27.02.2012, 08:43 


28/03/10
68
Цитата:
Тут уже предлагали заменять число частным от деления на исследуемое простое.

Ну я про это и спрашивал, вот единственное как в цикле это написать?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group