Нахождение не совсем простых чисел


17

Ваша задача, если вы решите принять ее, состоит в том, чтобы закодировать в гольф функцию, которая возвращает истину или ложь (или какое-либо аналогичное значащее представление «да» и «нет»), если число соответствует следующим критериям:

  1. Целое число само является простым числом ИЛИ
  2. Любое из соседних целых чисел является простым

Например:
ввод 7вернул бы True.
Ввод 8также вернул бы True.
Вход 15вернул бы False. (Ни 14, 15, ни 16 не являются простыми)

Входные данные должны быть в состоянии правильно возвращать числа от 2 ^ 0 до 2 ^ 20 включительно, поэтому не нужно беспокоиться о проблемах со знаками или целочисленных переполнениях.


Я полагаю, переполнение 32-битных чисел, а не переполнение буфера.
пользователь неизвестен

Упс, означало "переполнение целых чисел". Мозг пошел на автопилоте.
г-н Лама

Ответы:


11

J, 17

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

Возвращает логические значения, закодированные как коды возврата процесса: ноль для true, ненулевое значение для false. Образец использования:

   */<:$&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 Отлично. Большое спасибо.
Крис Харпер

3
Сделано несколько простых изменений, надеюсь, это все еще работает:f=lambda n:any(all(m%i for i in range(2,m))for m in[n,n-1,n+1])
Nabb

@Nabb Очень мило. Отлично сработано.
Крис Харпер

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 и встроить его в регулярное выражение, протестировав «1» * (n + 1), но начиная с ^ 1? 1? вместо.
Говард

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}}}

Кофейня (53)

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

<pedantic> Это должно быть "proc", а не "lambda" </
pedantic

3

Скучная Mathematica, 35 р-р !

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

15
По крайней мере, вы можете сыграть в гольф Or@@PrimeQ/@{n-1,n,n+1}.
Говард

Это не функция.
Мартин Эндер

@ MartinBüttner: я не знаю, Mathematica, извините.
Ry-

2
Используя версию Говарда Or@@PrimeQ@{#-1,#,#+1}&(косая черта в его коде не нужна)
Мартин Эндер

3

С 112 82 72 символа

После комментария Ильмари Каронен, сохранив 30 символов, удалив main, теперь Pвозвращает true / false. Также заменены циклы с рекурсией и еще несколько твиков.

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;.
Ильмари Каронен

... и, кроме того, задача гласит: «код-гольф - функция ».
Ильмари Каронен

3

Mathematica, 24 байта

Не знаю, почему этот старый пост появился в моем списке сегодня, но я понял, что Mathematica здесь конкурентоспособна.

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

Безымянная функция, принимающая целочисленный аргумент и возвращающая Trueили False. Прямая реализация.


PrimeQпотоки над списками, так Or@@PrimeQ@{#-1,#,#+1}&(или Or@@PrimeQ[#+{-1,0,1}]&) также работает, для -1 байт. (Хотя, я думаю, я не знаю, PrimeQпереплетались ли списки в 2012 году.)
Миша Лавров


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.
Набб

@Nabb: Ух ты, ты прав. Это глупо.
Ry-

Как насчет p=j++<=n? Если Javascript здесь похож на C, он должен работать.
Угорен

@ Югорен: Похоже, это сработало, спасибо!
mellamokb

2

Регулярное выражение (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 нет ...
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+1и n-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 в качестве ввода
Бен Райх

@BenReich Это не так. Мне пришлось добавить десять символов, чтобы это исправить :(
Стив Клантон,

1

CJam, 12 байт

CJam намного моложе этой задачи, поэтому этот ответ не имеет права на зеленую галочку (которая в любом случае должна быть обновлена ​​до ответа randomra). Тем не менее, игра в гольф на самом деле была довольно забавной - я начал с 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 #, но я так много узнаю о том, как работает язык и что он может делать с помощью таких задач.


Почему это не конкурирует?
Нить

1
Потому что я не уверен, что сегодня я использую что-то в F #, чего не было, когда вопрос задавался в 2012 году. Я признаю, что это педантично - даже параноидально. Но я пишу фармацевтическое программное обеспечение для жизни. Паранойя здорова. ;)
Ciaran_McCarthy

1
Посмотрите на таблицу версий F # в Википедии . В зависимости от версии, которая вам нужна, она может быть старше вопроса.



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)это приведет к -1for n=0и non-primes, и приведет к n-1for n=1или primes. Так p(0)+p(1)+p(2)как станет -1+0+1 = 0и вернет false (даже если 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

Q, 43 символа 36

{any min each a mod 2_'til each a:x+-1 0 1}
{any(min')a mod 2_'(til')a:x+-1 0 1}

0

J, 16 символов

   (_2&<@-4 p:]-2:)

   (_2&<@-4 p:]-2:) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 1 1



0

C ++ 97

Угорен, кажется, избил меня до умного решения. Таким образом, он является короткой версией цикла трижды:

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

Forth (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< ;

Попробуйте онлайн!

объяснение

Первичная проверка (р)

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

Основная функция (е)

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)


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.