Це прем'єр? без математики [закрито]


14

Напишіть програму або функцію будь-якою мовою, яка вказує, чи є вхід простим числом.

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

Які межі числа? Чи може це бути негативним? Нуль? Чи може він містити десяткову точку?
Джастін

Якщо у нього є бонусні бали, це не кодовий гольф
Пітер Тейлор

Додано "натуральний", щоб вказати межі на вході.
Уоллі

Я сподівався здивуватися якимось божевільним явним маніпулюванням рядків (я особисто думав над тим, щоб написати код для "зменшення" рядка, щоб я міг циклувати - і мене розірвало між довгим поділом рядка та повторним відніманням рядків ...), замість цього я був здивований тим крутим маленьким режекс унарним головним матчем! Можливо, мені потрібно ще раз задати питання, забороняючи регулярний вираз, щоб побачити, чи отримаю я ще чудові речі? Але я не думаю, що нічого не зможе наблизитися до стислості цього виразного плану.
Уоллі

Щоб отримати "більше чудових речей", можливо, ви можете спробувати зробити його популярним конкурсом . Зміна самого питання, як правило, нахмуриться. І я не впевнений, що вам слід поставити нове запитання або щось змінити лише тому, що хтось придумав щось, про що ви не думали - я думаю, що це трапляється тут досить часто. Крім того, правило згинання є частиною спорту :)
daniero

Відповіді:


7

Рубі, 64 - 10 = 54

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

Це повторюється від рядка '1' (плюс новий рядок) до рядка введення, використовуючи вбудований метод ітерації рядка Ruby, який виглядає жахливо, як додавання 1, але який технічно не створює числову змінну високого рівня в будь-якій точці . Він використовує той факт, що буде введено n ітерацій для введення n для створення n рядка довжини n, а потім використовує регулярне вираження, щоб визначити, чи може ця рядок згрупуватися в однакові підрядки.


Чи "1" на "карті {? 1}" є Fixnum? - якщо так, можливо, вам доведеться змінити його на "map ('1")? Я не можу знайти жодної документації на вираз? 1, за винятком деяких натяків, що в старих версіях Ruby він повертав ASCII-коди, а тепер повертає рядок .
Уоллі

? 1 те саме, що "1", це буквальний рядок з 1 символом. Я міг би замінити всі екземпляри 1, але перший, будь-яким іншим символом.
гістократ

Гаразд - я просто не міг знайти цю конструкцію десь добре описану!
Уоллі

Я вибираю це як "переможця", оскільки він виходить із шляху, щоб уникнути навіть натяку на математику.
Уоллі

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
Я не такий знайомий з Рубі, тому виправте мене, якщо я помиляюся, але чи "to_i" не перетворює рядок у ціле число? Не те, що я не люблю блискучу головну шашку в одинаку…
Wally

1
@Wally я не думаю, що "конвертувати" не є правильним словом, але метод повертає int, так. Все-таки я не використовую жодного з наступного Arithmetic operators, bit-wise operators, numeric variables and constants, і ви дійсно не можете класифікувати виклик методу як "math-stuff" in general..?
daniero

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

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 насправді не є прем'єр-міністром.
еліксинід

Використовує числовий індекс масиву - так, на краю специфікації.
Уоллі

Використовуйте 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, спочатку співпадаючи з одним фактором, потім іншим, повторюючи перший множник для решти рядка.


Мені подобається функція зменшення рядків - чітка і лаконічна.
Уоллі

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, яка буде друкувати бажаний результат. Немініфікована версія виглядає приблизно так. Я зробив руку для мінімізації, щоб очистити деякі змінні, а потім провів це через 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 ++).
Уоллі

О, не зрозумів, що я не можу зробити такий цикл .. перепишу це сьогодні ввечері.
Сугендран

В основному я створюю масив рядків, довжина яких є простими. Отже, коли я отримую введення, я продовжую додавати символи до рядка, поки значення довжини для рядка не збігається з вхідним. Потім я беру цей рядок і бачу, чи зможу я рівномірно розділити його на будь-який з відомих прайменів. Якщо я не можу, то це повинен бути прем'єр. І під діленням я маю на увазі, що я беру відомий простий рядок і продовжую додавати його до себе, довжина рядка або дорівнює, або більша, ніж у відповідній рядку.
Сугендран

Я оновив код, він фактично скорочує кількість символів :)
Сугендран,

Класно. Це схоже на ту саму ідею, що й у регулярному вираженні, але більш ефективна і чітко показує фактичну логіку.
Уоллі

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 не є простим.
Уоллі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.