Это премьер? без математики [закрыто]


14

Напишите программу или функцию на любом языке, который сообщает, является ли ввод простым числом.

  • Входные данные представляют собой строку, представляющую собой натуральное число в base-10.
  • На выходе получается одна из двух строк «Prime» или «Not !!» который правильно определяет вход.
  • Арифметические операторы, побитовые операторы, числовые переменные и константы, «математические вещи» в целом и т. Д. ... не допускаются нигде в вашей программе. Вы должны использовать строковые операции для выполнения всех необходимых «вычислений».
  • Вы можете сравнить длины строк (которые являются числами) - но -10 с вашим счетом, если вы этого не сделаете.
  • Ваша программа должна работать на любой длине ввода (учитывая достаточно памяти и времени).
  • Наименьшее количество байтов (UTF-8) побеждает.

Каковы границы на число? Это может быть отрицательным? Нуль? Может ли он содержать десятичную точку?
Джастин

Если у него есть бонусные баллы, это не код-гольф
Питер Тейлор

Добавлен «натуральный» для указания границ на входе.
Wally

Я надеялся удивиться какой-то сумасшедшей явной манипуляции со строками (лично я думал о написании кода для «декремента» строки, чтобы можно было зацикливаться - и я разрывался между длинным делением строки и повторным вычитанием строки ...), вместо этого я был удивлен тем прохладным маленьким регулярным выражением унарным премьер-матчером! Возможно, мне нужно снова задать вопрос, запрещающий регулярное выражение, чтобы увидеть, получу ли я еще более замечательные вещи? Но я не думаю, что что-нибудь сможет приблизиться к краткости этого регулярного выражения.
Уолли

Чтобы получить «более удивительные вещи», возможно, вы можете попробовать сделать его популярным конкурсом . Хотя изменение самого вопроса обычно не одобряется. И я не уверен, что вы должны задать новый вопрос или что-то изменить только потому, что кто-то придумал что-то, о чем вы не подумали - я думаю, что это случается довольно часто здесь. Кроме того, изменение правил является частью спорта :)
Даниеро

Ответы:


7

Рубин, 64 - 10 = 54

