Найменший прайм із поворотом (A068103)


33

Завдання, що знаходиться під рукою, - це задати число n, знайти найменший простір, який починається з НАЙКРАЩОГО n числа 2на початку числа. Це послідовність, яку я знайшов на OEIS ( A068103 ).

Перші 17 чисел у послідовності наведені нижче, якщо ви хочете більше, мені доведеться насправді реалізувати послідовність, що я не проти робити.

0  = 2
1  = 2
2  = 223
3  = 2221
4  = 22229
5  = 2222203
6  = 22222223                # Notice how 6 and 7 are the same! 
7  = 22222223                # It must be **AT LEAST** 6, but no more than necessary.
8  = 222222227
9  = 22222222223             # Notice how 9 and 10 are the same!
10 = 22222222223             # It must be **AT LEAST** 9, but no more than necessary.
11 = 2222222222243
12 = 22222222222201
13 = 22222222222229
14 = 222222222222227
15 = 222222222222222043
16 = 222222222222222221

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


5
Чи є нижня межа того, наскільки високу суму ми повинні підтримувати?
ETHproductions

1
Чи існує обмеження часу?
Бред Гілберт b2gills

@ETHProductions вибачте, пішов досить швидко після написання цього. Якщо ви маєте обмежити свої дані, обмеження має бути підкріплено логічним аргументом того, чому мова не підтримує числа, що перевищують більше x. Наприклад, якщо ваша мова підтримує лише 32-бітні цілі числа, ви можете пояснити це.
Чарівний восьминіг Урна

Відповіді:


12

Брахілог , 12 11 байт

:2rj:Acb#p=

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

Це перекладається на Брахілог несподівано безпосередньо. Це функція, а не повна програма (хоча надання інтерпретатора Zяк аргументу командного рядка призводить до того, що він додає відповідну обгортку, щоб перетворити функцію в програму; саме це я зробив, щоб зв’язок TIO працював). Також досить прикро, що jздається -1-індексованим і потребує виправлення, щоб дозволити це.

Ви можете зробити розумний аргумент, що =це не потрібно, але я вважаю, що з огляду на те, як сформульована проблема, це так; без, функція описує набір усіх простих чисел, що починаються з заданої кількості 2s, і без явного твердження, що програма повинна щось робити з цим описом (у цьому випадку, генеруючи перше значення), ймовірно, це не відповідати вимогам.

Пояснення

:2rjbAcb#p=
:2rj         2 repeated a number of times equal to the input plus one
    :Ac      with something appended to it
       b     minus the first element
        #p   is prime;
          =  figure out what the resulting values are and return them

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

Одна тонкощі (зазначена в коментарях): :Acbі b:Acє математично рівнозначними (як один видаляє з початку, а інший додає до кінця, при цьому область між ними ніколи не перетинається); У мене раніше було b:Ac, що є більш природним, але воно порушується на вході 0 (що я здогадуюсь, тому що cвідмовляється об'єднати порожній список ні в що; багато Brachylog вбудовані, як правило, чомусь перебиваються на порожні списки). :Acbгарантує, що cніколи не доведеться бачити порожній список, це означає, що і вхід 0 може працювати і зараз.


@muddyfish: Це так. Однак це не спрацювало 0без видимих ​​причин (Брахілог чомусь виявляється алергічним до нуля; я підозрюю, що cце відповідає). Це сказало, що це досить просто виправити, тому я зараз це виправлю.

b:Acне працює, тому що для введення, який 0ви отримуєте 2b:Ac: 2bдає, 0і ви не можете використовувати cз початковим нулем. Причиною цього є уникнення нескінченних циклів у загальному випадку, коли ви завжди могли додати нуль і мати однакові результати.
Фаталізувати

Крім того, ви можете скоротити це на один байт, написавши :2rjзамість,2:?j
Fatalize

Я забув r; це просто очевидне поліпшення. Я розумію, що відбувається з цим c(ви не хочете нескінченно багато результатів, коли біжите назад); однак, ймовірне вдосконалення полягає у забороні вироджених входів лише у тому випадку, якщо вони не пов'язані, дозволяючи їм, коли вхід вже пов'язаний з виродженим значенням.

Це, безумовно, можливо, і я додам його в трекер Github. Хоча реалізація конкатената вже майже 100 рядків, що багато для предиката Prolog.
Фаталізувати

15

Java (OpenJDK 8) , 164 110 байт

a->{int i=0;for(;!(i+"").matches("2{"+a+"}.*")|new String(new char[i]).matches(".?|(..+)\\1+");i++);return i;}

Дякуємо @FryAmTheEggman за купу байтів!

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


2
Не могли б ви пояснити, як працює в основному перевірка регулярного виразу?
Дж. Антоніо Перес

Я поняття не маю. Це не моє, і я не знаю, хто такий оригінальний творець. Я щойно займає рядок довжиною n і відповідає, якщо n не є простим.
Павло

Чи знаєте ви, що таке першоджерело? Де ви дізналися про це? Ви перевірили свій код?
Дж. Антоніо Перес

3
@Pavel Цей регулярний вираз перевірки первинності робить цю відповідь дивовижною, навіть якщо ви цього не зробили. Ви повинні додати це до теми "Поради щодо гольфу на Java".
Чарівний восьминога Урна

3
Я не можу перевірити код зараз, але я впевнений, що регулярний вираз працює так: new String(new char[i]))робить одинарний рядок довжиною, рівний кількості. Тоді регулярний вирівнювання відповідає збірним числам, перевіряючи, чи повторення набору цифр відповідає цілому рядку (в основному пробний поділ). Якщо я маю рацію, це означає, що ви повинні мати можливість гольфувати другу частину, щоб не мати ?, я повідомляю вас напевно, коли я дістанусь до комп'ютера.
FryAmTheEggman

