โปรแกรมที่จะหาจำนวนเฉพาะถัดไป


15

บทนำ:


คุณได้รับความเสียหายจากการไหลของเวลาโดยไม่ตั้งใจด้วยอุปกรณ์ที่คุณสร้างขึ้นเพื่อความสนุกสนานซึ่งกลายเป็นเครื่องย้อนเวลา เป็นผลให้คุณได้ผลักดันไปสู่อนาคตไกล คุณตระหนักว่าการคำนวณพลังการประมวลผลและคอมพิวเตอร์ทั่วไปได้รับการพัฒนาตามจำนวนเงินขนาดใหญ่จำนวนอนันต์จะแม่นยำ ดังนั้นคุณคว้าคอมพิวเตอร์ด้วยหน่วยความจำที่ไม่มีที่สิ้นสุดและพลังการประมวลผล คุณไม่มีความคิดว่ามันจะมีหน่วยความจำที่ไม่มีที่สิ้นสุดและพลังการประมวลผลที่ไม่มีที่สิ้นสุด แต่คุณเพียงแค่ยอมรับและกลับสู่ปัจจุบัน

ท้าทาย:


คุณได้ยินมาว่าคนที่ค้นพบนายกที่ใหญ่ที่สุดในปัจจุบัน2^74,207,281 − 1ได้รับเงิน $ 100,000 คุณตัดสินใจที่จะสร้างโปรแกรมที่ค้นหานายกคนต่อไปเนื่องจากคุณต้องการคืนเงินที่คุณใช้ไปกับคอมพิวเตอร์ คุณสร้างหมายเลขที่รับข้อมูลจากหมายเลขและค้นหาหมายเลขเฉพาะถัดไปไม่ว่าจะด้วยการ bruteforcing หรือวิธีอื่นใด

