Code-Challenge: Thủ tướng gần nhất


8

Thử thách

Trong tác vụ này, bạn sẽ được cấp một số nguyên N, bạn phải xuất số nguyên tố gần nhất cho số nguyên.

Nếu số là số nguyên tố tự xuất ra số.

Đầu vào N được đưa ra trong một dòng duy nhất, đầu vào được kết thúc bằng EOF. Số lượng đầu vào sẽ không vượt quá 10000 giá trị.

Thách thức là triển khai giải pháp nhanh nhất để có thể xử lý tối đa 10000 giá trị nhanh nhất có thể.

Đầu vào

 299246598
 211571591
 71266182
 645367642
 924278231

Đầu ra

 299246587
 211571573
 71266183
 645367673
 924278233

Những ràng buộc

  • N nhỏ hơn 2 ^ 64
  • Chăm sóc ngón tay của bạn không sử dụng hơn 4096 byte trong giải pháp của bạn.
  • Bạn có thể sử dụng bất kỳ ngôn ngữ nào bạn chọn miễn là bạn không sử dụng bất kỳ ngôn ngữ nào có sẵn cho các số nguyên tố.
  • Giải pháp nhanh nhất, với sự phức tạp về thời gian hiệu quả nhất sẽ chiến thắng!

THÊM:

Đây là phiên bản dễ dàng hơn cho cùng một vấn đề này (với N <2 ^ 31) để bạn có thể thử kiểm tra phương pháp của mình trong các trường hợp nhỏ hơn trước khi giải quyết vấn đề thực tế này.


2
Tính toán cơ bản mà bạn yêu cầu là một phần phụ của codegolf.stackexchange.com/q/1977/78 , chỉ một vài ngày trước. Cá nhân (tức là không đội mũ điều hành của tôi) Tôi thấy sự lặp lại nhàm chán như vậy.
dmckee --- ex-moderator mèo con

Chúng ta có thể sử dụng các xét nghiệm nguyên thủy xác suất?
Keith Randall

2
Làm thế nào để bạn có kế hoạch đánh giá nhanh nhất? Bằng tốc độ thực hiện trên phần cứng cố định? Hoặc bằng cách phân tích sự phức tạp của các bài nộp? Bạn sẽ bằng cách nào đó bình thường hóa chi phí hoạt động trong các ngôn ngữ khác nhau? - Cuối cùng, thử thách này có vẻ quá đơn giản. Thực sự không có chỗ để đổi mới ở đây.
MtnViewMark

1
@gnibbler: Sử dụng bảng tra cứu tất cả 2 ^ 64 giá trị sẽ cung cấp cho bạn giải pháp nhanh nhất nếu bạn có thể ép toàn bộ (giải pháp) thông qua cửa sổ 4096 byte :-)
Quixotic

2
@Debanjan, chúng ta có thể giả sử giả thuyết Riemann tổng quát trong việc nêu rõ độ phức tạp của thời gian không?
Peter Taylor

Câu trả lời:


6

Con trăn

import sys,random

# Miller-Rabin primality test, error rate 2^-200.                                                                                                                           
def prime(N):
  if N<3:return N==2
  s=0
  d=N-1
  while (d&1)==0:s+=1;d>>=1
  for i in xrange(100):
    a=random.randrange(1,N)
    if pow(a,d,N)!=1 and all(pow(a,d<<r,N)!=N-1 for r in xrange(s)):return 0
  return 1

for N in map(int,sys.stdin):
  d=0
  while 1:
    if prime(N+d):print N+d;break
    if prime(N-d):print N-d;break
    d+=1

Tôi nghĩ rằng cần lưu ý rằng thử nghiệm nguyên thủy Miller-Rabin không phải là quyết định vô điều kiện. vi.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
mbomb007

2

GPI GP

a(n)=x=[precprime(n),nextprime(n)];print(if(x[1]-n<n-x[2],x[1],x[2]))
while(1,print(a(input())))

Tôi cho rằng NextPrime[n]n
mathicala

0

Haskell

import Data.Numbers.Primes

-- Assuming, we are on x64
nearestPrime :: Int -> Int
nearestPrime n | n - s < l - n = s
               | otherwise     = l where
  l = head $ dropWhile (not . isPrime) [n..]
  s = head $ dropWhile (not . isPrime) [n,n-1..]

main = readLine >>= print . nearestPrime . read

Nên khá nhanh. Yêu cầu gói primes, có sẵn từ hackage.


Xin lỗi, điều đó không được phép, đây là thử thách mã và tôi đoán điều này cũng không hoạt động trong phiên bản ngắn hơn của vấn đề.
Quixotic

Như bạn đã nói, nhập mã là một sự xấu hổ. Trừ khi bạn đánh giá người khác theo tiêu chuẩn khác so với tiêu chuẩn của bạn
Tiến sĩ belisarius