5

Pyth, 12 байт

f&!x`T*Q\2P_

У псевдокоді:

f                key_of_first_truthy_value( lambda T:
  !                  not (
   x`T*Q\2               repr(T).index(input()*'2')
                     )
 &                   and
          P_T        is_prime(T)
                 )

Петлі lambdaпочинаючи з T=1, збільшуючи на 1, поки умова не буде виконана. Рядок 2s повинен бути підрядком з початку рядка, тобто метод індексу повинен повернутись 0. Якщо підрядка не знайдена, він повертається, -1що зручно також є правдою, тому не існує жодного виняткового випадку.

Ви можете спробувати в Інтернеті тут , але сервер дозволяє лише до введення 4.


4

Perl, 50 байт

49 байт коду + -pпрапор.

++$\=~/^2{$_}/&&(1x$\)!~/^1?$|^(11+)\1+$/||redo}{

Поставити вхід без остаточного нового рядка. Наприклад:

echo -n 4 | perl -pE '++$\=~/^2{$_}/&&(1x$\)!~/^1?$|^(11+)\1+$/||redo}{'

Для запуску чисел, більших за 4, потрібен певний час, оскільки він перевіряє кожне число (є 2 тести: перший /^2{$_}/перевіряє, чи достатньо 2 на початку, а другий - (1x$\)!~/^1?$|^(11+)\1+$/на первинність (з дуже поганими показниками)).


3

Haskell, 73 байти

f n=[x|x<-[2..],all((>0).mod x)[3..x-1],take n(show x)==([1..n]>>"2")]!!0

Приклад використання: f 3-> 2221.

Груба сила. [1..n]>>"2"створює список n 2s, який порівнюється з першими nсимволами в рядковому поданні поточного простого.


3

Математика, 103 байти

ReplaceRepeated[0,i_/;!IntegerDigits@i~MatchQ~{2~Repeated~{#},___}||!PrimeQ@i:>i+1,MaxIterations->∞]&

Безіменна функція, яка приймає невід'ємний цілий аргумент #і повертає ціле число. Він буквально тестує всі додатні цілі числа по черзі, поки не знайде одне, що обидва починається з #2s і є простим. Страшенно повільно для входів вище 5.

попередній результат: Mathematica, 155 байт

Mathematica була б краща для гри в гольф, якби вона не була так сильно набрана; ми маємо чітко переходити вперед і назад між цілими / списками / рядками.

(d=FromDigits)[2&~Array~#~Join~{1}//.{j___,k_}/;!PrimeQ@d@{j,k}:>({j,k+1}//.{a__,b_,10,c___}->{a,b+1,0,c}/.{a:Repeated[2,#-1],3,b:0..}->{a,2,0,b})]/. 23->2&

Цей алгоритм працює на списках цифр , як не дивно, починаючи з {2,...,2,1}. Поки це не цифри простого числа, він додає одну до останньої цифри, використовуючи правило {j___,k_}/;!PrimeQ@d@{j,k}:>({j,k+1}..., а потім вручну реалізує перенесення "один-до-наступної" цифри до тих пір, як будь-який з цифри дорівнюють 10, використовуючи правило {a__,b_,10,c___}->{a,b+1,0,c}... і тоді, якщо ми зайшли так далеко, що останній з провідних 2s перетворився на a 3, починається з іншої цифри на кінці, використовуючи правило {a,b+1,0,c}/.{a:Repeated[2,#-1],3,b:0..}->{a,2,0,b}. В /. 23->2кінці просто фіксується особливий випадок, коли вхід є 1: більшість праймерів не можуть закінчитися 2, але 2можуть. (Кілька помилок сплюнув на входах 0і 1, але функція знаходить свій шлях до правильної відповіді.)

Цей алгоритм досить швидкий: наприклад, на моєму ноутбуці потрібно менше 3 секунд, щоб обчислити, що перший прайм починається з 1000 2с 22...220521.


2

Піт, 17 байт

f&q\2{<`T|Q1}TPTh

Здається, це не вирішується через n = 4Інтернет, але це теоретично.

Пояснення

               Th    Starting from (input)+1, 
f                    find the first T so that
      <              the first
          Q          (input) characters
         | 1         or 1 character, if (input) == 0
       `T            of T's string representation
     {               with duplicates removed
  q\2                equal "2", 
 &                   and
            }T       T is found in
              PT     the list of T's prime factors.

2

Perl 6 , 53 байти

{($/=2 x$^n-1)~first {+($/~$_) .is-prime&&/^2/},0..*}

Спробуй це

Розширено:

{
  ( $/ = 2 x $^n-1 )       # add n-1 '2's to the front (cache in 「$/」)
  ~
  first {
    +( $/ ~ $_ ) .is-prime # find the first that when combined with 「$/」 is prime
    &&
    /^2/                   # that starts with a 2 (the rest are in 「$/」)
  },
  0..*
}


2

Пайк, 14 байт

.fj`Q\2*.^j_P&

Спробуйте тут!

.fj            - first number (asj)
   `    .^     -   str(i).startswith(V)
    Q\2*       -    input*"2"
             & -  ^ & V
          j_P  -   is_prime(j)

12 байт після виправлення та нова функція

~p#`Q\2*.^)h

Спробуйте тут!

~p           - all the primes
  #       )h - get the first where...
   `    .^   - str(i).startswith(V)
    Q\2*     -  input*"2"

2

Шавлія, 69 68 байт

lambda n:(x for x in Primes()if '2'*len(`x`)=>'2'*n==`x`[:n]).next()

Використовує генератор, щоб знайти перший (отже, найменший) нескінченно багато термінів.


2

Japt, 20 байт

L²o@'2pU +Xs s1)nÃæj

Перевірте його онлайн! Він закінчується протягом двох секунд на моїй машині на всіх входах до 14, а після цього, природно, втрачає точність (JavaScript має лише цілу точність до 2 53 ).

Велике спасибі @obarakon за роботу над цим :-)

Пояснення

                       // Implicit: U = input integer, L = 100
L²o                    // Generate the range [0...100²).
   @             Ã     // Map each item X through the following function:
    '2pU               //   Take a string of U "2"s.
         +Xs s1)n      //   Append all but the first digit of X, and cast to a number.
                       // If U = 3, we now have the list [222, 222, ..., 2220, 2221, ..., 222999].
                  æ    // Take the first item that returns a truthy value when:
                   j   //   it is checked for primality.
                       // This returns the first prime in the forementioned list.
                       // Implicit: output result of last expression

В останній версії Japt це може бути 12 байт:

_n j}b!+'2pU   // Implicit: U = input integer
_   }b         // Return the first non-negative bijective base-10 integer that returns
               // a truthy value when run through this function, but first,
      !+       //   prepend to each integer
        '2pU   //   a string of U '2's.
               // Now back to the filter function:
 n j           //   Cast to a number and check for primality.
               // Implicit: output result of last expression

Перевірте його онлайн! Він закінчується протягом половини секунди на моїй машині на всіх входах до 14.


Чудове рішення!
Олівер

Це не вдається на вході 5, оскільки ви ніколи не тестуєте 2222203, тільки 222223і незабаром після цього 2222210. Він також не працює на будь-якому вході, який потребує трьох чи більше додаткових цифр після рядка 2s, наприклад, вхід 15.
Грег Мартін

@GregMartin Darn, ти маєш рацію. Фіксується вартістю 5 байт.
ETHproductions

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

@GregMartin Це працює для всіх тестових випадків до 14, і JS наштовхується на цілі проблеми з точністю у випадку 15. Я не думаю, що алгоритм повинен бути теоретично правильним за останні 2 ^ 53, але, можливо, я помиляюся ...
ETHproductions

2

PHP, 76 байт

for($h=str_pad(2,$i=$argv[1],2);$i>1;)for($i=$p=$h.++$n;$p%--$i;);echo$p?:2;

приймає дані з аргументу командного рядка. Бігайте з -r.

зламатися

for($h=str_pad(2,$i=$argv[1],2) # init $h to required head
    ;$i>1;                      # start loop if $p>2; continue while $p is not prime
)
    for($i=$p=$h.++$n               # 1. $p = next number starting with $h
                                    #    (first iteration: $p is even and >2 => no prime)
    ;$p%--$i;);                     # 2. loop until $i<$p and $p%$i==0 ($i=1 for primes)
echo$p?:2;                      # print result; `2` if $p is unset (= loop not started)

1

Bash (+ coreutils), 53 байти

Працює до 2 ^ 63-1 (9223372036854775807) , знадобиться чималий час, щоб закінчити для N> 8.

Гольф

seq $[2**63-1]|factor|grep -Pom1 "^2{$1}.*(?=: \S*$)"

Тест

>seq 0 7|xargs -L1 ./twist

2
2
223
2221
22229
2222203
22222223
22222223

1

Пітон 3, 406 байт

w=2,3,5,7,11,13,17,19,23,29,31,37,41
def p(n):
 for q in w:
  if n%q<1:return n==q
  if q*q>n:return 1
 m=n-1;s,d=-1,m
 while d%2==0:s,d=s+1,d//2
 for a in w:
  x=pow(a,d,n)
  if x in(1,m):continue
  for _ in range(s):
   x=x*x%n
   if x==1:return 0
   if x==m:break
  else:return 0
 return 1
def f(i):
 if i<2:return 2
 k=1
 while k:
  k*=10;l=int('2'*i)*k
  for n in range(l+1,l+k,2):
   if p(n):return n

код тесту

for i in range(31):
    print('{:2} = {}'.format(i, f(i)))

тестовий вихід

 0 = 2
 1 = 2
 2 = 223
 3 = 2221
 4 = 22229
 5 = 2222203
 6 = 22222223
 7 = 22222223
 8 = 222222227
 9 = 22222222223
10 = 22222222223
11 = 2222222222243
12 = 22222222222201
13 = 22222222222229
14 = 222222222222227
15 = 222222222222222043
16 = 222222222222222221
17 = 222222222222222221
18 = 22222222222222222253
19 = 222222222222222222277
20 = 2222222222222222222239
21 = 22222222222222222222201
22 = 222222222222222222222283
23 = 2222222222222222222222237
24 = 22222222222222222222222219
25 = 222222222222222222222222239
26 = 2222222222222222222222222209
27 = 2222222222222222222222222227
28 = 222222222222222222222222222269
29 = 2222222222222222222222222222201
30 = 222222222222222222222222222222053

Я вирішив піти на швидкість в досить великому діапазоні, а не на байт. :) Я використовую детермінований тест на прихильність Міллера-Рабіна, який гарантовано до 3317044064679887385961981 з цим набором свідків. Більші праймери завжди успішно пройдуть тест, але деякі композити також можуть пройти, хоча ймовірність вкрай низька. Однак я також протестував вихідні числа для i> 22, використовуючи pyecm програму факторизації Elliptic Curve, і вони здаються простими.


1
По-перше: подання має мати ймовірність 1 шанс правильного виводу. по-друге, це кодовий гольф, тому вам потрібно насправді шукати байт. Окрім цього, приємно
Зруйнований лимон

1
@DestructibleWatermelon Дякую! Справедливий момент щодо розміру байтів. Я припускаю , що я міг , вставить p()виклик ... Ото, було б важко написати значно меншу програму , яка може дати правильний вихід для г> 20 протягом секунди (що не "обдурити», викликавши вбудовану перевірка первинності). :)
PM 2Ring

Багато програм не можуть обробити 33-значний номер (n: = 30). Зважаючи на те, що золотий стандарт ОП досягає лише 18 цифр і немає обмеження, встановленого ним / нею, розумно припустити, що n: = 30 є достатньо хорошим ІМО.
користувач3819867

@ PM2Ring Це не потрібно бути "за секунду". Зробіть код максимально коротким та ігноруйте швидкість взагалі. Це дух [коду-гольфу]. Я перейду на свій внесок на призовий, як тільки він буде в гольф.
mbomb007

насправді, якщо він дає правильний вихід до межі, то відповідь працює з імовірністю один.
Руйнуючий лимон

1

Python 3, 132 байти

def f(x):
 k=10;p=2*(k**x//9)
 while x>1:
  for n in range(p*k,p*k+k):
   if all(n%q for q in range(2,n)):return n
  k*=10
 return 2

Будь-яка надія на продуктивність була принесена в жертву для меншої кількості байтів.


-1

Java, 163 байти

BigInteger f(int a){for(int x=1;x>0;x+=2){BigInteger b=new BigInteger(new String(new char[a]).replace("\0","2")+x);if(b.isProbablePrime(99))return b;}return null;}

код тесту

    public static void main(String[] args) {
    for(int i = 2; i < 65; i++)
        System.out.println(i + " " + new Test20170105().f(i));
    }

вихід:

2 223
3 2221
4 22229
5 2222219
6 22222223
7 22222223
8 222222227
9 22222222223
10 22222222223
11 2222222222243
12 22222222222229
13 22222222222229
14 222222222222227
15 222222222222222143
16 222222222222222221
17 222222222222222221
18 22222222222222222253
19 222222222222222222277
20 2222222222222222222239
21 22222222222222222222261
22 222222222222222222222283
23 2222222222222222222222237
24 22222222222222222222222219
25 222222222222222222222222239
26 2222222222222222222222222213
27 2222222222222222222222222227
28 222222222222222222222222222269
29 22222222222222222222222222222133
30 222222222222222222222222222222113
31 222222222222222222222222222222257
32 2222222222222222222222222222222243
33 22222222222222222222222222222222261
34 222222222222222222222222222222222223
35 222222222222222222222222222222222223
36 22222222222222222222222222222222222273
37 222222222222222222222222222222222222241
38 2222222222222222222222222222222222222287
39 22222222222222222222222222222222222222271
40 2222222222222222222222222222222222222222357
41 22222222222222222222222222222222222222222339
42 222222222222222222222222222222222222222222109
43 222222222222222222222222222222222222222222281
44 2222222222222222222222222222222222222222222297
45 22222222222222222222222222222222222222222222273
46 222222222222222222222222222222222222222222222253
47 2222222222222222222222222222222222222222222222219
48 22222222222222222222222222222222222222222222222219
49 2222222222222222222222222222222222222222222222222113
50 2222222222222222222222222222222222222222222222222279
51 22222222222222222222222222222222222222222222222222289
52 2222222222222222222222222222222222222222222222222222449
53 22222222222222222222222222222222222222222222222222222169
54 222222222222222222222222222222222222222222222222222222251
55 222222222222222222222222222222222222222222222222222222251
56 2222222222222222222222222222222222222222222222222222222213
57 222222222222222222222222222222222222222222222222222222222449
58 2222222222222222222222222222222222222222222222222222222222137
59 22222222222222222222222222222222222222222222222222222222222373
60 222222222222222222222222222222222222222222222222222222222222563
61 2222222222222222222222222222222222222222222222222222222222222129
62 2222222222222222222222222222222222222222222222222222222222222227
63 2222222222222222222222222222222222222222222222222222222222222227
64 2222222222222222222222222222222222222222222222222222222222222222203

582.5858 мілісекунд

Пояснення: перетворює петлі на цілі числа та додає їх у вигляді рядків до кореневого рядка, який є заданим рядком "2", і перевіряє, чи є він простим чи ні.


3
isProbablePrimeмає випадкові помилкові позитиви . Це скасує відповідь, оскільки існують обставини, за яких вона повертає неправильне значення.

Ймовірність помилки менше 2 ^ -99 (див. Документацію ).
SamCle88

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