คำอธิบาย: คุณมีเครื่องสมมุติที่มีหน่วยความจำไม่สิ้นสุดและกำลังประมวลผล โปรแกรมของคุณต้องไม่ถูก จำกัด (เช่น: int ของ C # สามารถเก็บได้จาก-2,147,483,648ถึง2,147,483,647) โปรแกรมของคุณจะต้องสามารถจัดเก็บและทำงานได้กับทุกขนาดทุกขนาด คุณมีทรัพยากรที่ไม่มีที่สิ้นสุดดังนั้นคุณไม่ควรสนใจว่าจะมีหน่วยความจำไม่เพียงพอหากคุณอนุญาต

ตัวอย่าง I / O:
อินพุต: ไพรม์ที่ใหญ่ที่สุดที่ค้นพบในปัจจุบันที่มี 22,338,618 หลัก
เอาท์พุท: ตรงไปข้างหน้านายกรัฐมนตรี

เห็นได้ชัดว่าคุณไม่จำเป็นต้องพิสูจน์ว่ามันใช้งานได้เพราะต้องใช้เวลาในการคำนวณในเครื่องทางกายภาพ แต่ถ้าคุณย้ายโปรแกรมของคุณไปยังเครื่องสมมุติที่มีพลังการประมวลผล / หน่วยความจำไม่สิ้นสุดก็ควรคำนวณทันที


การค้นหานายกคนถัดไปและตรวจสอบว่าตัวเลขเป็นนายกหรือไม่นั้นเป็นสองสิ่งที่แตกต่างอย่างสิ้นเชิง


1
มันจะต้องเป็นเฉพาะนายกต่อไปโดยเฉพาะ ? อัลกอริธึมการค้นหาชั้นนำมากมายสำหรับช่วงเวลาที่มีค่ามากค้นหาเฉพาะตัวเลขบางประเภทและบางครั้งจึงพลาดช่วงเวลา ...
FlipTack

10
ฉันคิดว่าคุณควรเพิ่มกรณีทดสอบที่ร้ายแรง
FlipTack

3
" โปรแกรมของคุณต้องไม่ถูก จำกัด " แต่บนพื้นฐานของตัวอย่างที่ฉันสงสัยว่าทุก ๆ ภาษาที่มีอยู่นั้นมีจำนวน จำกัด หากไม่มีเหตุผลอื่นที่เหมาะสมกว่าการใช้ชนิด จำกัด เพื่อจัดการกับหน่วยความจำ
ปีเตอร์เทย์เลอร์

1
เป็นไปได้ที่ซ้ำกันของตัวเลขนี้หรือไม่?
โพสต์ Rock Garf Hunter

2
@ mbomb007 ทำไม คำตอบทั้งหมดยกเว้นคำที่มีอยู่ภายในที่เห็นเพื่อเพิ่ม wrapper พิเศษ
โพสต์ Rock Garf Hunter

คำตอบ:



8

Python 3 , 45 ไบต์

f=lambda n,k=1,m=1:m%k*k>n or-~f(n,k+1,m*k*k)

ลองออนไลน์!


3
ฉันเชื่อว่านี่เป็นทฤษฎีบทของวิลสันปลอมตัว kเท่ากับผลสุดท้ายมีm (k-1)!^2ตั้งแต่(k-1)! = -1 mod k เก็บเฉพาะเมื่อ k เป็นจำนวนเฉพาะเรามี(k-1)! (k-1)! = 1 mod k ซึ่งเมื่อคูณด้วย k จะเป็น k เอง คุณคำนวณสแควร์เพื่อกำจัดข้อยกเว้นเพียงอย่างเดียวของ (k-1)! = 0 mod k สำหรับคอมโพสิต k ซึ่งเกิดขึ้นสำหรับ k = 4 ถูกต้องไหม
orlp

ใช่ถูกต้องแล้ว
Dennis

นี้พ่นRecursionError: maximum recursion depth exceeded in comparisonสำหรับf(1000)
OVS

5
@ovs คำถามที่บอกว่าเรามีความทรงจำไม่รู้จบ ดังนั้นเราจึงสามารถถือว่า recursion ขีด จำกัด RecursionErrorของความลึกสูงเพียบจึงไม่ต้องกังวลเกี่ยวกับ
FlipTack

6

Python 2, 78 77 76 74 ไบต์

def f(n):
 while 1:
    n+=1
    if[i for i in range(1,n)if n%i<1]==[1]:return n

-1 ไบต์ขอบคุณ @KritixiLithos
-1 ไบต์ขอบคุณ @FlipTack
-2 ไบต์ขอบคุณ @ElPedro


n%i<1สั้นกว่าn%i==0
Kritixi Lithos

ifคุณไม่จำเป็นต้องช่องว่างหลังจากนั้น
FlipTack

ฉันคิดว่าคุณหมายถึง<1
Jonathan Allan

ฉันคิดว่าคุณสามารถใช้แท็บแทนการเว้นวรรค 2 สำหรับการเยื้องระดับที่สอง แต่ฉันไม่สามารถทดสอบได้ในขณะนี้
ElPedro

1
@ElPedro ถูกต้อง คุณสามารถเปลี่ยนช่องว่างด้านหน้าn+=1และifลงในแท็บและบันทึก 2 ไบต์



4

Bash + coreutils, 52 ไบต์

for((n=$1,n++;`factor $n|wc -w`-2;n++)){ :;};echo $n

ลองออนไลน์!

เอกสารสำหรับ bash และ factor ไม่ได้ระบุค่าจำนวนเต็มสูงสุดที่สามารถจัดการได้ (แม้ว่าในทางปฏิบัติแต่ละการใช้งานจะมีค่าจำนวนเต็มสูงสุด) สันนิษฐานได้ว่าใน GNU แห่งอนาคตบนเครื่องจักรขนาดใหญ่ของคุณการทุบตีและปัจจัยจะมีจำนวนเต็มขนาดไม่ จำกัด


จริง ๆ แล้วเอกสารจะระบุปัจจัยที่ว่าถ้าสร้างโดยไม่มี gnu mp สนับสนุนความแม่นยำเดียวเท่านั้น
Dani_l

1
@Dani_l เอาละรายการ man สำหรับ bash บอกเพียงว่า: "การประเมินผลเสร็จในจำนวนเต็มความกว้างคงที่โดยไม่มีการตรวจสอบการล้น แต่การหารด้วย 0 ถูกดักและตั้งค่าสถานะเป็นข้อผิดพลาด" ไม่ได้ระบุความกว้าง (ตามที่ฉันจำได้การใช้งานสต็อคของ bash บนเครื่องของฉันใช้จำนวนเต็มแบบ 64 บิต แต่ฉันไม่สามารถตรวจสอบได้ในตอนนี้) ส่วนปัจจัยนั้นจะได้รับการอัปเดตแน่นอน: คอมพิวเตอร์ในอนาคตของ OP ที่มีทรัพยากรไม่สิ้นสุด รวบรวมด้วย gnu_up เพื่อรับความแม่นยำไม่ จำกัด :)
Mitchell Spector

