การค้นหาตัวเลขที่ไม่ได้สำคัญมาก


17

ความท้าทายของคุณถ้าคุณเลือกที่จะยอมรับมันคือการฟังก์ชั่น code-golf ที่ส่งคืนจริงหรือเท็จ (หรือบางส่วนที่มีความหมายคล้ายกันคือใช่และไม่ใช่) หากตัวเลขตรงตามเกณฑ์ต่อไปนี้:

  1. จำนวนเต็มนั้นเป็นจำนวนเฉพาะหรือ
  2. จำนวนเต็มเพื่อนบ้านอย่างใดอย่างหนึ่งเป็นจำนวนเฉพาะ

ตัวอย่างเช่น:
อินพุต7จะคืนค่าเป็น True
อินพุตของ8จะส่งคืนค่าเป็น True ด้วยเช่นกัน
อินพุตของ15จะส่งคืนค่าเท็จ (ทั้ง 14, 15, หรือ 16 เป็นไพร์ม)

อินพุตต้องสามารถส่งคืนได้อย่างถูกต้องสำหรับตัวเลขระหว่าง 2 ^ 0 ถึง 2 ^ 20 ดังนั้นจึงไม่จำเป็นต้องกังวลเกี่ยวกับปัญหาการลงชื่อหรือการล้นของจำนวนเต็ม


ฉันเดาว่าเป็นจำนวนมากเกิน 32 บิตไม่ใช่บัฟเฟอร์มากเกิน
ผู้ใช้ที่ไม่รู้จัก

อ๊ะเกิดความหมายว่า "จำนวนเต็มล้น" สมองทำงานอัตโนมัติ
Mr. Llama

คำตอบ:


11

J, 17

*/<:$&q:(<:,],>:)

ส่งคืน booleans ที่เข้ารหัสเป็นรหัสส่งคืนกระบวนการ: ศูนย์สำหรับจริงไม่ใช่ศูนย์สำหรับเท็จ ตัวอย่างการใช้งาน:

   */<:$&q:(<:,],>:) 7
0
   */<:$&q:(<:,],>:) 8
0
   */<:$&q:(<:,],>:) 15
3

*/0 p:<:,],>:สั้นลงและฟังก์ชั่นที่เหมาะสม (แลมบ์ดา) คือ([:*/0 p:<:,],>:)
randomra


6

Python 85 80

def f(n):g=lambda n:all(n%i!=0for i in range(2,n));return g(n)or g(n-1)or g(n+1)

เป็นครั้งแรกที่ Code Golf ดังนั้นอาจมีลูกเล่นบางอย่างที่ขาดหายไป


[]คุณสามารถลบ ทั้งหมดจะมีความสุขมากกว่าที่จะทำงานกับนิพจน์ตัวสร้าง หากคุณไม่ทราบรหัสของคุณเป็นที่น่าเกลียดคุณยังสามารถลบช่องว่างระหว่าง0และforและและ) or
stranac

@stranac Awesome ขอบคุณมาก.
Kris Harper

3
ทำการเปลี่ยนแปลงเล็กน้อยอย่างตรงไปตรงมาหวังว่ามันจะยังคงใช้ได้:f=lambda n:any(all(m%i for i in range(2,m))for m in[n,n-1,n+1])
2012 เวลา 13:35

@Nabb ดีมาก ทำได้ดี.
Kris Harper

5

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

Python (2.x), 85 ตัวอักษร

import re
f=lambda n:any(not re.match(r"^1?$|^(11+?)\1+$","1"*x)for x in[n,n-1,n+1])

คุณสามารถลบ for loop และสร้างลงใน regexp โดยการทดสอบ "1" * (n + 1) แต่เริ่มต้นด้วย ^ 1? 1? แทน.
Howard

4

ทับทิม (55 หรือ 50 เป็นแลมบ์ดา)

def f q;(q-1..q+1).any?{|n|(2..n-1).all?{|d|n%d>0}};end

หรือแลมบ์ดา (ใช้ g[23]เรียกมัน)

g=->q{(q-1..q+1).any?{|n|(2..n-1).all?{|d|n%d>0}}}

Coffeescript (53)

p=(q)->[q-1..q+1].some (n)->[2..n-1].every (d)->n%d>0

<pedantic> มันควรจะเป็น "proc" ไม่ใช่ "lambda" </pedantic> ;-)
Doorknob

3

