Знайдіть найменший прайм від підрядка


17

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

Користувачі введуть послідовність цифр, і ви знайдете найменший прайм, який містить цей рядок у базі 10.

Приклад:

input   -> output
"10"    -> 101
"03"    -> 103
"222"   -> 2221
"98765" -> 987659

Виграє найкоротший код у байтах . Я знаю, що деякі мови (математика, мудрець, pari-gp ...) мають вбудовані функції, пов'язані з праймерами. -50 байт, якщо програма не покладається на такі функції. Не намагайтеся обдурити це, будь ласка, якщо ваша мова вже має величезну перевагу, не вимагайте премії.

Редагувати

Відповідно до кількох коментарів нижче, найменший показник, який містить "03", - це 3. Чи справді це має значення? Єдине, про що я можу придумати, - це те, що, можливо, цифри легше обробляти, ніж рядки.

У таких випадках, як "03", кращим результатом буде 103. Однак я не вважаю це основоположною частиною вашої програми, тому ви можете ігнорувати будь-який провідний нуль, якщо він надасть вам меншу кількість байтів.


5
Це здається приємною базою для завдання проекту Euler
Джон Дворак

Найменший простір, що містить "03", - це 03. Можливо, вам слід додати правило, що пояснює, що вхід може містити провідні нулі, але вихід може не робити.
Річка рівня Св.

2
@steveverrill немає такої кількості, як 03. Якщо ви мали на увазі 3, то це не містить "03".
Джон Дворак

3
@JanDvorak 03 є дійсним поданням числа 3. (2.9 ... повторюється нескінченно, еквівалентно 2 + 9/9, також вважається деяким правильним поданням.) Я розумію з прикладу, зважаючи на те, що 03 не є прийнятним представлення цього питання. Це педантний пункт, але, зважаючи на звичайне зловживання правилами, я думаю, що варто зробити це.
Рівень річки Св.

1
Я думаю, що кращим способом викласти слово було б знайти найменше число, яке при перетворенні на рядок міститиме "03".
Thebluefish

Відповіді:


13

Golfscipt, 33 32 байти = -18 балів

2{:x,2>{x\%!},!!x`3$?)!|}{)}/;;x

Пояснення:

  • 2{...}{)}/- починаючи з 2, хоча щось істинне, збільшуючи верхню частину стека
  • ;;x- відкиньте проміжні значення, зібрані за {}{}/та вхідні дані, а потім поставте туди останнє тестоване значення

  • :x,2>- зберігати значення , як x, то список від 2доx-1

  • {x\%!},!!- зберігайте ті, що xподіляються на, а потім примушуйте до булевих (не порожніх)
  • x`3?)!- шукайте введення у текстовій формі x( -1якщо його не знайдено), приріст, заперечення.
  • | - або

7

Програма Haskell, 97 символів = 47 балів

main=getLine>>= \i->print$head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]

Функція Haskell, 75 символів = 25 балів

p i=head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]

тип pє (Integral a, Show a) => [Char] -> a. Якщо ви надаєте свій власний інтегральний тип, ви можете шукати шляхом інфікування у власному представленні цих значень. Стандарт Integerвикористовує очікувані десяткові позначення для цілих чисел.

Не дуже швидко. Квадратичне значення (не розмір) виводу.

неозорений варіант:

import Data.List
leastPrime infix = head $ filter prime' [2..]
  where prime' x  = all (\n-> x`mod`n /= 0) [2..x-1]
                 && i `isInfixOf` show x
main = print . leastPrime =<< getLine

приклад:

Prelude> let p i=head$[x|x<-[2..],all((/=0).mod x)[2..x-1],i`Data.List.isInfixOf`show x]
Prelude> p "0"
101
Prelude> p "00"
1009
Prelude> p "000" -- long pause
10007

3

Java - 175 символів.

class s{public static void main(String[]a){int i,n=2,p;for(;;){p=1;for(i=3;i<n;i++)if(n%i==0)p=0;if((n==2||p>0)&&(""+n).indexOf(a[0])>=0) {System.out.println(n);break;}n++;}}}