3

Maxima, 10 ไบต์

next_prime

ฟังก์ชั่นส่งกลับนายกที่เล็กที่สุดที่ใหญ่กว่าอาร์กิวเมนต์



3

Python ที่มี sympy ขนาด 28 ไบต์

import sympy
sympy.nextprime

sympy.nextprimeเป็นฟังก์ชั่นที่ทำสิ่งที่มันบอกบนดีบุก ใช้งานได้กับทุกแพท

repl.it


Python, 66 59 ไบต์

-4 bytes ต้องขอบคุณ Lynn (ใช้งาน-~)
-3 bytes ขอบคุณ FlipTack (ใช้andและorอนุญาตให้...==1เปลี่ยนเป็น...-1เงื่อนไขได้)

f=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n

repl.it

ฟังก์ชั่นวนซ้ำที่นับขึ้นnจนกระทั่งพบค่านายกโดยการทดสอบว่ามีเพียงหนึ่งหมายเลขเท่านั้นn-1ที่หาร (เช่น 1) ใช้งานได้สำหรับจำนวนเต็มทั้งหมดทำให้เกิดข้อผิดพลาดสำหรับการลอย

ใช้งานได้กับ 2.7.8 และ 3.5.2 ไม่ทำงานบน 3.3.3 (ข้อผิดพลาดทางไวยากรณ์เนื่องจากไม่มีที่ว่างระหว่าง==1และelse)


(n+1)%(i+1)คือ-~n%-~iฉันคิดว่า
ลินน์มม

ขอบคุณ ... ฉันพยายามทำให้สั้นลงโดยใช้ทฤษฎีบทของ Wilson
Jonathan Allan

การลัดวงจรand/ การorทำงานสั้น ๆเช่นนี้f=lambda n:sum(-~n%-~i<1for i in range(n))==1and-~n or f(n+1)หรือไม่?
FlipTack

ที่จริงแล้ว ^ สามารถเล่นกอล์ฟกับf=lambda n:sum(-~n%-~i<1for i in range(n))-1and f(n+1)or-~n
FlipTack

@FlipTack ตอนแรกฉันหลีกเลี่ยงมันเพื่อที่จะได้ผ่านศูนย์ แต่มันจะใช้ได้ - นั่นคือสามไบต์ประหยัด!
Jonathan Allan

2

Python, 114 83 ไบต์

def g(b):
 while 1:
  b+=1
  for i in range(2,b):
   if b%i<1:break
  else:return b

หากไม่มีบิวด์อิน

-30 โดยลบช่องว่างและ -1 โดยเปลี่ยนb%i==0เป็นb%i<1


3
นี่จะไม่หานายกคนต่อไปถ้าคุณใส่1
FlipTack

ตอนนี้สมมติว่า b> 2
sagiksp

คุณไม่สามารถสร้างกฎของคุณเองได้ ... คุณต้องทำตามข้อกำหนดการท้าทาย ไม่มีที่ไหนบอกได้เลยว่าคุณสามารถรับขอบเขตของอินพุทได้
FlipTack

แม้จะมีข้อสันนิษฐานว่าสิ่งนี้ล้มเหลวสำหรับอินพุตที่มีค่าแม้ทั้งหมด
FlipTack

ฉันเป็นคนงี่เง่าฉันอ่านมันผิด ซ่อมมัน. @FlipTack
sagiksp

2

Perl 6 , 25 ไบต์

{first *.is-prime,$_^..*}

มันทำงานอย่างไร

{                       }  # A lambda.
                  $_ ..*   # Range from the lambda argument to infinity,
                    ^      # not including the start point.
 first           ,         # Iterate the range and return the first number which
       *.is-prime          # is prime.

Perl 6 , 32 ไบต์

{first {all $_ X%2..^$_},$_^..*}

ด้วยการทดสอบแบบดั้งเดิมที่ไม่มีประสิทธิภาพที่กำหนดเอง

มันทำงานอย่างไร

