ความเหงาของจำนวนเฉพาะ


24

เมื่อเร็ว ๆ นี้ฉันได้อ่านนวนิยายเรื่อง"The Solitude of Prime Numbers"ซึ่งตัวละครหลักนั้นค่อนข้างจะเปรียบเทียบกับตัวเลขตัวเอกสองตัว(" อยู่ด้วยกันเสมอ แต่ไม่เคยสัมผัส ")

วินไพร์มเป็นหมายเลขที่มีค่าน้อยกว่า 2 หรือมากกว่า 2 หมายเลขที่สำคัญ - ตัวอย่างเช่นคู่ที่สำคัญ (41, 43) กล่าวอีกนัยหนึ่งนายกรัฐมนตรีคู่แฝดเป็นนายกที่มีช่องว่างที่สำคัญของสอง บางครั้งคำแฝดสำคัญใช้สำหรับคู่แฝด ชื่ออื่นสำหรับสิ่งนี้คือคู่แฝดหรือคู่นายกรัฐมนตรี วิกิพีเดีย

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

งาน:

รับจำนวนจำนวนเต็มบวก N> 4 พบว่าตัวเลขที่สำคัญเหงา (AKA แยกตัวเลขที่สำคัญ ) ระหว่างคู่ใกล้เคียงที่สุดของจำนวนเฉพาะคู่

โปรดทราบว่าในกรณีนี้กับระยะตัวเลขที่สำคัญเหงาผมหมายถึงทุกตัวเลขที่สำคัญที่ไม่ได้เป็นจำนวนเฉพาะคู่และระหว่างคู่ของจำนวนเฉพาะคู่ นั่นเป็นเหตุผลว่าทำไม N> 4 เพราะสองคู่แรกของจำนวนเฉพาะคือ (3, 5) และ (5, 7)

ตัวอย่าง:

  1. N = 90
  2. ค้นหาสองคู่แรกของช่วงเวลาคู่ <N และ> N พวกเขาคือ: (71, 73) และ (101, 103)
  3. ค้นหาช่วงเวลาที่โดดเดี่ยวในช่วง> 73 และ <101
  4. ได้แก่ : 79, 83, 89, 97

กรณีพิเศษ:

  • หาก N อยู่ระหว่างตัวเลขสองหลักสองคู่ให้หาคู่ที่ใกล้เคียงที่สุดของค่าแฝด> N + 1 และ <N-1 ตัวอย่าง: N = 72, หาคู่รักที่ใกล้ที่สุดของจำนวนเฉพาะคู่> 73 <71 แล้วแยกออกจากรายการ 71 และ 73 เพราะพวกเขาไม่ได้เป็นช่วงเวลาที่เหงา ดังนั้นสำหรับ N = 72 ผลลัพธ์ที่คาดหวังคือ: 67, 71 , 73 , 79, 83, 89, 97
  • หาก N อยู่ในช่วงเวลาแฝดสองช่วงตัวอย่างเช่น N = 73 คู่ที่ใกล้ที่สุดของช่วงเวลาสองช่วงคือ (71, 73) และ (101, 103) ถ้า N = 71 คู่ที่ใกล้ที่สุดของช่วงเวลาแฝดคือ (59, 61) และ (71, 73)

กรณีทดสอบ:

N = 70   >  Lonely primes are:  67
N = 71   >  Lonely primes are:  67
N = 72   >  Lonely primes are:  67, 79, 83, 89, 97 (not the twins 71 and 73)
N = 73   >  Lonely primes are:  79, 83, 89, 97 
N = 90   >  Lonely primes are:  79, 83, 89, 97
N = 201  >  Lonely primes are:  211, 223
N = 499  >  Lonely primes are:  467, 479, 487, 491, 499, 503, 509

กฎ:

  • เขียนโปรแกรมหรือฟังก์ชั่นเต็มรูปแบบที่จะรับหมายเลข N จากอินพุตมาตรฐาน
  • แสดงรายการของช่วงเวลาที่โดดเดี่ยวในรูปแบบที่อ่านได้เช่น csv, รายการ, อาร์เรย์ ฯลฯ
  • รหัสที่สั้นที่สุดชนะ
  • โปรดรวมซอทำซอทดสอบออนไลน์ (เมื่อเป็นไปได้)

4
ผลลัพธ์ที่คาดหวังสำหรับอินพุตเช่น 71, 72 หรือ 73 คืออะไร
Martin Ender

1
Lonely Prime AKA Isolated Prime
Digital Trauma

