扭曲的最小素数(A068103)


33

给定一个数字n,手头的任务将找到最小的素数,该最小素数以数字的AT LEAST 开头。这是我在OEIS(A068103)上找到的序列。 n2

下面给出了序列中的前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位整数,则可以对此进行解释。
Magic Octopus Urn'1

Answers:


12

Brachylog12 11字节

:2rj:Acb#p=

在线尝试!

令人惊讶的是,这直接转化为Brachylog。这是一个函数,而不是完整的程序(尽管将解释器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,没有明显的原因(Brachylog出于某种原因似乎对零过敏;我怀疑c是负责任的)。也就是说,它很容易修复,所以我现在就修复它。

b:Ac不起作用,因为对于输入,0您会得到2b:Ac2b给定,0并且不能使用c前导零。这样做的原因是为了避免在通常情况下始终可以加零并得到相同结果的无限循环。
Fatalize

另外,您可以通过写:2rj而不是将其缩短一个字节,例如,2:?j
Fatalize

我忘记了r; 那只是一个简单的改进。我了解发生了什么c(向后运行时,您不需要无限多个结果);但是,可能的改进是仅当输入未绑定时才禁止简并输入,而当输入已绑定到简并值时允许输入。

这绝对是可行的,我将其添加到Github跟踪器中。尽管连接的实现已经差不多100行长,这对于Prolog谓词来说是很多的。
致命

15

Java(OpenJDK 8)164110字节

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

感谢@FryAmTheEggman一堆字节!

在线尝试!


2
您能解释一下主要检查正则表达式如何工作吗?
J. Antonio Perez

我不知道。这不是我的,也不知道最初的创作者是谁。我刚才就是一个长度为n的字符串,如果n不是素数则匹配。
Pavel

您知道原始来源是什么吗?您从哪里学到的?您是否测试过代码?
J. Antonio Perez

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=11 开始递增直到满足条件。2s 的字符串必须是字符串开头的子字符串,即index方法需要返回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

Mathematica,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}... 将一个加到最后一个数字上,然后手动实现带一个到下一个的数字,只要使用规则{a__,b_,10,c___}->{a,b+1,0,c}... 等于10位数...然后,如果我们走得太远,以至最后一个前导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,但该函数找到了正确答案的方法。)

该算法非常快:例如,在我的笔记本电脑上,计算从1000 2s 开始的第一个素数是不到3秒22...220521


2

Pyth,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

Pyke,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个),它在我的机器上的半秒内完成。


很好的解决方案!
奥利弗(Oliver)

这在输入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

Python 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

我决定在相当大的范围内提高速度,而不是字节大小。:)我使用确定性的Miller-Rabin素数检验,对于这组证人,该检验最多可保证3317044064679887385965961981。较大的素数总是会顺利通过测试,但一些复合材料也可以传递,虽然几率非常低。但是,我还使用椭圆曲线分解程序pyecm测试了i> 22的输出数字,它们似乎是质数。


1
首先,提交内容的几率必须为1。其次,这是代码高尔夫,因此您实际上必须考虑字节大小。除此之外,不错
破坏的柠檬

1
@DestructibleWatermelon谢谢!关于字节大小的公平点。我想我可以内联p()调用... OTOH,很难编写一个较小的程序,在一秒钟之内可以给出i> 20的正确输出(通过调用内置程序不会“欺骗”)素数检查器)。:)
下午17年

许多程序无法处理33位数字(n:= 30)。鉴于OP的黄金标准只能上升到18位,并且他/她没有设置其他限制,因此可以合理地假设n:= 30足以满足IMO的要求。
user3819867

@ PM2Ring它不需要在“一秒钟之内”。使代码尽可能短,并完全忽略速度。这就是[代码高尔夫]的精神。打高尔夫球后,我将把我的下注改为上票。
mbomb007 '01

实际上,如果它确实产生了到极限的正确输出,则答案确实以概率为1起作用。
破坏的柠檬

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 '17

@ SamCle88可能性不大,这在技术上是错误的。isProbablePrime不适合用于主要验证,并且在其他挑战中已被拒绝。
Magic Octopus Urn'1
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.