Ви можете зберегти 1 символ, пропустивши пробіл між indexOf(a[0])>=0)і {System.out.println(n).
ProgramFOX

@ProgramFOX Дякую
wildcard

Я думаю, що ви можете легко зберегти (близько 8) символів, замінивши свої boolean p=trueчимось подібним int p=1тощо.
флоріан h

оголошення одразу всіх ваших вкладень ще більше зменшить розмір програми.
Олів'є Грегоар

3

Математика 58

(n=1;While[StringCases[ToString[p=Prime@n],#]=={},n++];p)&

Відносні моменти часу на моєму Mac (2,6 ГГц i7 з 8 ГБ пам'яті).

Знайдіть найменший простір, що містить "01".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["01"]]

{0.000217, 101}


Знайдіть найменший простір, що містить "012345".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["012345"]]

{5.021915, 10123457}


Знайдіть найменший простір, що містить "0123456".

AbsoluteTiming[(n = 1; While[StringCases[ToString[p = Prime@n], #] == {}, n++]; p) &["0123456"]]

{87.056245, 201234563}


Ви можете використовувати StringFreeQїї для скорочення.
алефальфа

2

Мудрець , 72

Працює в інтерактивному рядку

a=raw_input()
i=0
p=2
while a not in str(p):i+=1;p=Primes().unrank(i)
p

Primes().unrank(i)дає iперше просте число, причому 0-й простий дорівнює 2.


2

R 56 56 -50 = 6

k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k

Візьміть вклад як stdin. Збільшення k до k є простим (перевіряється шляхом підсумовування екземплярів, для яких k mod 2 до k - нулі, отже, FALSE, оскільки 0 перетворився на логічну, є FALSE) і містить рядок, заданий як вхідний (перевірений простим grep, тут grepl оскільки ми хочемо логічного результату).

Використання:

> k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k
1: "03"
2: 
Read 1 item
[1] 103
> k=2;n=scan(,"");while(!grepl(n,k)|sum(!k%%2:k)>1)k=k+1;k
1: "003"
2: 
Read 1 item
[1] 2003

2

оболонка однолінійки (coreutils): 45 годин

Тут не визначається функція ... просто oneliner, який бере один аргумент $nі сканує цілий діапазон (насправді трохи більше, щоб скоротити код). Версія 55 символів:

seq 5e9|grep $n|factor|awk '{if(NF==2)print $2}'|head -n1

Це навіть не надто повільно. Бо n=0123456він повертається 201234563в 81.715s. Це вражаюче швидко для довгого конвеєра з двома струнними процесорами.

Видаляючи два символи (до 53) та одну трубу, ми можемо запустити її ще швидше:

seq 5e9|grep $n|factor|awk '{if(NF==2){print $2;exit}}'

І нарешті, якийсь sedмайстер зведе до 45 символів , хоча роздруківка некрасива:

seq 5e9|grep $n|factor|sed -n '/: \w*$/{p;q}'

n = 000 -> 10007: 10007 (користувач 0,017s)

n = 012345 -> 10123457: 10123457 (користувач 7.11s)

n = 0123456 -> 201234563: 201234563 (користувач 66,8s)


2

J - 38 char -50 = -12 балів

Зазвичай в J ви використовуєте дуже оптимізовані вбудовані елементи, призначені для праймес, тому я не збираюся вибачатися за повільність у виконанні.

>:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2

Пояснили:

  • >:@]^:(...)^:_&2- Починаючи з 2, з кроком, поки не (...)повернеться false.
  • (+.i.)@]- Візьміть GCD лічильника з кожним цілим числом, меншим за нього. (Ми використовуємо конвенцію GCD (X, 0) = X.)
  • ]=*/@- Візьміть добуток усіх цих чисел і перевіряйте рівність на лічильник. Якщо лічильник є простим, у списку були всі 1, за винятком GCD з 0; інакше буде принаймні один GCD, більший за 1, тому продукт буде більшим за лічильник.
  • >./@(E.":) - Перевірте, чи є рядкове представлення лічильника (": ) містить рядок ( E.) у будь-якій точці. >./є функцією max, і ми використовуємо її, тому що E.повертає булевий вектор з 1, де б не починалося підрядку в основному рядку.
  • *:- Логічні NAND результати разом. Це буде помилковим, лише якщо обидва входи були правдивими, тобто якщо лічильник обох був простим і містив підрядку.

Використання:

   >:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2 '03'
103
   >:@]^:(>./@(E.":)*:]=*/@(+.i.)@])^:_&2 '713'
2713

Щодо нащадків, ось версія, яка використовує основний вбудований (тривалістю 30 знаків, але без бонусу):

>:@]^:(>./@(E.":)*:1 p:])^:_&2

1 p:] тестує лічильник на первинність замість фокусу GCD.


2

Brachylog (v2), 3 байти в кодуванні Brachylog

ṗ≜s

Спробуйте в Інтернеті!

Подання функції, беручи введення з правого аргументу, видаючи висновок шляхом мутації лівого аргументу. (Це протилежне звичайній конвенції Брахілогів; див. Цей мета-пост для додаткового обговорення. Заміна аргументів на більш звичний порядок обійдеться в три байти.) Посилання TIO має обгортку, яка викликає функцію відповідною умовою виклику та друкує результат.

Пояснення

ṗ≜s
 ≜   Find the integer closest to zero
ṗ      which is prime {implicit: and output it via the left argument}
  s    and which is a substring of the {right argument}

На жаль, Брахілог настільки підходить для цієї проблеми, що згідно з правилами проблеми, я навіть не можу намагатися отримати бонус (що іронічно означає, що він нездатний виграти).

Однією з причин, що мені дуже подобається Брахілог, є те, що програмування - це спілкування між людиною та комп'ютером, і, таким чином, "ідеальна" мова дозволить вам просто перекласти специфікацію проблеми безпосередньо англійською мовою; ідеї, за допомогою яких було заявлено про проблему та за допомогою якої написана програма, були б однаковими. Брахілог може вражати цей ідеал напрочуд часто; тут питання "знайти найменший прайм, що містить задану підрядку", і я можу буквально об'єднати поняття "найменший, простий, що містить підрядку" у правильному порядку та мати робочу програму. Як такий, Брахілог говорить набагато більше про природу спілкування, ніж про мову, в якій вам довелося чітко вказати алгоритм вирішення проблеми; іноді, розмовляючи з іншими людьми, ми намагаємось пояснити проблему, пояснюючи кроки, які ви зробили б для її вирішення, але це рідко. То чому наші мови повинні бути різними?


1

JavaScript 83 байти = 33 бали

Гольф:

for(s=prompt(n=x=0);!n;x++)for(n=(''+x).match(s)?2:0;n&&n<x;n=x%n?n+1:0);alert(x-1)

Безголів (трохи):

s=prompt() // get the input
n = 0
for(x=0;!n;x++) // stop when n is non-zero
    if ((''+x).match(s)) { // if x matches the pattern, check if x is prime
        for(n=2;n&&n<x;)
            n = (x%n == 0) ? 0 : n+1; // if x%n is zero, x is not prime so set n=0
        // if n is non-zero here, x is prime and matches the pattern
    }
alert(x-1)

0

Javascript (Node.JS) - 93 байти = 43 бали

l:for(i=x=process.argv[2];j=i;i++){while(--j>2)if(!(i%j*(""+i).match(x)))continue l
throw i}

У вилученому вигляді з чутливими назвами змінних:

outerLoop:for (currentTry=inputNumber=process.argv[2]; primeIterator=currentTry; currentTry++ ) {
    while (--primeIterator > 2) 
        if(!(currentTry % primeIterator * (""+currentTry).match(inputNumber)))
            continue outerLoop;
    throw i
}

0

Іржа 0,9 136 байт = 86 балів

fn main(){
   let mut n:u32=2;
   while n.to_str().find_str(std::os::args()[1])==None ||
         range(2,n).find(|&x|n%x==0)!=None {
      n=n+1;
   }
   print!("{}",n);
}

Дуже явний попри компактність. Занадто багато місця витрачено на пошук рядків. :(

Тут версія без пробілів (136 char)

fn main(){let mut n:u32=2;while n.to_str().find_str(std::os::args()[1])==None||range(2,n).find(|&x|n%x==0)!=None{n=n+1;}print!("{}",n);}



0

Perl 6 , 36 - 50 = -14 балів

{$^a;first {/$a/&&$_%%one ^$_},2..*}

Спробуйте в Інтернеті!

Враховуючи $_%%one ^$_, що лише 2 байти менші за розмір.is-prime , я вважаю, що це варто для бонусу. Це час очікується на останній тестовий випадок.

Пояснення:

{                                  }  # Anonymous code block
 $^a;                                 # Assign input to $a
     first                    ,2..*   # Find the first number
           {                 }        # Which
            /$a/                        # Contains the input
                &&                      # And
                  $_%%one ^$_           # Is prime

На 2 байти менше?
лише ASCII

lol @ частина запитання, в якій сказано: "Не намагайтеся обдурити це, будь ласка, якщо ваша мова вже має величезну перевагу, не вимагайте премії".
лише ASCII

@ ASCII only Ну, мене все ще б’є GolfScript, тому ...:$
Jo King

0

Python 3 , 80 79 байт - 50 = 30 29 балів

-1 байт завдяки творчому використанню лише @ ASCII, %sа неstr

Тестовий випадок "98765" ще не підтверджений через те, як довго потрібно тестування. Підтверджено для тестового випадку "98765" через пару годин, але з аналогічним підходом, який використовує оцінку короткого замикання, щоб уникнути деяких перевірок первинності. набагато швидше. Крім того, це може бути ~ 2х швидше, якщо ми знаємо, що "2" не є входом (ми можемо уникнути перевірки парних чисел на первинність), встановивши i=3спочатку і i+=2в циклі, без зайвих витрат на байт.

def f(x):
 i=2
 while(x in"%s"%i)*all(i%j for j in range(2,i))-1:i+=1
 return i

Спробуйте в Інтернеті!

Пояснення whileумови ( (x in"%s"%i)*all(i%j for j in range(2,i))-1):

(x in"%s"%i): True/ 1якщо поточний лічильник містить бажану послідовність чисел у ньому; False/ 0інакше.

all(i%j for j in range(2,i)): True/ 1якщо у поточного лічильника завжди є залишок, поділений на будь-яке ціле число від 2 (включно) до самого себе (виключне), тобто просте; False/0 інакше.

У *примножує два умови разом, і виступає в якості andоператора - продукт True/ 1тоді і тільки тоді , коли обидві умови True/1 .

-1Виступає в якості notоператора: False/ 0- 1 призводить до -1, який вважається дійсним, тоді як True/ 1- 1 призводить0 , який вважається хибним. Таким чином, цикл продовжується, поки число або не містить бажаної послідовності чисел, або не є простим.

Замінити *з andі додати в круглі дужки все , але -1для набагато швидше, аналогічне рішення (тобто трохи більше).

76 байт - 50 = 26 балів розчин в Python 2 дається @ ASCII - тільки (використовує ``замість того str(),

def f(x):
 i=2
 while(x in`i`)*all(i%j for j in range(2,i))-1:i+=1
 return i

Спробуйте в Інтернеті!



@ ASCII тільки я не дуже використовував python 2 і в основному використовую python 3, тож це те, в чому я гольфую. Хоча здається, що більшість часу python 2 закінчується коротше ...
Ніл А.

Ви ввели друкарську помилку, у першій, яку ви маєтеreturn I
лише ASCII


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