@MartinEnder ฉันขยายคำถามของฉันด้วยกรณีพิเศษ ขอขอบคุณสำหรับการชี้แจง.
มาริโอ

1
ฉันพบว่ากรณีพิเศษทำให้ความท้าทายเล็กน้อย (และถูกเพิ่มเมื่อคำตอบบางคำตอบถูกโพสต์แล้ว)
Luis Mendo

1
@JanathanAllan ใช่คุณสามารถพิจารณา N> 4 เพราะสองคู่แรกของหมายเลขนายกรัฐมนตรีคู่คือ (3, 5) และ (5, 7) ฉันเพิ่มข้อกำหนดเพื่อให้ชัดเจนกับทุกคน
มาริโอ

คำตอบ:


2

ที่จริงแล้ว 47 ไบต์

การแก้ปัญหานี้เกี่ยวข้องกับกรณีที่nอยู่ระหว่างสองเฉพาะคู่โดยการตรวจสอบถ้าขอบเขตล่างเป็นขนาดใหญ่ของคู่ของจำนวนเฉพาะคู่ (ขจัดคู่ลากไปทางซ้ายของเราจากการถูกขีด จำกัด ล่างของเรา) และถ้าขอบเขตบนมีขนาดเล็กคู่ของจำนวนเฉพาะคู่ (ขจัดคู่ลากไปทางขวาของเราจากการถูกของเราขอบเขตบน) เพื่อป้องกันไม่ให้ช่วงเวลาแฝดถูกรวมอยู่ในช่วงของเราเมื่อเรามีขอบเขตล่างและบนเราจำเป็นต้องลบช่วงเวลาpที่p-2หรือp+2เป็นไพรม์ดังนั้นตรรกะหรือ OR และลบล้างโค้ด

นี่เป็นเวลานานเล็กน้อยและอาจจะสามารถเล่นกอล์ฟต่อไปได้ ยินดีต้อนรับคำแนะนำการเล่นกอล์ฟ ลองออนไลน์!

╗1`╜+;⌐p@p&`╓F╜+1`╜-;¬p@p&`╓F╜-x`;;¬p@⌐p|Y@p&`░

Ungolfing

╗         Store implicit input n in register 0.

1`...`╓   Get the first value x for which the following function f returns a truthy value.
  ╜         Push n from register 0.
  +         Add x to n.
  ;⌐        Duplicate n+x and add 2 to a copy of n+x.
  p         Check if n+x+2 is prime.
  @p        Swap n+x to TOS and check if n+x is prime.
  &         Logical AND the two results.
F         Push the first (and only) result of previous filtering
╜+        Add that result to n to get the upper bound for our solitude.

1`...`╓   Get the first value x for which the following function f returns a truthy value.
  ╜         Push n from register 0.
  -         Subtract x from n.
  ;¬        Duplicate n-x and subtract 2 from a copy of n-x.
  p         Check if n-x-2 is prime.
  @p        Swap n-x to TOS and check if n-x is prime.
  &         Logical AND the two results.
F         Push the first (and only) result of previous filtering.
╜-        Subtract that result from n to get the lower bound for our solitude.

x`...`░   Push values of the range [a...b] where f returns a truthy value. Variable m.
  ;;        Duplicate m twice.
  ¬p        Check if m-2 is prime.
  @⌐p       Check if m+2 is prime. 
  |Y        Logical OR the results and negate.
             This eliminates any numbers with neighboring primes.
  @p        Check if m is prime.
  &         Logical AND primality_check(m) and the previous negation.
             This keeps every other prime number in the range.

ฉันไม่ได้รับเอาต์พุตที่คาดหวัง23เมื่อ24กำหนดอินพุต ขอบเขตที่สำคัญคู่ที่ควรจะเป็น17 / 19และ29 / 31และเป็นที่สำคัญบางแห่งในช่วง23 19 .. 29
AdmBorkBork

@ TimmyD โอ้เพราะความรักของ esolangs อาจเป็นข้อผิดพลาดที่pบอกว่า25เป็นนายกยังไม่ได้รับการแก้ไขหรือเดนนิสยังไม่ได้ดึงจริงตั้งแต่การแก้ไขข้อผิดพลาด ให้ฉันไปตรวจสอบ
Sherlock9

@TimmyD เนื่องจากการแก้ไขข้อบกพร่องเสร็จสมบูรณ์แล้วคำตอบนี้ยังคงใช้ได้เนื่องจากล่ามหลักทำงานได้ เพียงว่าล่ามออนไลน์ Try It Online ยังไม่ได้รับการอัพเดต นับตั้งแต่ได้รับการอัปเดตและ TIO ควรทำงานทันที
Sherlock9