Mathematica ที่น่าเบื่อ35คำตอบ!

PrimeQ[n-1]||PrimeQ[n]||PrimeQ[n+1]

15
Or@@PrimeQ/@{n-1,n,n+1}อย่างน้อยคุณอาจกอล์ฟมันเข้าไป
Howard

นี่ไม่ใช่ฟังก์ชั่น
Martin Ender

@ MartinBüttner: ฉันไม่รู้ Mathematica ขอโทษ
Ry-

2
ใช้เวอร์ชั่นของ Howard Or@@PrimeQ@{#-1,#,#+1}&(ไม่จำเป็นต้องใช้เครื่องหมายทับในโค้ดของเขา)
Martin Ender

3

C, 112 82 72 ตัวอักษร

ติดตามความคิดเห็นของ Ilmari Karonen ได้บันทึก 30 ตัวอักษรโดยการลบmainตอนนี้Pกลับเป็นจริง / เท็จ แทนที่ลูปด้วยการเรียกซ้ำและการปรับแต่งเพิ่มเติม

p(n,q){return++q==n||n%q&&p(n,q);}P(n){return p(-~n,1)|p(n,1)|p(~-n,1);}

รุ่นเดิม:

p(n,q,r){for(r=0,q=2;q<n;)r|=!(n%q++);return!r;}
main(int n,int**m){putchar(48|p(n=atoi(*++m))|p(n-1)|p(n+1));}

คุณสามารถประหยัด 2 main(n,m)int**m;ตัวอักษรด้วย
Ilmari Karonen

... และนอกจากนี้ความท้าทายบอกว่า "โค้ดกอล์ฟฟังก์ชั่น "
Ilmari Karonen

3

Mathematica ขนาด 24 ไบต์

ไม่ทราบว่าทำไมโพสต์เก่านี้ปรากฏในรายการของฉันวันนี้ แต่ฉันรู้ว่า Mathematica แข่งขันที่นี่

Or@@PrimeQ/@{#-1,#,#+1}&

ฟังก์ชั่นที่ไม่มีชื่อการอาร์กิวเมนต์จำนวนเต็มและกลับมาหรือTrue Falseการใช้งานโดยตรง


PrimeQเธรดเหนือรายการดังนั้นOr@@PrimeQ@{#-1,#,#+1}&(หรือOr@@PrimeQ[#+{-1,0,1}]&) ก็ใช้งานได้เช่นกันสำหรับ -1 ไบต์ (แม้ว่าฉันเดาว่าฉันไม่รู้ว่าจะมีPrimeQเธรดมากกว่ารายการในปี 2012) หรือไม่
Misha Lavrov


2

JavaScript (71 73 80 )

n=prompt(r=0);for(j=n-2;p=j++<=n;r|=p)for(i=1;++i<j;)p=j%i?p:0;alert(r)

การสาธิต: http://jsfiddle.net/ydsxJ/3/

แก้ไข 1:เปลี่ยนfor(i=2;i<j;i++)เป็น for(i=1;++i<j;)(ขอบคุณ@minitech) แปลงifคำสั่งเป็นสามส่วน ย้ายr|=pและp=1เข้าสู่ภายนอกforเพื่อกำจัดการจัดฟันด้านใน บันทึก 7 ตัวอักษร

แก้ไข 2:รวมp=1และj++<=nไปยังp=j++<=nบันทึก 2 ตัวอักษร (ขอบคุณ@ugoren)


คุณสามารถใช้for(i=1;++i<j;)แทนfor(i=2;i<j;i++)การบันทึกได้อีก 1 ตัวอักษร
Ry-

1
@minitech: !j%iจะไม่ทำงานเพราะความสำคัญ j%i<1ทางเลือกที่ทำงาน
2012

@Nabb: ว้าวคุณพูดถูก นั่นมันโง่
Ry-

แล้วไงp=j++<=nล่ะ หาก Javascript เหมือนกับ C ที่นี่ควรใช้งานได้
ugoren

@ugoren: ดูเหมือนว่ามันทำงานได้ขอบคุณ!
mellamokb

2

Regex (ECMAScript), 20 ไบต์

^x?x?(?!(x+)(x\1)+$)

ลองออนไลน์!

เวอร์ชั่นด้านบนจัดการกับศูนย์ไม่ถูกต้อง แต่ใช้เวลาเพิ่ม 1 ไบต์เท่านั้น:

^x?x?(?!(x+)(x\1)+$)x

ในฐานะโบนัสที่เพิ่มเข้ามานี่เป็นเวอร์ชั่นที่ให้ผลตอบแทนการแข่งขัน1สำหรับผู้ที่มีค่าน้อยกว่าผู้ชนะเลิศ2สำหรับ3ผู้ชนะเลิศและผู้ชนะมากกว่าหนึ่งคน:

^x?x??(?!(x+)(x\1)+$)x

ลองออนไลน์!


ช่วงคำถามที่พูดถึงคือ "ระหว่าง 2 ^ 0 และ 2 ^ 20" ดังนั้น 1..2 ^ 20 ดังนั้น 0 ไม่มี 0 ...
RosLuP

@RosLuP ซึ่งเป็นสาเหตุที่คำตอบหลักของฉันคือ 20 ไบต์และไม่จัดการ 0 อย่างถูกต้อง ฉันพบว่าคุณค่าเกินกว่าข้อกำหนดที่แน่นอนของคำถามและให้คำตอบที่มีประสิทธิภาพมากขึ้นพร้อมกับคำตอบที่ตรงกับข้อกำหนดของคำถามน้อยที่สุด
Deadcode

บางครั้งฉันทำแบบเดียวกัน (เขียนการทดสอบ 'ไม่จำเป็น') แต่ดูเหมือนว่าจะขัดกับวิธีคิด codegolf และคนที่เขียนพวกเขาจะไม่ถือว่า "ร้ายแรง" ...
RosLuP

1
@RosLuP แต่อะไรคืออันตรายตราบใดที่ฉันให้คำตอบน้อยที่สุดกับคำตอบหลักของฉัน และคุณสามารถยกตัวอย่างของคนที่คิดแบบนั้นจริง ๆ ได้ไหม? ฉันสามารถเข้าใจมันถ้าฉันให้ฉันเพียงคำตอบที่เป็นหนึ่งที่แข็งแกร่ง แต่ฉันไม่ได้ทำอย่างนั้น
Deadcode

1

C #, 96

มันส่งกลับ -1,0,1 สำหรับจริงสิ่งอื่นใดเป็นเท็จ

ข้อเสนอแนะใด ๆ ที่จะทำให้มันสั้นลงจะยอดเยี่ยม!

int p(int q){var r=q-1;for(var i=2;i<r&r<q+2;i++){if(i==r-1)break;if(r%i==0)r+=i=1;}return r-q;}

รูปแบบการขยายตัว:

int p(int q){
    var r=q-1;
    for(var i=2;i<r&r<q+2;i++){
        if(i==r-1)break;
        if(r%i==0)r+=i=1;
    }
    return r-q;     
}

ฉันไม่แน่ใจว่าทั้งหมด แต่ผมคิดว่าคุณสามารถลบif(i==r-1)break;และเปลี่ยนตรงกลางของforวงจากไปi<r i<r-1มันจะพาคุณลงมาที่ 82
Ciaran_McCarthy

1

GolfScript: 26

)0\{.:i,{i\%!},,2=@|\(}3*;

คำอธิบาย: บล็อกชั้นในสุด{.:i,{i\%!},,2=@|\(}จะกำหนดว่าส่วนบนสุดของสแต็กนั้นเป็นไพร์มหรือไม่โดยตรวจสอบว่ามีปัจจัย 2 อย่างน้อยกว่าด้านบนสุดของสแต็กหรือไม่ จากนั้นจะแยกสิ่งนี้ออกด้วยไอเท็มที่สองบนสแต็กซึ่งเก็บสถานะว่ามีการดูไพรม์หรือไม่ ในที่สุดก็ลดจำนวนที่ด้านบนของสแต็ค

เริ่มต้นด้วยการเพิ่มอินพุตอินพุตเริ่มต้นสถานะไพรม์ที่เห็นและทำซ้ำบล็อก 3 ครั้ง ตั้งแต่นี้จะพร่องสองครั้ง แต่เราเริ่มต้นโดยการเพิ่มนี้จะครอบคลุมและn+1n-1


1

C #, 87 97 ตัวอักษร

bool p(int q){return new[]{q-1,q,q+1}.Any(x=>Enumerable.Range(2,Math.Abs(x-2)).All(y=>x%y!=0));}

ฉันไม่คิดว่าจะใช้งานได้กับ 1 หรือ 2 เป็นอินพุต
Ben Reich

@BenReich มันไม่ได้ ฉันต้องเพิ่มสิบตัวอักษรเพื่อแก้ไข :(
Steve Clanton

1

CJam, 12 ไบต์

CJam อายุน้อยกว่าความท้าทายนี้ดังนั้นคำตอบนี้จึงไม่มีสิทธิ์ใช้เครื่องหมายถูกสีเขียว (ซึ่งควรได้รับการอัปเดตเป็นคำตอบแบบสุ่มของต่อไป) อย่างไรก็ตามการเล่นกอล์ฟมันสนุกจริงๆ - ฉันเริ่มต้นที่ 17 ไบต์และเปลี่ยนวิธีการเล่นของฉันอย่างสมบูรณ์สามครั้งโดยประหยัดหนึ่งหรือสองไบต์ในแต่ละครั้ง

{(3,f+:mp:|}

นี่คือบล็อกซึ่งเทียบเท่ากับฟังก์ชันใน CJam ที่ใกล้เคียงที่สุดซึ่งคาดว่าอินพุตในสแต็กและปล่อย 1 (ความจริง) หรือ 0 (เท็จ) บนสแต็ก

ทดสอบที่นี่

นี่คือวิธีการทำงาน:

(3,f+:mp:|
(          "Decrement the input N.";
 3,        "Push an array [0 1 2].";
   f+      "Add each of those to N-1, to get [N-1 N N+1].";
     :mp   "Test each each element for primality, yielding 0 or 1.";
        :| "Fold bitwise OR onto the list, which gives 1 if any of them was 1.";

1

F #, 68 ไบต์ (ไม่แข่งขัน)

let p n=Seq.forall(fun x->n%x>0){2..n-1}
let m n=p(n-1)||p n||p(n+1)

ลองออนไลน์!

นี่คือเหตุผลที่ฉันรักรหัสกอล์ฟ ฉันยังคงเป็นมิตรกับสิ่งแวดล้อมด้วย F # แต่ฉันได้เรียนรู้มากมายเกี่ยวกับวิธีการทำงานของภาษาและสิ่งที่สามารถทำได้จากความท้าทายเหล่านี้


ทำไมมันถึงไม่ใช่การแข่งขัน?
Nit

1
เพราะฉันไม่แน่ใจว่าฉันใช้อะไรใน F # วันนี้ที่ไม่ได้อยู่รอบ ๆ เมื่อคำถามถูกถามในปี 2012 ฉันยอมรับว่ามันเชื่องช้าแม้แต่หวาดระแวง แต่ฉันเขียนซอฟต์แวร์เภสัชกรรมเพื่อหาเลี้ยงชีพ ความหวาดระแวงมีสุขภาพดี ;)
Ciaran_McCarthy

1
ดูที่F # 's ตารางรุ่นในวิกิพีเดีย อาจเก่ากว่าคำถามทั้งนี้ขึ้นอยู่กับรุ่นที่คุณต้องการ



1

Java 8, 83 ไบต์

n->n==1|p(n-1)+p(n)+p(n+1)>0int p(int n){for(int i=2;i<n;n=n%i++<1?0:n);return--n;}

ส่งคืนtrue/ falseเป็นค่าจริง / เท็จ

ลองออนไลน์

คำอธิบาย: "

n->                    // Method with integer parameter and boolean return-type
  n==1                 //  Return whether the input is 1 (edge-case)
  |p(n-1)+p(n)+p(n+1)>0//  Or if the sum of `n-1`, `n`, and `n+1` in method `p(n)` is not 0

int p(int n){          // Separated method with integer as both parameter and return-type
  for(int i=2;i<n;     //  Loop `i` in the range [2, `n`)
    n=n%i++<1?         //   If `n` is divisible by `i`
       0               //    Change `n` to 0
      :                //   Else:
       n);             //    Leave `n` as is
                       //  (After the loop `n` is either 0, 1, or unchanged,
                       //   if it's unchanged it's a prime, otherwise not)
  return--n;}          //  Return `n` minus 1

ดังนั้นint p(int n)จะส่งผลให้-1สำหรับn=0และไม่ใช่ช่วงเวลาและจะส่งผลn-1ให้n=1หรือเฉพาะช่วงเวลา ตั้งแต่p(0)+p(1)+p(2)จะกลายเป็น-1+0+1 = 0และจะกลับเท็จ (แม้ว่า2จะเป็นนายก) n=1เป็นกรณีที่ขอบโดยใช้วิธีการนี้


วนรอบเดียวโดยไม่มีวิธีการแยกจะเป็น85 ไบต์ :

n->{int f=0,j=2,i,t;for(;j-->-1;f=t>1?1:f)for(t=n+j,i=2;i<t;t=t%i++<1?0:t);return f;}

ส่งคืน1/ 0เป็นค่าจริง / เท็จ

ลองออนไลน์

คำอธิบาย:

n->{              // Method with integer as both parameter and return-type
  int f=0,        //  Result-integer, starting at 0 (false)
      j=2,i,      //  Index integers
      t;          //  Temp integer
  for(;j-->-1;    //  Loop `j` downwards in range (2, -1]
      f=          //    After every iteration: Change `f` to:
        t>1?      //     If `t` is larger than 1 (`t` is a prime):
         1        //      Change `f` to 1 (true)
        :         //     Else:
         f)       //      Leave `f` the same
    for(t=n+j,    //   Set `t` to `n+j`
        i=2;i<t;  //   Inner loop `i` in the range [2, t)
      t=t%i++<1?  //    If `t` is divisible by `i`:
         0        //     Change `t` to 0
        :         //    Else:
         t);      //     Leave `t` the same
                  //   (If `t` is still the same after this inner loop, it's a prime;
                  //   if it's 0 or 1 instead, it's not a prime)
  return f;}      //  Return the result-integer (either 1/0 for true/false respectively)


0

R, 68 ตัวอักษร

f=function(n){library(gmp);i=isprime;ifelse(i(n-1)|i(n)|i(n+1),1,0)}

การใช้งาน (1 สำหรับ TRUE, 0 สำหรับ FALSE):

f(7)
[1] 1
f(8)
[1] 1
f(15)
[1] 0

1
ฉันไม่รู้วิธีการทำงานของ R จริงๆ แต่คุณสามารถทำi(n-1)|i(n)|i(n+1)แทนได้ifelse(i(n-1)|i(n)|i(n+1),1,0)หรือไม่?
Ry-

คุณพูดถูก: g = function (n) {library (gmp); i = isprime; i (n-1) | i (n) | i (n + 1)} - ลดลงถึง 56 ตัวอักษร! ;-)
เปาโล

0

C ++

k=3;cin>>i;i--;
while(k)
{l[k]=0;
  for(j=2;j<i;j++)
   if(!(i%j))
     l[k]++;
  k--;
  i++;
}
if(!l[1]|!l[2]|!l[3])
     cout<<"1";
else cout<<"0";

ยินดีต้อนรับสู่ CodeGold.SE หากคุณดูคำตอบอื่น ๆ คุณจะสังเกตเห็นรูปแบบทั่วไปที่ใช้สำหรับคำตอบของคำถาม [code-golf] คุณอาจต้องการนำไปใช้กับคำตอบของคุณเช่นกัน
dmckee





0

C ++ 97

ugoren ดูเหมือนจะเอาชนะฉันไปยังทางออกที่ฉลาด ดังนั้นเขาจึงเป็นเวอร์ชั่นสั้น ๆ ในวงวนสามครั้ง:

P(int k){int j=1;for(int i=2;i<k;){j=k%i++&&j;}return j;}
a(int b){return P(b)|P(b+1)|P(b-1);}

0

ออกมา (gforth) 104 ไบต์

: p dup 1 > if 1 over 2 ?do over i mod 0> * loop else 0 then nip ;
: f dup 1- p over 1+ p rot p + + 0< ;

ลองออนไลน์!

คำอธิบาย

นายกรัฐมนตรี (p)

dup 1 > if          \ if number to check if greater than 1
   1 over 2 ?do     \ place a 1 on the stack to act as a boolean and loop from 2 to n
      over i  mod   \ take the modulo of n and i
      0> *          \ check if greater than 0 (not a divisor) and multiply result by boolean
   loop             \ end the loop, result will be -1 if no divisor was found (prime)
else                \ if n is less than 2
   0                \ put 0 on the stack (not prime)
then                \ end the loop
nip                 \ drop n from the stack

ฟังก์ชั่นหลัก (f)

dup 1- p             \ get n-1 and check if prime
over 1+ p            \ get n+1 and check if prime
rot p                \ rotate stack to put n on top and check if prime
+ + 0<               \ add the three results and check if less than 0 (at least 1 was prime)


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