ワイルドカードシーケンスに一致するすべての正方形[終了]


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]

どこ '?' お好みのキャラクターです。

正規表現に関しては、を想像し'?'てみてください'.'

問題は、10進数の文字列表現がこのワイルドカードシーケンスと一致するすべての平方数(要件は最大100万個)を見つけることです。「ワイルドカード文字」は、明らかに数字でない限り、任意のASCII文字を使用できます。

たとえば、4096一致4**6します4*9*が、4114どちらにも一致しません。

入力

入力は、正規表現に一致するシーケンスとして与えられ[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

仕様書

  • 特定の範囲の正方形のリストを見つけるためにビルトインを使用することはできません
  • 標準抜け穴が適用されます
  • 最大1 000 000(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 2017年

2
なぜ25有効な回答***が有効ではないの*2*ですか?
Neil

3
数値に先行ゼロがなかったので、長さのシーケンスのみが一致した場合、これはよりクリーンになると思います。
XNOR

@ニールそれは私自身の解決策の問題でしょう。xnorの提案に従います。
HyperNeutrino 2017年

入力は1桁の整数および特殊文字、などの配列にすることができます{4, "w", "w", 6}(またはより良いまだ、{4, w, w, 6}など)ではなく、文字の配列、{"4", "w", "w", "6"}
グレッグマーティン

回答:



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 2017年

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

オンラインでお試しください!

これは基本的に上記の回答の2番目の部分であり、数字とワイルドカードがある変数を含む入力としてのリストがあります。

ただし、ブラキログ(大文字)には変数名が26個しかないため、これを有効とは見なしません。


これはすべての入力で機能するようです。よくやった。ただし、1バイトの引数が必要なため、これは24バイトと見なします。しかし、これに対する採点がどのように機能するかはわかりません。
HyperNeutrino 2017年

1
@AlexL。引数は、出力変数の名前を伝えるためだけにあります(必要に応じて、別の大文字を使用できます)。これは、述語/関数に名前が付けられているが関数を呼び出すProlog /言語の回答に似ていますが、呼び出すときに使用するバイトを実際にはカウントしません。
致命的

はい。引数が必要なので(そうでない場合はが返されるtrue.)、24と評価する必要があるかどうかはわかりませんが、これを必要とする言語を以前に使用したことがありません。これをどのように採点するかを決定するための参照を見つけようとしますが、23と採点することは理にかなっているので、それはそのままにしておきます。
HyperNeutrino 2017年

1

Perl 6の30の 26バイト

-4バイトの@ b2gillsに感謝!

{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 2017年

ええと、これはどのように使用しますか?Perlについて何も知りません。
HyperNeutrino 2017年

@AlexL .:ありがとう、答えを更新しました(説明も追加しました)。ラムダです。直接呼び出す(例{ ... }("9*9***"):)か、後で使用するために変数/シンボルに割り当てることができます。Perl 6はPerlとは別の言語であるため、Perlインタープリターでは動作しないことに注意してください。
smls 2017年

私は使用sudo apt-get install rakudoはずPerl6のインタプリタを取得するために...私が入れたときperl6、私の端末にコマンドとして、それはPerl6のインタプリタであるように思わ何を開始しますが、私はそれを使用する方法がわかりません。私はそれがラムダであることを知っていますが、それを呼び出す方法がわかりません。
HyperNeutrino 2017年

@AlexL .:「オンラインで試す」リンクを追加しました。このリンクは、として実行できる完全なスクリプトとして表示されますperl6 foo.p6。次のようなシェルワンライナーでもテストできますperl6 -e 'say {grep /^<$_>$/,map * **2,^1e4}( "9.9..." )'
smls

1

Ruby、54バイト

文字列引数を取る関数。オンラインでお試しください。

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

i ** 2の代わりにi * iを使用してバイトを節約できます
GB

2番目#は行の残りをコメントにするため、これは機能していないようです。
HyperNeutrino 2017年

@AlexLああ、それは大丈夫です。repl.it/FJCV
Value Ink

Rubyのテスト方法がわかりませんでした。謝罪いたします。これはすべての入力で機能するようです。よくやった!
HyperNeutrino 2017年

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バイト

編集:ジョンファンミンの答えに触発された後、以下の私のソリューションを更新しました。ES6に準拠しました。

はワイルドカードの形式'1..4'で入力を受け取ります.

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。ルールが変わったようです。以前のルールは、ワイルドカード文字を選択できることを示唆していました。
ジョージリース2017年

サポートする必要があるのは1e6...まで
HyperNeutrino 2017年

さらに、ルールを元に戻しました。問題はルールで**はなく、オペレーターが存在しないためです。少なくとも私のシステムではそうではありません。
HyperNeutrino 2017年

@AlexL。申し訳ありませんが、私はあなたが入力を意味していると思いました**。はい、それは私がここにタイトルが更新されますES7は、現在サポートされているブラウザの一覧ですdeveloper.mozilla.org/en/docs/Web/JavaScript/Reference/...
ジョージReithの

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]}"

質問は、ワイルドカードがアスタリスクとして与えられることを指定します。質問の以前のリビジョンでは、独自のワイルドカード文字を選択できましたか?
smls 2017年

1
@smls:ルールセクションにはありませんが、質問は独自のワイルドカードを選択することを指定しています:ワイルドカードとして使用される文字は、必ずしもアスタリスクである必要はありません。明らかに数字ではありません。
Emigna 2017年

はい、混乱しました。後で、ワイルドカード文字はアスタリスクにする必要があることを明確に述べています。正規表現での定義が先導していると思います。解決策を修正します。
ダニエル2017年

1
ええと、@ Emignaが引用している文は、独自のワイルドカード文字を選択できることを明確に示していますね。
smls '13年

明確にするために、ワイルドカード文字は何でもかまいません。説明を書き直すときに、誤ってルールをめちゃくちゃにしました。
HyperNeutrino 2017年

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 reand を使用するとre.findall、3バイトを節約できます。from...import *この場合、による最適化は実際には最適化しません。
HyperNeutrino 2017年

入力が提供されると、有効な回答1....が提供されますが、これは正しくありません。プログラムを修正してください。1 4 916 25
HyperNeutrino 2017年

「\ n」に参加してケースを修正してください。
Carra

これはに対しては機能しません1......。戻りますが[]、与えるはず[1000000]です。これは、range(0, 1001)ではなくを使用して0バイトのコストで修正できますrange(0, 1000)
HyperNeutrino 2017年

良い点、私は説明からすべてのテストケースをチェックしました:)
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 2017年