@ Belisarius Bạn nhầm. Đây không phải là mã golf nên kích thước mã không phải là một lựa chọn. Nhiệm vụ bạn đã cố gắng giải quyết là mã golf tuy nhiên.
FUZxxl

1
Sử dụng các số nguyên tố sẵn có không phải là một lựa chọn tốt vì đây không phải là codegolf và toàn bộ vấn đề là thực hiện một cách tiếp cận nhanh Câu trả lời này xứng đáng với -1, rõ ràng. Tôi không cảm thấy trong một tâm trạng xuống cấp, mặc dù.
Tiến sĩ belisarius

@ Belisarius Nếu bạn có nhu cầu "trả thù", hãy bỏ phiếu cho tôi. Không có vấn đề với điều đó; không bao giờ, đó là phong cách xấu.
FUZxxl

0

Hồng ngọc

require 'prime'
gets(p).split.each{|n|
    a=b=n.to_i
    a,b = a-1,b+1 while !a.prime?  and !b.prime?
    p a.prime? ? a : b
}

Sử dụng các số nguyên tố sẵn có không phải là một lựa chọn tốt vì đây không phải là codegolf và toàn bộ vấn đề là thực hiện một cách tiếp cận nhanh, quyết định của điểm số tốt nhất là dựa trên sự phức tạp của giải pháp nên điều này không được phép, xin lỗi.
Quixotic

0

Java

Quá trình này mất <1 giây cho đến khi num bắt đầu lớn hơn 10 ^ 8. Không đủ hiệu quả, xem xét 2 ^ 64 là khoảng 1,8 * 10 ^ 19. (Bắt đầu 10 ^ 15 6 phút trước và vẫn đang chạy D :)

import java.util.*;

class ClosestPrime {

    public static double closest(double num) {
        double returnme = 0;
        if (isPrime(num)){returnme = num;}
        for (double i = 0; i < num / 2; i++) { //checks each side of num
            if (isPrime(num - i)) {returnme = num - i;
                break;}
            if (isPrime(num + i)) {returnme = num + i;
                break;}
        }
        return returnme;
    }

    private static boolean isPrime(double num) {
        long sqrtnum = (long) Math.sqrt(num); //no need to check for factors above sqrt(num)
        List<Double> primes = new LinkedList<Double>();
        primes.add((double) 2);
        for (double i = 3; i < sqrtnum; i+=2) {primes.add(i);} //fill list with odd numbers

        for (long i = 2; i <= sqrtnum; i++) {
            if (num / i % 1 == 0) {return false;}   
            ListIterator<Double> iter = primes.listIterator();
            while (iter.hasNext()) {if ((iter.next()) / i % 1 == 0){iter.remove();}} //sieving by Eratosthenes
        }
        return true;
    }
}

Điều này đưa ra câu trả lời chắc chắn mọi lúc, vì nó không sử dụng thuật toán xác suất, nhưng trả giá rất cao cho điều đó về hiệu quả - 10 ^ 18 sẽ có hơn 5 triệu số nguyên tố trong danh sách, và thậm chí nhiều hơn trước khi sàng. Có thể cải thiện điều này đôi khi với một thuật toán sàng tốt hơn. Tôi không mong đợi điều này sẽ đánh bại bất kỳ ai khác :)


0

Haskell

Điều này là khá nhanh, và không xác định đến một giới hạn lớn. Cũng là Haskell đầu tiên của tôi :). wcnói 903b chưa được biên dịch.

Chỉnh sửa: Nếu bất cứ ai muốn ước tính độ phức tạp thời gian, hãy là khách của tôi ...

import System.Environment
import Math.NumberTheory.Moduli -- arithmoi
import Data.List.Ordered -- data-ordlist

main :: IO ()
main = interact processInputStrings

processInputStrings :: String -> String
processInputStrings input = unlines $ map show $ getClosestMembers $ map read $ lines $ input 

isPrime :: Integer -> Bool
{- Implement the Miller–Rabin test with basis valid up to somewhere > 2^64 -}
isPrime 2 = True
isPrime 3 = True
isPrime t =  let
        factor :: (Integer, Integer) -> (Integer, Integer)
        factor (d,s) = if even d then factor (d `div` 2, s+1) else (d,s)
        (d,s) = factor (t-1, 0)
    in 
        and $ map (\a ->
            or [(powerMod a d t) == 1, or [(powerMod a (2^r * d) t) == t-1 | r <- [0..s-1]]]
        ) $ filter (<t) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]


getClosestMembers :: [Integer] -> [Integer]
getClosestMembers inputs = map (\i -> head [n | n <- concat [[i-d, i+d] | d <- [0..]], isPrime n]) inputs
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.