ใช่ - ขอบคุณสำหรับคำอธิบาย!
AdmBorkBork

8

PowerShell v2 +, 237 149 147 231 216 181 174 169 166 ไบต์

param($n)filter f($a){'1'*$a-match'^(?!(..+)\1+$)..'}for($i=$n;!((f $i)-and(f($i+2)))){$i++}for(){if(f(--$i)){if((f($i-2))-or(f($i+2))){if($i-lt$n-1){exit}}else{$i}}}

$nจะเข้า กำหนดฟังก์ชั่นใหม่fเป็นฟังก์ชั่นที่สำคัญ regex (ที่นี่กลับมาบูลีนถ้าอินพุตเป็นนายกหรือไม่)

ส่วนถัดไปกำหนด$iให้เท่ากับ$nแล้ววนขึ้นไปเรื่อย ๆ จนกว่าเราจะพบว่าครึ่งล่างของคู่หลักคู่บนของเรา เช่นสำหรับการป้อนข้อมูลนี้หยุดที่90$i=101

จากนั้นเราวนซ้ำจากขอบบนลง ฉันรู้ว่ามันดูเหมือนวงวนไม่สิ้นสุด แต่ในที่สุดมันก็จะจบ

หากหมายเลขปัจจุบันเป็นนายก ( f(--$i)) แต่มัน+/- 2 ไม่ได้เป็นนายกเราเพิ่ม$iไปยังท่อ อย่างไรก็ตามถ้ามัน+/- 2เป็นนายกเราตรวจสอบว่าเราต่ำกว่า$n-1(เช่นเพื่ออธิบายสถานการณ์เมื่อมันอยู่ในคู่ที่สำคัญคู่) ซึ่งเป็นจุดที่เราexitจุดที่เรา เมื่อเสร็จสิ้นโปรแกรมไปป์ไลน์จะถูกพิมพ์ไปยังหน้าจอโดยทางWrite-Outputอ้อม

NB - เนื่องจากโครงสร้างลูปให้พิมพ์จำนวนเฉพาะตามลำดับจากมากไปน้อย OP ได้ชี้แจงว่าตกลง

ตัวอย่าง

เอาต์พุตที่นี่คั่นด้วยช่องว่างเนื่องจากเป็นวิธีการสร้างสตริงเริ่มต้นสำหรับอาร์เรย์

PS C:\Tools\Scripts\golfing> 70,71,72,73,90,201,499,982|%{"$_ --> "+(.\the-solitude-of-prime-numbers.ps1 $_)}
70 --> 67
71 --> 67
72 --> 97 89 83 79 67
73 --> 97 89 83 79
90 --> 97 89 83 79
201 --> 223 211
499 --> 509 503 499 491 487 479 467
982 --> 1013 1009 997 991 983 977 971 967 953 947 941 937 929 919 911 907 887


3

JavaScript, 186 183 168 158 Bytes

// solution:
function d(d){function p(n){for(i=n;n%--i;);return!--i}u=d;for(;!p(d--)||!p(--d););for(;!p(u++)||!p(++u););for(;++d<u;)if(p(d)&&!p(d-2)&&!p(d+2))console.log(d)}

// runnable test cases:
console.info('Test ' + 70);
d(70);
console.info('Test ' + 71);
d(71);
console.info('Test ' + 72);
d(72);
console.info('Test ' + 73);
d(73);
console.info('Test ' + 90);
d(90);
console.info('Test ' + 201);
d(201);
console.info('Test ' + 499);
d(499);


ยินดีต้อนรับสู่ PPCG! คำตอบแรกที่ดี
AdmBorkBork

2

PHP, 207 ไบต์

47 54 ไบต์สำหรับis_primeฟังก์ชั่นที่ PHP ไม่มี ฉันต้องเอาชนะ Mathematica โดยปราศจากสิ่งนั้น :-D

function p($n){for($i=$n>1?$n:4;$n%--$i;);return$i<2;}if(p($n=$argv[1])&p($n+2)|$z=p($n-1)&p($n+1))$n-=2;for($n|=1;!p($n)|!p($n-2);$n--);for($z++;$z--;$n+=2)for(;$n+=2;)if(p($n)){if(p($n+2))break;echo"$n,";}

-rทำงานด้วย พิมพ์เครื่องหมายจุลภาคต่อท้าย

