与通配符序列匹配的所有正方形


9

这是受2016 ARML竞赛团队问题#6的启发。

这是挑战:

您将获得一个“通配符序列”,它是一个数字序列和另一个字符。字符串通过以下伪代码匹配此通配符序列:

w = wildcard
s = string
# s matches w iff
for all 0 >= i > wildcard.length, w[i] == '?' or s[i] == w[i]

哪里?是您选择的角色。

就正则表达式而言,只需想象'?''.'

挑战在于找到所有十进制字符串表示形式都与该通配符序列匹配的平方数(要求最大为100万)。很明显,“通配符”可以是您选择的任何ASCII字符,只要它不是数字即可。

例如,4096匹配4**6和,4*9*4114都不匹配。

输入项

输入将作为与regex匹配的序列给出[0-9?]+。它可以是ASCII字符的字符串,字符数组或字节数组。

输出量

输出将是一个任意分隔的数字列表/集合/数组,它们是完美的平方并与通配符序列匹配。

有效输入的示例:

1234567*90
1234567?90
1234567u90
['1', '2', '3', '4', '5', '6', '7', '*', '9', '0']
[49, 50, 51, 52, 53, 54, 55, 42, 57, 48]
[1, 2, 3, 4, 5, 6, 7, '*', 9, 0]

有效输出示例:

[1, 4, 9]
1 4 9
1, 4, 9
1-4-9

等等

技术指标

  • 您可能无法使用内置函数来查找特定范围内的正方形列表
  • 适用标准漏洞
  • 您必须能够处理1000000(100万)
  • 如果提供输入1******,则打印正确[1000000]。打印也正确[1000000, 1002001, 1004004, 1006009, 1008016, 1010025, ...]
  • 通配符序列永远不会以通配符开头;也就是说,它们将始终匹配相同长度的字符串。

测试用例

4**6  ->  [4096, 4356]
1**1  ->  [1521, 1681]
1**  ->  [100, 121, 144, 169, 196]
9****9  ->  [908209, 915849, 927369, 935089, 946729, 954529, 966289, 974169, 986049, 994009]
9*9***  ->  [919681, 929296]
1**0*  ->  [10000, 10201, 10404, 10609, 12100, 14400, 16900, 19600]
9***4  ->  [91204, 94864, 97344]

获奖

最短(有效)(有效)提交截止日期为2月14日,并以最早提交的获胜者打破平局。


1
我认为使这一点更清晰的一个好开始是指定?答案者要选择的内容。
FryAmTheEggman

2
为什么是25有效答案,***而不是*2*
尼尔

3
我认为,如果数字从不包含前导零,那么这样做会更干净,因此仅匹配其长度的序列。
xnor

@Neil这将是我自己的解决方案的问题。我接受xnor的建议。
HyperNeutrino

输入是否可以是一个由一位整数组成的数组和一个特殊字符(如{4, "w", "w", 6}(或更好{4, w, w, 6})),而不是一个字符数组(如{"4", "w", "w", "6"}?)?
格雷格·马丁

Answers:


0

05AB1E,22字节

这里可能还有很大的改进空间。
任何非数字都可以用作通配符。

3°LnvyS¹)ø€Æ0QPyg¹gQ&—

在线尝试!

进一步打高尔夫球后再作解释。


这似乎适用于所有输入。做得好。
HyperNeutrino

1

Mathematica,44个字节

Print@@@IntegerDigits[Range@1*^3^2]~Cases~#&

输入是一个数字列表,其中带有_(不带引号)通配符。例如{4, _, _, 6}

说明

Range@1*^3

产生清单 {1, 2, 3, ... , 1000}

... ^2

平方它。(从1到1,000,000的所有方块的列表)

IntegerDigits[ ... ]

将每个正方形拆分为数字列表。

... ~Cases~#

查找与输入指定的模式匹配的那些。

Print@@@ ...

打印它们。


这似乎适用于所有测试用例。做得好。
HyperNeutrino

1

Brachylog,23个字节

@e:{@$|,}a#0:{c.~^#I,}f

在线尝试!

说明

@e                        Split into a list of characters
  :{@$|,}a                Replace each digit char by the corresponding digit, and each things
                            that are ot digits into variables
          #0              All elements of the resulting list must be digits
            :{       }f   Output is the result of finding all...
              c.            ...concatenations of those digits which...
               .~^#I,       ...result in a number which is the square of an integer #I

不同的输入格式,13字节

根据您认为有效的输入内容,可以执行以下操作:

#0:{c.~^#I,}f

在线尝试!

这基本上是上面答案的第二部分,带有输入的列表,其中包含通配符所在的数字和变量。

但我认为这无效,因为Brachylog中只有26个变量名(大写字母),所以如果您有26个以上的通配符,那么这将不起作用。


这似乎适用于所有输入。做得好。但是,我认为这是24个字节,因为需要一个1字节的参数。我不确定如何为此打分。
HyperNeutrino

