<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; AHK: Алгоритмы нахождения простых чисел до заданного целого числа]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=3460&amp;type=atom" />
	<updated>2009-07-28T22:34:31Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=3460</id>
		<entry>
			<title type="html"><![CDATA[AHK: Алгоритмы нахождения простых чисел до заданного целого числа]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=26555#p26555" />
			<content type="html"><![CDATA[<p>Следующие варианты кода сохраняют в текстовый файл строку, содержащую все простые числа до числа limit. Для наглядности в файл также выводится информация о количестве времени, понадобившемся для создания строки (без учёта времени записи в файл).<br /><a href="http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D1%88%D0%B5%D1%82%D0%BE_%D0%AD%D1%80%D0%B0%D1%82%D0%BE%D1%81%D1%84%D0%B5%D0%BD%D0%B0">Решето Эратосфена.</a><br /></p><div class="codebox"><pre><code>limit = 1000000

FileDelete, %A_Desktop%\Prime%limit%.txt

StartTime := A_TickCount

Is_Prime := Prime_Erat(limit, quantity := 0)

Time := A_TickCount - StartTime
sec_msec := SubStr(Time/1000, 1, -3)
min_sec_msec := sec_msec &gt;= 60 ? Floor((sec := SubStr(sec_msec, 1
    , -4))/60) &quot;.&quot; SubStr(&quot;00&quot; . Mod(sec, 60), -1) . SubStr(sec_msec, -3) : sec_msec

FileAppend,
(
Проверено: %limit%
Найдено: %quantity%
Время: %min_sec_msec%
Сохранено: %A_Desktop%\Prime%limit%.txt

%Is_Prime%
), %A_Desktop%\Prime%limit%.txt
Run, %A_Desktop%\Prime%limit%.txt

Prime_Erat(limit, ByRef quantity)  ; функция, возвращающая строку с простыми числами до limit
{
    #NoEnv
    SetBatchLines, -1  ; для скорости
    
; Необходимо провести вычёркивания кратных для всех простых чисел Prime, для которых
; Prime**2 &lt;= limit. Вычисляем ближайшее снизу целое число к квадратному корню из limit
    sqr_lim := Floor(Sqrt(limit))
    
    Prime := 2   ; первое простое число

; Вместо того, чтобы создавать массив из натуральных чисел до limit, и вычёркивать составные,
; для экономии времени создадим массив из составных чисел. Не входящие в него
; целые в пределах limit будут простыми
    While (Prime &lt;= sqr_lim)
    {
        if !Composite%Prime%    ; число, не входящее в массив — простое 
        {
            Is_Prime .= Prime &quot;, &quot;   ; запишем его сразу в строку, чтобы после не обращаться к нему повторно
            quantity++               ; счётчик простых чисел
            j := Prime * Prime
            While (j &lt;= limit)
            {
                Composite%j% := True   ; создаём массив из составных чисел
                j += Prime
            }
        }
        Prime++
    }

    While (Prime &lt;= limit)    ; запишем в строку остальные простые числа (бОльшие, чем sqr_lim)
    {
        if !Composite%Prime%
        {
            Is_Prime .= Prime &quot;, &quot;
            quantity++
        }
        Prime++
    }
    Return SubStr(Is_Prime, 1, -2)
}</code></pre></div><p><a href="http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D1%88%D0%B5%D1%82%D0%BE_%D0%90%D1%82%D0%BA%D0%B8%D0%BD%D0%B0">Решето Аткина.</a><br />Без комментариев. Чтобы понять, как работает этот код, см. <a href="http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D1%88%D0%B5%D1%82%D0%BE_%D0%90%D1%82%D0%BA%D0%B8%D0%BD%D0%B0">статью</a>, <a href="http://cr.yp.to/papers/primesieves-19990826.pdf">источник</a>, а также <a href="http://e-science.ru/forum/index.php?showtopic=12506&amp;st=80&amp;p=88360&amp;#entry88360">уточнение</a>.<br /></p><div class="codebox"><pre><code>limit = 1000000

FileDelete, %A_Desktop%\Prime%limit%.txt

StartTime := A_TickCount

Is_Prime := Prime(limit, quantity := 0)

Time := A_TickCount - StartTime
sec_msec := SubStr(Time/1000, 1, -3)
min_sec_msec := sec_msec &gt;= 60 ? Floor((sec := SubStr(sec_msec, 1
    , -4))/60) &quot;.&quot; SubStr(&quot;00&quot; . Mod(sec, 60), -1) . SubStr(sec_msec, -3) : sec_msec

FileAppend,
(
Проверено: %limit%
Найдено: %quantity%
Время: %min_sec_msec%
Сохранено: %A_Desktop%\Prime%limit%.txt

%Is_Prime%
), %A_Desktop%\Prime%limit%.txt
Run, %A_Desktop%\Prime%limit%.txt

Prime(limit, ByRef quantity)
{
    SetBatchLines, -1
    Loop % limit
        Is_Prime%a_index% := false
    Is_Prime2 := Is_Prime3 := True
    sqr_lim := Floor(Sqrt(limit)), x2 := 0

    While (a_index &lt;= sqr_lim)
    {
        i := a_index
        x2 += 2 * i - 1, y2 := 0
        While (a_index &lt;= sqr_lim)
        {
            y2 += 2 * a_index - 1

            n := 4 * x2 + y2
            if (n &lt;= limit) &amp;&amp; (mod(n, 12) = 1 || mod(n, 12) = 5)
                Is_Prime%n% := !Is_Prime%n%

            n -= x2
            if (n &lt;= limit) &amp;&amp; (mod(n, 12) = 7)
                Is_Prime%n% := !Is_Prime%n%

            n -= 2 * y2
            if (i &gt; a_index) &amp;&amp; (n &lt;= limit) &amp;&amp; (mod(n, 12) = 11)
                Is_Prime%n% := !Is_Prime%n%
        }
    }

    i := 5
    While (i &lt;= sqr_lim)
    {
        if Is_Prime%i%
        {
            n := i * i
            j := n
            While (j &lt;= limit)
                Is_Prime%j% := false, j += n
        }
        i++
    }

    i := 2
    While (i &lt;= limit)
    {
        if Is_Prime%i%
        {
            Is_Prime .= i . &quot;, &quot;
            quantity++
        }
        i++
    }
    Return SubStr(Is_Prime, 1, -2)
}</code></pre></div>]]></content>
			<author>
				<name><![CDATA[teadrinker]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=24515</uri>
			</author>
			<updated>2009-07-28T22:34:31Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=26555#p26555</id>
		</entry>
</feed>