ทำให้พังถล่ม

// is_prime function:
// loops from $n-1 down to 1, breaks if it finds a divisor.
// returns true if divisor is <2 (==1)
// special case $n==1: initialize $i=4 to prevent warnings
function p($n){for($i=$n>1?$n:4;$n%--$i;);return$i<2;}

// is $n between primes?
if($z=p(1+$n=$argv[1])&p($n-1)) // set $z to go to the _second_ twin pair above
    $n-=2;
// no:
else
    if(p($n)&p($n+2))$n-=2;     // $n is part of the upper pair
    // p($n)&p($n-2):           // $n is part of the lower pair
    // else:                    // this is a lonely (isolated) prime

// 1. find closest twins <=$n
for($n|=1;!p($n)|!p($n-2);$n--);

// 2. list primes until the next twin primes
L:
for(;$n+=2;)if(p($n))
    if(p($n+2))break;       // next twin primes found: break loop
    else echo"$n,";         // isolated prime: print

// 3. if ($z) repeat (once)
$n+=2;  // skip twin pair
if($z--)goto L;

หมายเหตุ :

is_primeฟังก์ชั่นจริงผลตอบแทนtrueสำหรับ$n<2; แต่อย่างน้อยก็ไม่สร้างคำเตือน ใส่$n=ก่อนที่$n>1จะแก้ไข


php.net/manual/th/function.gmp-nextprime.phpห้องสมุดนี้ช่วยได้ไหม?
JörgHülsermann

@ JörgHülsermann: ถ้าจะให้อย่างน้อย 11 ไบต์ถ้า gmp จะอยู่ในการติดตั้งมาตรฐาน ลองมัน.
ติตัส


1

แร็กเก็ต 228 ไบต์

(λ(n)(let*((t 0)(lr(λ(l i)(list-ref l i)))(pl(drop(reverse(for/list((i(in-naturals))#:when(prime? i)#:final(and(> i n)
(= 2(- i t))))(set! t i)i))2)))(for/list((i(length pl))#:break(= 2(-(lr pl i)(lr pl(add1 i)))))(lr pl i))))

ข้อเสียของรุ่นนี้คือมันพบว่าตัวเลขที่สำคัญทั้งหมดจนถึง N และไม่ใช่แค่คนรอบ ๆ เอ็น

เวอร์ชันที่ไม่ถูกปรับแต่ง:

(define (f n)
  (let* ((t 0)
         (lr (λ(l i) (list-ref l i)))
         (pl (drop(reverse  
                   (for/list ((i (in-naturals))
                              #:when (prime? i)
                              #:final (and
                                       (> i n)
                                       (= 2 (- i t))))
                     (set! t i)
                     i)) 2)))
    (for/list ((i (length pl))
               #:break (= 2 (- (lr pl i) (lr pl (add1 i)))) )
      (lr pl i)))
)

การทดสอบ:

(f 90)

เอาท์พุท:

'(97 89 83 79)

1

แร็กเก็ต 245 ไบต์

(λ(n)(let((pl(reverse(let lp((n n)(t 0)(ol '()))(set! t(prev-prime n))(if(and(>(length ol)0)
(= 2(-(car ol)t)))(cdr ol)(lp t 0(cons t ol)))))))(let lq((n n)(t 0)(ol pl))(set! t(next-prime n))
(if(= 2(- t(car ol)))(cdr ol)(lq t 0(cons t ol))))))

เวอร์ชันที่ไม่ถูกปรับแต่ง:

(require math)
(define f
  (lambda(n)
    (let ((pl 
           (reverse
            (let loop ((n n) (t 0) (ol '()))
              (set! t (prev-prime n))
              (if (and
                   (> (length ol) 0)
                   (= 2 (- (car ol) t)))
                  (cdr ol)
                  (loop t 0 (cons t ol)))))))
      (let loop2 ((n n) (t 0) (ol pl))
        (set! t (next-prime n))
        (if (= 2 (- t (car ol)))
            (cdr ol)
            (loop2 t 0 (cons t ol))))))
  )

(f 90)

เอาท์พุท:

'(97 89 83 79)

1

Python 2.7: 160 ไบต์

t=lambda n:all(n%d for d in range(2,n))
def l(n):
 i=n
 while t(i)*t(i+2)-1:i+=1
 while t(n)*t(n-2)-1:n-=1
 print[x for x in range(n,i)if t(x)&~(t(x-2)|t(x+2))]

ข้อเสนอแนะยินดีต้อนรับ :)

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