1
@AlexL。该参数仅用于指示输出变量的名称(如果需要,可以使用另一个大写字母)。这类似于Prolog /语言中带有谓词/函数的函数的答案,但您实际上在调用它时并没有计算使用的字节数。
致命

好的。我不确定是否应该将其记为24,因为该参数是必需的(否则它只会返回true.),但是我之前从未使用过需要此参数的语言。我会尝试找到一些参考资料来确定我应该如何给它打分,但是将其打分为23是有意义的,所以我会一直保持这一水平。
HyperNeutrino

1

Perl 6的30 26个字节

感谢@ b2gills -4个字节!

{grep /^<$_>$/,map * **2,^1e4}

{grep /^<$_>$/,(^1e4)»²}

将点用作通配符,以便将输入用作正则表达式:

{                            }   # a lambda
                         ^1e4    # range from 0 to 9999
               map * **2,        # square each value
 grep /      /,                  # filter numbers that match this regex:
        <$_>                     #   lambda argument eval'ed as sub-regex
       ^    $                    #   anchor to beginning and end

在线尝试

接受星号作为通配符的变体(如任务描述的先前版本所建议)将为42个字节:

{grep /^<{.trans("*"=>".")}>$/,(^1e4)»²}

我已经重述了规则,您可以选择任何通配符。我将其计为38个字节。
HyperNeutrino

嗯,你怎么用这个?我对Perl一无所知。
HyperNeutrino

@AlexL .:谢谢,我已经更新了答案(并添加了解释)。这是一个lambda;您可以直接调用它(例如{ ... }("9*9***")),或将其分配给变量/符号以供以后使用。请注意,Perl 6是与Perl不同的语言,因此它不适用于Perl解释器。
smls

我曾经sudo apt-get install rakudo有一个假定的Perl6解释器...当我将perl6命令作为命令输入终端时,它启动了似乎是Perl6解释器的窗口,但我不知道如何使用它。我知道这是一个lambda,但我不知道如何称呼它。
HyperNeutrino

@AlexL .:我添加了一个“在线尝试”链接,该链接将其显示为可以作为运行的完整脚本perl6 foo.p6。您还可以在shell oneliner中对其进行测试,例如perl6 -e 'say {grep /^<$_>$/,map * **2,^1e4}( "9.9..." )'
smls

1

Ruby,54个字节

带有字符串参数的函数。在线尝试。