โครงสร้างด้านนอกเป็นเหมือนด้านบน แต่ภาคแสดงที่ส่งผ่านไปยังfirst(เพื่อตัดสินใจว่าตัวเลขที่กำหนดเป็นนายก) ตอนนี้:

{               }  # A lambda.
     $_            # Lambda argument (number to be tested).
          2..^$_   # Range from 2 to the argument, excluding the end-point.
        X          # Cartesian product of the two,
         %         # with the modulo operator applied to each pair.
 all               # Return True if all the modulo results are truthy (i.e. non-0).

ผมหวังที่จะได้รับสิ่งที่สั้นลงด้วยPerl 5แต่มันเป็นเรื่องยากที่จะชนะในตัว.is-prime;)
Zaid

2

Pyke, 8 7 ไบต์

~p#Q>)h

ลองที่นี่!

4 ไบต์ไม่ใช่การแข่งขัน

(ล่ามอัปเดตแล้วตั้งแต่มีการโพสต์ข้อความท้าทาย)

~p<h

ลองที่นี่!

~p   -   primes_iterator()
  <  -  filter(^, input() < i)
   h - ^[0]

ทำไมการไม่แข่งขันครั้งที่สอง ฉันไม่เข้าใจพอ
theonlygusti

@theonlygusti: โดยทั่วไปแล้วเหตุผลที่ถูกต้องเพียงอย่างเดียวในการทำเครื่องหมายการส่งที่ไม่ใช่การแข่งขันที่นี่ (ซึ่งไม่ใช่การไม่ส่งเลย) เนื่องจากคุณแก้ไขข้อบกพร่องหรือเพิ่มคุณสมบัติในภาษาที่เขียนในโปรแกรมและช่วยคุณได้ . (ฉันมักจะเขียนมันเป็น "language postdates challenge" เพื่อความชัดเจนมากขึ้น)

@theonlygusti ชี้แจง
สีฟ้า


1

05AB1E , 16 13 ไบต์ (Emigna @ -3 ไบต์)