puts ('1
'..gets).map{?1}*''=~/^1?$|^(11+?)\1+$/?'Not!!': :Prime

Это перебирает строку '1' (плюс символ новой строки) во входную строку, используя встроенный в Ruby метод итерации строк, который выглядит очень похоже на добавление 1, но технически не создает высокоуровневую числовую переменную в любой точке. , Он использует тот факт, что для ввода n для создания строки длиной n будет n итераций, а затем использует регулярное выражение, чтобы определить, можно ли сгруппировать эту строку в идентичные подстроки.


Является ли «1» в «карте {? 1}» Fixnum? - если это так, возможно, вам придется изменить его на «map ('1')». Я не могу найти никакой документации по выражению? 1, за исключением некоторых намеков на то, что в более старых версиях Ruby он возвращал коды ASCII и теперь возвращает строку .
Уолли

? 1 совпадает с '1', это строковый литерал из 1 символа. Я мог бы заменить все экземпляры 1, но первый любым другим символом.
гистократ

Хорошо - я просто не мог найти эту конструкцию, хорошо описанную где-либо!
Wally

Я выбираю это как «победитель», так как это делает все возможное, чтобы избежать даже намека на математику.
Wally

3
Никакая шляпная подсказка Эбигейл? Стыдно. Это прямая версия решения Perl 1998 года: catonmat.net/blog/perl-regex-that-matches-prime-numbers
skibrianski

16

Рубин: 52 - 10 = 42

Используя вариацию этого знаменитого регулярного выражения.

puts ?_*gets.to_i=~/^(_|(__+?)\2+)$/?"Not!!":"Prime"

Просто чтобы прояснить: ?_*gets.to_iэто строковая операция, которая добавляется "_"к себе n раз, где n - номер ввода. Как я вижу, никакие длины строк не сравниваются, поэтому они должны удовлетворять критерию бонуса в 10 символов.


1
Я не очень знаком с Ruby, так что поправьте меня, если я ошибаюсь, но разве «to_i» не преобразует строку в целое число? Не то, чтобы я не любил блестящую простейшую шашку в унарной…
Уолли

1
@ Я не думаю, что слово "convert" - не то слово, но метод возвращает int, да. Тем не менее, я не использую ничего из следующего Arithmetic operators, bit-wise operators, numeric variables and constants, и вы не можете классифицировать вызов метода как "math-stuff" in general..?
Даниеро

@daniero Звучит разумно - возможно, прямо на краю спецификации.
Wally

3

Perl 52-10 = 42

Реализация

print((('-'x$ARGV[0])=~/^.$|^(..+?)\1+$/)?Not:Prime)

демонстрация

$ seq 1 10|xargs -I{} bash -c "echo -n '{} '  && perl Prime.pl {} && echo"
1 Not
2 Prime
3 Prime
4 Not
5 Prime
6 Not
7 Prime
8 Not
9 Not
10 Not

4
1 на самом деле не простое число.
эликсид

Использует числовой индекс массива - так на краю спецификации.
Wally

Используйте popвместо $ARGV[0], сохраните 4 символа, удалите числовой индекс массива
моб

1

ECMAScript 6, 159 - 10 = 149

Звучит как задача для регулярных выражений. I / O с prompt/ alertкак обычно.

for(s=prompt(u=""); /[^0]/.test(s); )
  s=s.replace(/(.)(0*)$/,(_,d,t)=>u+="x"," 012345678"[d]+t.replace(/0/g,"9"))
alert(/^((xx+)\2+|x?)$/.test(u)?"Not!!":"Prime")

Цикл while уменьшает десятичное число на одну каждую итерацию чисто регулярным выражением. Конечное регулярное выражение соответствует строке, состоящей из составного числа x, сначала сопоставляя один фактор, затем другой, повторяя первый фактор один для остальной части строки.


Мне нравится функция декремента строки - понятная и лаконичная.
Wally

1

Javascript 266

function N(a){function b(a){return P.every(function(b){if(n=b,i=a.length,j=b.length,j>i) return;if(j==i) return 1;while(n.length<i)n+=b;return n.length!=i})}if(q=A,A!=a)for(;q.length.toString()!=a;)b(q)&&P.push(q),q+=A;console.log(b(q)?"Prime":"Not!!")}A="0",P=[A+A]

Создает функцию с именем N, которая будет печатать желаемый результат. Unminified версия выглядит следующим образом. Я выполнил минимизацию рук, чтобы очистить некоторые переменные, а затем провел их через uglify, а затем снова минимизировал их.

// A a string of "0" for using to generate long strings
// P is the store for all known primes
A="0", P=[A+A];
function N(val) {
  function _isPrime(str) {
    // go through all the known primes and return true
    // if we don't match on any of them
    return P.every(function(prime) {
      // prime is some known string whose length is a prime number
      tsr = prime, strlen = str.length, primelen = prime.length;
      // if the string we're checking has fewer chars than
      // this then it's not a prime
      if(strlen < primelen) return 0;
      // if the string we're checking has the same number of chars
      // as the the prime we're checking against then it is a prime
      if(primelen == strlen) return 1;
      // Keep incrementing our temporary string with the prime we're
      // checking. we'll break out of the loop once the temporary string
      // is greater than or equal to the string we're testing
      while(tsr.length < strlen) {
        tsr += prime;
      }
      return !(tsr.length == strlen)
    });
  }
  // start with a string of one unit
  nstr = A
  if(A!=val) {
    // keep incrementing the string so that we can compile a list
    // of known primes smaller than this value
    while(nstr.length.toString() !== val) {
      if(_isPrime(nstr)) {
        P.push(nstr);
      }
      nstr += A;
    }
  }
  console.log(_isPrime(nstr) ? "Prime" : "Not!!");
}

Протестировано с использованием этого фрагмента:

for(var X=0;X<10;X++) {
  console.log('checking: ' + X);
  N(X.toString());
}

1
Я не уверен, что вижу, как это работает, но я вижу числовую переменную (i) и арифметический оператор (i ++).
Wally

О, не понимал, что я не могу сделать цикл for, как этот ... перепишу его сегодня вечером.
Sugendran

В основном я создаю массив строк, длины которых являются простыми числами. Поэтому, когда я получаю ввод, я продолжаю добавлять символы в строку до тех пор, пока значение длины для строки не будет соответствовать вводу. Затем я беру эту строку и вижу, могу ли я равномерно разделить ее на любое из известных простых чисел. Если я не могу, тогда это должно быть простое число. И под делением я имею в виду, что я беру известную простую строку и продолжаю добавлять ее к себе, если длина строки равна или больше, чем рассматриваемая строка.
Sugendran

Я обновил код, он на самом деле немного уменьшает количество символов :)
Sugendran

Здорово. Это похоже на ту же идею, что и регулярное выражение, но более эффективно и явно показывает реальную логику.
Wally

0

Баш 66 - 10 = 56

Реализация

[[ -z `printf %$1s|grep -P "^(..+?)\1+$"` ]]&&echo Prime||echo Not

демонстрация

$ seq 1 10|xargs -I{} bash -c "echo -n '{} '  && ./Prime.sh {}"
1 Prime
2 Prime
3 Prime
4 Not
5 Prime
6 Not
7 Prime
8 Not
9 Not
10 Not

Как и выше, 1 не является простым.
Wally

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