->s{(0..1e3).map{|i|"#{i**2}"[/^#{s.tr ?*,?.}$/]}-[p]}

您可以通过使用节省字节I * I,而不是我的** 2
GB

这似乎不起作用,因为第二个步骤#是将该行的其余部分添加为注释。
HyperNeutrino

@AlexL哦,很好。repl.it/FJCV
价值油墨

哦,好吧,我只是不知道如何测试Ruby。我很抱歉。这似乎适用于所有输入。做得好!
HyperNeutrino

0

批次,109个字节

@for /l %%i in (0,1,999)do @set/aj=%%i*%%i&call copy nul %%j%%.%%j%%$>nul
@for %%s in (%1.%1$)do @echo %%~ns

使用?作为通配符。通过创建1000个文件来工作。文件名是平方号,文件扩展名是带$后缀的平方号。这是因为Batch的模式匹配将尾随?s作为可选计数,因此1?将与1和都匹配16。将$因此迫使比赛要准确。但是,我们不想输出$,因此我们只输出不带扩展名的文件名。


0

JavaScript(ES6),68 66字节

编辑:在受到JungHwan Min的答案的启发后,更新了以下我的解决方案。现在它符合ES6。

以通配符'1..4'where 的格式.输入。

而不是迭代到1e6和平方根,而是迭代到1e3和平方。

p=>[...Array(1e3)].map((_,n)=>''+n*n).filter(n=>n.match(`^${p}$`))

JavaScript(ES7),71 69字节

p=>[...Array(1e6).keys()].filter(n=>n**.5%1?0:(''+n).match(`^${p}$`))

创建一个从0到1e6的数字数组,然后按方形且与模式匹配的数字对其进行过滤。

它非常慢,因为它总是迭代到1e6。


我认为这没有用**,因为它给了我一个机会"SyntaxError: expected expression, got '*'"
HyperNeutrino

@AlexL。规则似乎已经改变。先前的规则建议我可以选择通配符。
乔治·瑞斯

您最多只需要支持1e6...
HyperNeutrino

另外,我把规则改回来了。问题不在于规则,这是因为**运算符不存在,至少在我的系统中不存在。
HyperNeutrino

@AlexL。抱歉,我认为您的意思是输入**。是的,它是ES7我会更新标题下面是目前支持的浏览器列表developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
乔治·瑞思

0

Perl,42 45 38字节

编辑:由亚历克斯澄清,我们可以使用句点作为通配符,以消除y //操作。

perl -pe 's|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

编辑:使用星号作为通配符并期望STDIN上的通配符序列的解决方案

perl -pe 'y/*/./;s|.*|@{[grep/^$&$/,map$_*$_,1..1e3]}|'

无疑,这有很多改进的余地,这很简单。通配符表达式应作为命令行参数,并带有句点通配符(还有什么?)。

say"@{[grep/^$ARGV[0]$/,map$_*$_,1..1e3]}"

问题指定通配符以星号形式给出。这个问题的较早版本是否允许选择自己的通配符?
smss

1
@smls:尽管不在规则部分,但该问题仍指定选择您自己的通配符:用作通配符的字符不必一定是星号,它可以是您选择的任何ASCII字符,只要它显然不是数字。
Emigna

是的,我对此感到困惑。稍后,它明确表示通配符必须为星号。我想正则表达式的定义是领先的。我将修改解决方案。
丹尼尔(Daniel)

1
嗯,@ Emigna引用的句子很清楚,我们可以选择自己的通配符,不是吗?
smss

需要说明的是,通配符可以是您想要的任何字符。重新解释时,我不小心弄乱了规则。
HyperNeutrino

0

Python 3-98 97字节

import re;print(re.findall(r"\b"+input()+r"\b",("\n".join([str(x*x) for x in range(1,1001)]))))

需要输入“ 4..6”。


您可以使用import re和节省3个字节re.findall。与优化from...import *实际上并没有在这种情况下,对其进行优化。
HyperNeutrino

提供的input 1....会给出1 4 916 25作为有效答案,这是不正确的。请更正您的程序。
HyperNeutrino

通过加入“ \ n”来修复此问题。
卡拉

这不适用于1......。它返回[],但应该给[1000000]。使用range(0, 1001)而不是可以将其固定为0字节range(0, 1000)
HyperNeutrino

好点,我只是检查了描述中的所有测试用例:)
Carra

0

k-28个字符

{s(&:)($:s:s*s:!1001)like x}

用途?作为通配符。该like函数?用作通配符,此函数列出前1001个正方形(包括1M),并将它们全部转换为字符串,然后检查它们与模式匹配的位置。

    {s(&:)($:s:s*s:!1001)like x} "1??"
100 121 144 169 196

我收到此错误:type error {s(&:)($:s:s*s:!1001)like x} "1" at execution instance 2 of ":"。您能否提供指向正在运行的测试套件的链接,或者查看是否存在问题?
HyperNeutrino

@AlexL。它为我在KDB +的K色模式
C. Quilley

嗯 我将尝试使用其他解释器进行测试。
HyperNeutrino

0

bash + Unix实用程序,33个字节

dc<<<'0[2^pv1+lax]dsax'|grep ^$1$

这使用'。' 作为通配符。

dc程序无限循环打印平方数:

0     Push 0 on the stack.

[     Start a macro (called a).

2^    Square the number at the top of the stack.

p     Print the number at the top of the stack, followed by a newline.

v     Replace the number at the top of the stack (a square number) with its square root.

1+    Increment the number at the top of the stack.

lax   Run the macro again (looping).

]     End of the macro.

dsax  Store the macro in register a and run it.

直流输出通过管道传输到grep,后者仅打印与所需模式匹配的正方形。

当我在实际的Linux或OS X系统上运行它时,此方法有效(但它在TIO上不起作用,可能是因为dc程序试图永久递归,并且我怀疑TIO的堆栈空间不足以进行递归和/或具有永无止境的管道有问题)。


我正在Linux Mint 17.3 Rosa上运行它,并且它并没有终止。我认为问题在于永无止境的dc命令。
HyperNeutrino

我怀疑实际上是导致问题的缓冲。我没有该版本的Linux,但是您可以尝试用grep --line-buffered替换grep(以使每行在grepped时被打印)。[当然,这会增加一些字节。]
Mitchell Spector

我添加了grep参数,但没有任何区别。我尝试将放在的--line-buffered任何一侧^$1$,但无论哪种方式都行不通。
HyperNeutrino

@AlexL.Thank you for trying. I don't know if the difference is in the kernel or in the bash version I'm running. I got it to work in TIO by forcing an end to grep's input using head, as follows: dc<<<'0[2^pv1+lax]dsax'|head -1sed s/./0/g<<<$1|grep ^$1$ This uses the length of the pattern to limit the numbers being tested (4-character patterns check only up to 9999, etc.). Here's a TIO link: tio.run/nexus/…
Mitchell Spector

谢谢您的修复。我认为当前的解决方案不会真正起作用(尽管我对bash的了解不多),因为看来它需要在将其输入之前计算所有值grep。但是,由于它目前不是最短的解决方案,因此我将其保持在33字节以进行评分。它似乎适用于所有输入,很好!
HyperNeutrino
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.