2•7£?ÿ•o[>Dp#

ลองออนไลน์!

2•7£?ÿ•o        # Push current largest prime.
        [   #    # Until true..
         >Dp    # Increment by 1, store, check primality.
                # After infinite loop, implicitly return next prime.

จะไม่[>Dp#ทำงานเหรอ
Emigna

คุณยังสามารถตัดได้อีก 8 ไบต์เนื่องจากโปรแกรมควรใช้ไพร์มเป็นอินพุตและเอาต์พุตไพรม์ถัดไป
Emigna

@Emigna ดังนั้นคำถามนี้ซ้ำกัน
Magic Octopus Urn

เป็นไปได้ใช่
Emigna

1

Perl, 30 ไบต์ (29 +1 สำหรับ-p):

(1x++$_)=~/^(11+?)\1+$/&&redo

การใช้

ป้อนหมายเลขหลังจากกดย้อนกลับ (ป้อน 12345 ในตัวอย่างด้านล่างเอาต์พุต 12347):

$ perl -pe '(1x++$_)=~/^(11+?)\1+$/&&redo'
12345
12347

มันทำงานอย่างไร

  • กำหนดสตริงของ1ที่มีความยาว++$_ที่ไหน$_เริ่มแรกเป็นค่าที่ป้อนเข้า
  • regex ตรวจสอบว่าสตริงของ1s มีความยาวไม่เฉพาะหรือไม่ (อธิบายไว้ที่นี่ )
  • หากความยาวสตริงไม่ใช่ไพร์มการตรวจสอบจะถูกประเมินอีกครั้งสำหรับจำนวนเต็มถัดไป ( ++$_)
  • ถ้าความยาวสตริงเป็นไพร์มwhileวนซ้ำจะออกจากลูปและ-pพิมพ์ค่า$_
  • หมายเหตุ: ไม่จำเป็นต้องจัดการกับตัวพิมพ์ขอบที่มี"1"ความยาว 1 เนื่องจากจะไม่ถูกใช้สำหรับค่าที่น้อยกว่า1ตามข้อกำหนด

1

Java 7, 373 343 334 303 268 ไบต์

import java.math.*;class M{public static void main(String[]a){BigInteger n,i,o,r=new BigInteger(a[0]);for(r=r.add(o=r.ONE);;r=r.add(o)){for(n=r,i=o.add(o);i.compareTo(n)<0;n=n.mod(i).compareTo(o)<0?r.ZERO:n,i=i.add(o));if(n.compareTo(o)>0)break;}System.out.print(r);}}

ขอบคุณ -75 ไบต์ @Poke

Ungolfed:

import java.math.*;
class M{
  public static void main(String[] a){
    BigInteger n,
               i,
               o,
               r = new BigInteger(a[0]);
    for(r = r.add(o = r.ONE); ; r = r.add(o)){
      for(n = r, i = o.add(o); i.compareTo(n) < 0; n = n.mod(i).compareTo(o)< 0
                                                        ? r.ZERO
                                                        : n,
                                                   i = i.add(o));
      if(n.compareTo(o) > 0){
        break;
      }
    }
    System.out.print(r);
  }
}

ลองที่นี่

ตัวอย่างอินพุต / เอาท์พุต:

7 -> 11
1609 -> 1613
104723 -> 104729

@Poke ฉันเล่นกอล์ฟอีก 31 ไบต์โดยการเพิ่มstaticสำหรับฟิลด์และเมธอดpแต่การลบเมธอดcและpพารามิเตอร์ของ
Kevin Cruijssen

0

QBIC , 34 ไบต์

:{a=a+1[2,a/2|~a%b=0|b=a]]~a<b|_Xa

ตามออกนี้Qbic ทดสอบ คำอธิบาย:

:{a=a+1    Read 'a' from the command line, start an infinite loop 
           and at the start of each iteration increment 'a'
[2,a/2|    FOR b = 2, b <= a/2, b++
~a%b=0|    IF b cleanly divides a, we're no prime
b=a]]      so, break out of the FOR loop ( ]] = End if, NEXT )
~a<b|      If the FOR loop completed without breaking
_Xa        then quit, printing the currently tested (prime) number
           The second IF and the DO-loop are implicitly closed by QBIC.

0

JavaScript (ES7), 61 ไบต์

a=>{for(;a++;){for(c=0,b=2;b<a;b++)a%b||c++;if(!c)return a;}}

การใช้

f=a=>{for(;a++;){for(c=0,b=2;b<a;b++)a%b||c++;if(!c)return a;}}
f(2)

เอาท์พุต

3

ดี แต่ฉันไม่คิดว่ามันจะใช้ได้เพราะ JavaScript เอง (ไม่ใช่คอมพิวเตอร์) จะเสียความแม่นยำหลังจาก 2 ^ 53
ETHproductions

คุณพูดถูก แต่ฉันไม่คิดว่าจะสามารถหลีกเลี่ยงข้อ จำกัด ได้แม้ว่าเราจะแบ่งจำนวนเป็น 32 บิตในอาเรย์เพราะในที่สุดตัวเลขก็ต้องถูกประมวลผลโดยรวม หากคุณมีความคิดเกี่ยวกับวิธีการแก้ไขปัญหานี้โปรดแจ้งให้เราทราบ
ลูกา

1
มีห้องสมุด JS สำหรับคณิตศาสตร์ที่มีความแม่นยำตามอำเภอใจ - ฉันยังสร้างไว้ในบางจุด - ดังนั้นฉันมั่นใจว่าเป็นไปได้ ฉันจะไปในครั้งต่อไปที่ฉันอยู่ที่คอมพิวเตอร์ของฉัน
ETHproductions

ฉันทำ Google และดูเหมือนว่าน่าสนใจ ฉันจะยิงมันด้วย
ลุค

0

MATL, 3 ไบต์

_Yq 

ฟังก์ชั่นYqจะส่งกลับไพรม์ถัดไปของค่าสัมบูรณ์ของอินพุทถ้าอินพุทเป็นลบดังนั้นเราจึงจับอินพุตโดยปริยายลบมัน ( _) และหาไพรม์ถัดไปที่ใช้Yqและหานายกถัดไปโดยใช้

ลองออนไลน์!


0

Haskell, 42 46 43 ไบต์

f n=[i|i<-[n..],all((>0).rem i)[2..i-1]]!!1

รหัสปกติสำหรับกำลังดุร้าย

ของหลักสูตรนี้พบต่อไป จำนวนเฉพาะที่น้อยที่สุดหลังจากนั้นnนั้น ไม่มีนายกที่ใหญ่ที่สุด

ทำงานสำหรับn > 0

แก้ไข:ถือว่าnเป็นนายก ขอขอบคุณที่@Laikoniคำแนะนำ 'ในการแสดงความคิดเห็น


คุณสามารถบันทึกไบต์โดยการแทนที่ด้วยhead[...] [...]!!0อย่างไรก็ตามฉันคิดว่ามีใครคิดว่าnมันยอดเยี่ยมดังนั้นคุณสามารถใช้[n..]แทน[n+1..]แล้วนำองค์ประกอบที่สอง[...]!!1มาใช้ได้
Laikoni

0

SimpleTemplate ขนาด 132 ไบต์

อัลกอริทึมนั้นแย่มากเพราะฉันต้องทำโค้ดของตัวเองเพื่อตรวจสอบว่าตัวเลขนั้นดีหรือไม่
มันพิสูจน์แล้วว่าน่ากลัว แต่ได้ผล

{@setY argv.0}{@setX 1}{@whileX}{@setX}{@set+T Y,-1}{@for_ from2 toT}{@ifY is multiple_}{@incX}{@/}{@/}{@ifX}{@incY}{@/}{@/}{@echoY}

รับตัวเลขเป็นอาร์กิวเมนต์แรกโดยแสดงผลลัพธ์


Ungolfed:

{@set number argv.0}
{@set remainder 1}
{@while remainder}
    {@set remainder 0}
    {@set+ tmp number, -1}
    {@for divisor from 2 to tmp}
        {@if number is multiple divisor}
            {@inc by 1 remainder}
        {@/}
    {@/}
    {@if remainder}
        {@inc by 1 number}
    {@/}
{@/}
{@echo number}

เคล็ดลับเกี่ยวกับวิธีการลบที่ผ่านมาว่า@if?


0

Lua, 876 ไบต์

function I(a)a.s=a.s:gsub("(%d)(9*)$",function(n,k)return tostring(tonumber(n)+1)..("0"):rep(#k)end)end function D(a)a.s=a.s:gsub("(%d)(0*)$",function(n,k)return tostring(tonumber(n)-1)..("9"):rep(#k)end):gsub("^0+(%d)","%1")end function m(a,b)local A=K(a)local B=K(b)while V(0,B)do D(A)D(B)end return A end function M(a,b)local A=K(a)local B=K(b)while V(m(B,1),A)do A=m(A,B)end return A end function l(n)return#n.s end function p(a)local A=K(a)local i=K(2)while V(i,A)do if V(M(A,i),1)then return false end I(i)end return true end function V(b,a)A=K(a)B=K(b)if l(A)>l(B)then return true end if l(B)>l(A)then return false end for i=1,l(A)do c=A.s:sub(i,i)j=B.s:sub(i,i)if c>j then return true elseif c<j then return false end end return false end function K(n)if(type(n)=='table')then return{s=n.s}end return{s=tostring(n)}end P=K(io.read("*n"))repeat I(P)until p(P)print(P.s)

Lua ซึ่งแตกต่างจากภาษาอื่น ๆ จะมีขนาดเต็มจำนวนสูงสุด เมื่อตัวเลขได้รับมากกว่า 2 32สิ่งต่าง ๆ จะหยุดทำงานอย่างถูกต้องและ Lua เริ่มพยายามประมาณการแทนค่าที่แน่นอน

ดังนั้นฉันจึงต้องใช้วิธีการใหม่ในการจัดเก็บตัวเลขโดยเฉพาะฉันเก็บไว้เป็นสตริง Base10 เนื่องจาก Lua ไม่ได้มีการ จำกัด ขนาดใน Strings นอกเหนือจากขนาดของหน่วยความจำ

ฉันรู้สึกว่าคำตอบนี้เป็นมากกว่าจิตวิญญาณของคำถามเนื่องจากมีการใช้จำนวนเต็มความแม่นยำโดยพลการเช่นเดียวกับการทดสอบที่สำคัญ

อธิบาย

-- String Math
_num = {}

_num.__index = _num

-- Increase a by one.
-- This works by grabbing ([0-9])999...$ from the string.
-- Then, increases the first digit in that match, and changes all the nines to zero.
-- "13", only the "3" is matched, and it increases to 1.
-- "19", firstly the 1 is turned to a 2, and then the 9 is changed to a 0.
-- "9" however, the 9 is the last digit matched, so it changes to "10"
function _num.inc(a)
    a.str = a.str:gsub("(%d)(9*)$",function(num,nines)
            return tostring(tonumber(num)+1)..("0"):rep(#nines)
        end)
end


-- Decrease a by one
-- Much like inc, however, uses ([0-9])0...$ instead.
-- Decrements ([0-9]) by one and sets 0... to 9...
-- "13" only the "3" is matched, and it decreases by one.
-- "10", the "1" is matched by the ([0-9]), and the 0 is matched by the 0..., which gives 09, which is clipped to 9.
function _num.dec(a)
    a.str = a.str:gsub("(%d)(0*)$",function(num,zeros)
        return tostring(tonumber(num)-1)..("9"):rep(#zeros)
    end)         :gsub("^0+(%d)","%1")
end

-- Adds a and b
-- Makes A and B, so that the original values aren't modified.
-- B is then decremented until it hits 0, and A is incremented.
-- A is then returned.
function _num.__add(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while B > 0 do
        A:inc()
        B:dec()
    end
    return A
end

-- Subs b from a
-- Works just like Addition, yet Dec's A instead of Incs.
function _num.__sub(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while B > 0 do
        A:dec()
        B:dec()
    end
    return A
end

-- A % B
-- Makes A and B from a and b
-- Constantly subtracts B from A until A is less than B
function _num.__mod(a,b)
    local A = str_num(a)
    local B = str_num(b)
    while A >= B do
        A = A - B
    end
    return A
end

-- #a
-- Useful for golfiness
function _num.__len(n)
    return #n.str
end

-- Primacy Testing
-- Generates A from a and i from 2.
-- Whilst i is less than A, i is incremented by one, and if A % i == 0, then it's not a prime, and we return false.
-- Once that finishes, we return true.
function _num.isprime(a)
    local A = str_num(a)
    local i = str_num(2)
    while i < A do
        if A%i < 1 then
            return false
        end
        i:inc()
    end
    return true
end

-- b < a
-- A and B are generated from a and b
-- Fristly, if the length of A and B aren't equal, then that result is output.
-- Otherwise, each character is searched from left to right, the moment they are unequal, the difference is output.
-- If all the characters match, then it's equal. Return false.
function _num.__lt(b,a)
    A=str_num(a)
    B=str_num(b)
    if #A > #B then
        return true
    end
    if #B > #A then
        return false
    end
    for i=1, #A.str do
        As = A.str:sub(i,i)
        Bs = B.str:sub(i,i)
        if As > Bs then
            return true
        elseif As < Bs then
            return false
        end
    end
    return false
end


-- b <= a
-- Same as b < a, but returns true on equality.
function _num.__le(b,a)
    A=str_num(a)
    B=str_num(b)
    if #A > #B then
        return true
    end
    if #B > #A then
        return false
    end
    for i=1, #A.str do
        As = A.str:sub(i,i)
        Bs = B.str:sub(i,i)
        if As > Bs then
            return true
        elseif As < Bs then
            return false
        end
    end
    return true
end

-- Just straight up returns it's string component. Endlessly faster than the int equivalent, mostly because it never is anything _but_ the string form.
function _num.__tostring(a)
    return a.str
end

-- Just set up the metatable...
function str_num(n)
    if(type(n)=='table')then
        return setmetatable({str = n.str}, _num)
    end
    return setmetatable({str = tostring(n)}, _num)
end

-- Generate a new str_num from STDIN
Prime = str_num(io.read("*n"))

-- This is handy, because it will call Prime:inc() atleast once, and stop at the next prime number it finds.
-- Basically, if it weren't for all that overhead of making the math possible, that's all this would be.
repeat
    Prime:inc()
until Prime:isprime()
print(Prime)

แม้ว่าข้างต้นใช้ Metatables แทนที่จะเป็นเพียงฟังก์ชั่นปกติเช่นคำตอบจริงซึ่งทำงานได้น้อยกว่า



0

หลาม + primefac , 34 32 ไบต์

ไม่ได้ค่อนข้างสั้นที่สุดเท่าที่ใช้sympy(คำตอบอื่นแล้วใช้นั้น) แต่ก็ยังคงสวยสั้นและก็มากได้เร็วขึ้น

import primefac as p
p.nextprime

ลองออนไลน์

การป้อนข้อมูล2**2000เสร็จสมบูรณ์ในไม่กี่วินาที


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.