@AlexL。kdb +のkモードで動作します
C. Quilley

うーん。別のインタープリターでテストしてみます。
HyperNeutrino 2017年

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.

DC出力は、必要なパターンに一致する正方形のみを出力するgrepにパイプされます。

これは、実際のLinuxまたはOS Xシステムで実行すると機能します(ただし、TIOでは機能しません。おそらく、dcプログラムが永遠に再帰しようとしているため、TIOが再帰のためにスタック領域を使い果たしているか、または終わらないパイプの問題)。


私はこれをLinux Mint 17.3 Rosaで実行していますが、終了しません。問題は、終わりのないdcコマンドにあると思います。
HyperNeutrino 2017年

問題を引き起こしているのは、実際にはバッファリングだと思います。私はそのバージョンのLinuxを持っていませんが、grepをgrep --line-bufferedに置き換えてみてください(各行がgrepさ​​れたときに印刷されるようにするため)。[もちろん、バイト数が追加されます。]
Mitchell Spector

grep引数を追加しましたが、違いはありません。入れてみた--line-bufferedどちらかの側にをましたが^$1$、どちらの方法でも機能しません。
HyperNeutrino 2017年

@AlexL。試していただきありがとうございます。違いがカーネルにあるのか、実行しているbashのバージョンにあるのかわかりません。次のように、headを使用してgrepの入力を強制的に終了することにより、TIOで機能するようになりました:dc <<< '0 [2 ^ pv1 + lax] dsax' | head -1 sed s/./0/g<<<$1| grep ^ $ 1 $これは、テストする数を制限するパターン(4文字のパターンは最大9999までなどをチェックします)。TIOリンクは次のとおりです。とおり。tio.run nexus …
Mitchell Spector

修正ありがとうございます。現在の解決策は実際には機能しないと思います(ただし、bashについての知識はあまりありません)grep。ただし、現時点では最短のソリューションではないため、スコアリングのために33バイトに維持します。すべての入力で機能するようですので、よくできました!
HyperNeutrino 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.