よくリンクされた挑戦


40

私が退屈しているときに時々する活動は、一致するペアでいくつかの文字を書くことです。次に、これらのキャラクターをつなぐために線を描画します(決して上にならないように重ねます)。たとえば、と書くと、次のように線を引きます。abcbac

最初のリンク

または私は書くかもしれませんabbcac

セカンドリンク

これらの線を描いたら、チャンクの周りに閉じたループを描いて、描いた線がループと交差しないようにします。たとえば、最初のループでは描画できるのはループ全体だけですが、2番目のループでは s(またはその他すべて)の周りにループを描画できますb

描かれたループ

しばらくこれをいじると、一部の文字列が描画され、閉じたループにすべての文字が含まれるか、文字が含まれないことがわかります(最初の例のように)。このような文字列をリンクされた文字列と呼びます。

一部の文字列は複数の方法で描画できることに注意してください。たとえば、は次の両方の方法で描画できます(3つ目の方法は含まれていません)。bbbb

方法1 または 方法2

これらの方法のいずれかを描画して、行を交差させずに文字の一部を含む閉じたループを作成できる場合、文字列はうまくリンクされていません。(したがって、はうまくリンクされていません)bbbb

仕事

あなたの仕事は、うまくリンクされた文字列を識別するプログラムを書くことです。入力はすべての文字が偶数回出現する文字列で構成され、出力は2つの異なる一貫した値のいずれかである必要があります。

また、あなたのプログラムがうまくリンクされた文字列でなければなりません意味

  • プログラムでは、すべての文字が偶数回表示されます。

  • 渡されたときに、真理値を出力する必要があります。

プログラムは、印刷可能なASCIIまたは独自のプログラムからの文字で構成される任意の文字列に対して正しい出力を生成できる必要があります。各文字が偶数回表示されます。

回答は、バイト単位の長さとしてスコア付けされ、バイト数が少ないほどスコアが高くなります。

ヒント

文字列は、各文字がその部分文字列内で偶数回出現するように、連続した空でない厳密な部分文字列が存在する場合、適切にリンクされません。

テストケース

abcbac -> True
abbcac -> False
bbbb -> False
abacbc -> True
abcbabcb -> True
abcbca -> False

1
テストケース:abcbca -> False
Ørjanヨハンセン

あなたのヒントには余分なものがあると思いますthere
ジョナサンフレッチ

2
明確にするために、文字列がすべての文字の合計偶数を持っているかどうかは、それが適切にリンクされた文字列であるかどうかとは無関係です。この要件は、プログラムのソースコードにのみ適用されます。これはもちろん、セマンティクスの問題にすぎません。プログラムは、文字の総数が奇数の入力文字列に対して未定義の動作を許可されているためです(少なくとも1つの提出されたプログラムはこれを利用します)。
デッドコード

入力にはどのような種類の文字を使用できますか?
xnor

@xnorチャレンジに追加しました。うまくいけば、それで解決できます。
ウィートウィザード

回答:


19

正規表現(ECMAScriptの2018または.NET)、140の 126 118 100 98 82バイト

^(?!(^.*)(.+)(.*$)(?<!^\2|^\1(?=(|(<?(|(?!\8).)*(\8|\3$){1}){2})*$).*(.)+\3$)!?=*)

これは、98バイトバージョンよりもはるかに低速です。これは^\1、先読みの左側にあり、その後に評価されるためです。速度を取り戻す簡単なスイッチャーについては、以下を参照してください。しかし、これにより、以下の2つのTIOは以前よりも小さなテストケースセットを完了することに制限され、.NETのTIOは独自の正規表現をチェックするには遅すぎます。

オンラインでお試しください!(ECMAScript 2018)
オンラインでお試しください!(。ネット)

18バイト(118→100)をドロップするために、ネイルの正規表現からネガティブルックビハインド内に先読みを配置する必要がない(80バイトの無制限の正規表現を生成する)本当にすてきな最適化を盗みました。ありがとう、ニール!

それは、69バイトの無制限の正規表現につながったjayteaのアイデアのおかげで、信じられないほどの16バイト(98→82)を落としたときに時代遅れになりました!それははるかに遅いですが、それはゴルフです!

(|(正規表現を適切にリンクするためのノーオペレーションは、.NETの下で非常にゆっくりと評価するという結果になることに注意してください。幅がゼロのオプションの一致は不一致として扱われるため、ECMAScriptではこの効果はありません。

ECMAScriptはアサーションの量指定子を禁止しているため、要件を満たすことが難しくなります。しかし、この時点ではゴルフが非常に充実しているため、特定の制限を解除してもゴルフの可能性が広がるとは思いません。

制限(101 69バイト)を渡すために必要な余分な文字なし:

^(?!(.*)(.+)(.*$)(?<!^\2|^\1(?=((((?!\8).)*(\8|\3$)){2})*$).*(.)+\3))

遅いですが、この単純な編集(わずか2バイト追加)により、失われた速度などすべてが回復します。

^(?!(.*)(.+)(.*$)(?<!^\2|(?=\1((((?!\8).)*(\8|\3$)){2})*$)^\1.*(.)+\3))

^
(?!
    (.*)               # cycle through all starting points of substrings;
                       # \1 = part to exclude from the start
    (.+)               # cycle through all ending points of non-empty substrings;
                       # \2 = the substring
    (.*$)              # \3 = part to exclude from the end
    (?<!               # Assert that every character in the substring appears a total
                       # even number of times.
        ^\2            # Assert that our substring is not the whole string. We don't
                       # need a $ anchor because we were already at the end before
                       # entering this lookbehind.
    |                  # Note that the following steps are evaluated right to left,
                       # so please read them from bottom to top.
        ^\1            # Do not look further left than the start of our substring.
        (?=
            # Assert that the number of times the character \8 appears in our
            # substring is odd.
            (
                (
                    ((?!\8).)*
                    (\8|\3$) # This is the best part. Until the very last iteration
                             # of the loop outside the {2} loop, this alternation
                             # can only match \8, and once it reaches the end of the
                             # substring, it can match \3$ only once. This guarantees
                             # that it will match \8 an odd number of times, in matched
                             # pairs until finding one more at the end of the substring,
                             # which is paired with the \3$ instead of another \8.
                ){2}
            )*$
        )
        .*(.)+         # \8 = cycle through all characters in this substring
        # Assert (within this context) that at least one character appears an odd
        # number of times within our substring. (Outside this negative lookbehind,
        # that is equivalent to asserting that no character appears an odd number
        # of times in our substring.)
        \3             # Skip to our substring (do not look further right than its end)
    )
)

可変長の後読みに変換する前に、分子先読み(103 69バイト)を使用して作成しました。

^(?!.*(?*(.+)(.*$))(?!^\1$|(?*(.)+.*\2$)((((?!\3).)*(\3|\2$)){2})*$))

^
(?!
    .*(?*(.+)(.*$))       # cycle through all non-empty substrings;
                          # \1 = the current substring;
                          # \2 = the part to exclude from the end
    (?!                   # Assert that no character in the substring appears a
                          # total even number of times.
        ^\1$              # Assert that our substring is not the whole string
                          # (i.e. it's a strict substring)
    |
        (?*(.)+.*\2$)    # \3 = Cycle through all characters that appear in this
                          # substring.
        # Assert (within this context) that this character appears an odd number
        # of times within our substring.
        (
            (
                ((?!\3).)*
                (\3|\2$)
            ){2}
        )*$
    )
)

また、正規表現自体がリンクされているようにするために、上記の正規表現のバリエーションを使用しています。

(?*(.+)(.*$))(?!^\1$|(?*(.)+.*\2$)((((?!\3).)*(\3|\2$)){2})*$)\1

とともに使用する場合regex -xml,rs -o、これはすべての文字(存在する場合)の偶数を含む入力の厳密な部分文字列を識別します。確かに、これを行うために非正規表現プログラムを作成できたかもしれませんが、その中でどこが楽しいでしょうか?


8
それはまだgolfedされていますWTF
ASCIIのみの

@ASCIIのみで、まだゴルフ中です...
Quintec

11

ゼリー、20バイト

ĠẈḂẸẆṖÇ€Ạ
ĠẈḂẸ
ẆṖÇ€Ạ

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

最初の行は無視されます。すべての文字が偶数回出現するという条件を満たすためだけにあります。

次の行は、最初にĠ値によってインデックスをループします。次に、結果リストの各サブリストの長さ()を取得すると、各文字が表示される回数を取得します。これらのいずれかが非偶数であるかどうかを確認するために、各カウントの最後のit を取得し、真実(ゼロ以外)の値があるかどうかを尋ねます。

したがって、このヘルパーリンクは、部分文字列丸で囲むことができないかどうかを返します。

メインリンクでは、入力のすべての部分文字列()を取得し、最後の部分文字列を削除して(文字列全体を丸で囲むことができるかどうかを確認しないように)、各部分文字列でヘルパーリンク(Ç)を実行します。その結果、ll個の部分文字列を丸で囲むことができないかどうかが決まります。


それで、ええ、これも私の解決策になりますが、残念ながら、それは退屈です... :(
Erik the Outgolfer

8

J、34バイト

2:@':.,|~*'>1(#.,)*/@(1>2|#/.~)\.\

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

FrownyFrogのおかげで-8バイト

元の

J、42バイト

(*#'.,012&|@~#')=1#.[:,([:*/0=2&|@#/.~)\.\

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

説明

(*#'.,012&|@~#') = 1 #. [: , ([: */ 0 = 2&|@#/.~)\.\

(*#'.,012&|@~#')                                       NB. this evaluates to 1
                                                       NB. while supplying extra
                                                       NB. chars we need.  hence...
                 =                                     NB. does 1 equal...
                   1 #.                                NB. the sum of...
                        [: ,                           NB. the flatten of...
                             (                  )\.\   NB. the verb in parens applied
                                                       NB. to every suffix of every
                                                       NB. prefix, ie, all contiguous 
                                                       NB. substrings
                             ([: */ 0 = 2&|@#/.~)      NB. def of verb in paren:
                                             /.~       NB. when we group by each
                                                       NB. distinct char...
                              [: */                    NB. is it the case that
                                                       NB. every group...
                                           @#          NB. has a length...
                                    0 = 2&|            NB. divisible by 2...

1
@Deadcode他のすべての部分文字列と同様に文字列全体に対して反対のテストを行うことになりますので、ほとんどのソリューションでは省略できます。を使用したテストでabcは、Perlエントリのみが「失敗」しません。(ただし、他の問題もあります。)
ØrjanJohansen

1
@ØrjanJohansenあなたは誤解しました。文字数が奇数の文字列(リンクが適切な文字列ではなく、プログラムのソースコードを不適格とする)はリンクが良好であり、このプログラムはリンクが良好な文字列の一部に対してfalseyを返します。質問はこの未定義の動作を明示的に許可しているため、プログラムは有効です。ジョナ、あなたのプログラムがこれを行うのは本当に面白いと思うし、このように機能する方法を見つけたことを賞賛します。私は説明が大好きです。この種のプログラミングは完全に私とは無関係なので、コメントとコードが理解できません。
デッドコード

1:@':.,02|~*'=1(#.,)*/@(0=2|#/.~)\.\
FrownyFrog

1
2:@':.,|~*'>1(#.,)*/@(1>2|#/.~)\.\有効なようです
FrownyFrog

6

Python 3.8(プレリリース)、66バイト

lambda l,b={id}:len({str(b:=b^{c})for(c)in l})<len(l)#,<^fmnost{}#

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

割り当て式の時代が到来しました。PEP 572のPython 3.8に含まれ、ゴルフは同じになることはありません。Early Developer Preview 3.8.0a1はこちらからインストールできます

割り当て式を使用:=すると、その値を評価しながらインラインで変数に割り当てることができます。たとえば、(a:=2, a+1)を与え(2, 3)ます。これはもちろん、再利用のために変数を保存するために使用できますが、ここではさらに一歩進んで、理解のアキュムレータとして使用します。

たとえば、次のコードは累積合計を計算します [1, 3, 6]

t=0
l=[1,2,3]
print([t:=t+x for x in l])

リスト内包を通過するたびに、累積合計tが増加しx、新しい値が内包によって生成されたリストに格納されることに注意してください。

同様に、b:=b^{c}文字のセットを更新して、character bが含まれるかどうかを切り替えcて、の新しい値に評価しますb。したがって、コードは[b:=b^{c}for c in l]で文字cを反復処理しl、各空でないプレフィックスで奇数回出現した文字のセットを蓄積します。

このリストは、代わりにセットの内包表記にし、その長さがの長さよりも小さいかどうかを確認することにより、重複がないかチェックされますs。その場合、繰り返しとsは、それらの時間の間に見られる部分で、すべての文字が偶数個の数字に遭遇し、文字列がリンクされていないことを意味します。Pythonでは、セットのセットをハッシュ化できないため、内部セットは代わりに文字列に変換されます。

セットbはオプションの引数として初期化され、関数スコープで正常に変更されます。これにより関数が再利用できなくなるのではないかと心配していましたが、実行するたびにリセットされるようです。

ソースの制限のため、ペアになっていない文字は最後のコメントに詰め込まれます。余分な括弧を無料でキャンセルするのfor(c)in lではなく、書くことfor c in l。任意のセットとして開始できるため、無害なid初期セットに入れbますが、{}Pythonが空の辞書を作成するため、空のセットを書き込むことはできません。文字idはペアリングが必要な文字の1つなので、関数をidそこに配置できます。

コードは否定されたブール値を出力するため、コードFalse自体が正しく渡されることに注意してください。



5

Python 2、74バイト

bmn0=f=lambda s,P={0},d=[]:s<" "if(P in d)else+f(s[f<s:],P^{s[0^0]},[P]+d)

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

文字列を反復処理し、Pこれまでに奇数回表示された文字セットを追跡します。リストにdはのすべての過去の値が格納されPます。現在のPがにあるd場合、これは、その時間以降に表示された文字で、各文字が偶数回出現したことを意味します。その場合、入力全体を確認したかどうかを確認します。完了している場合は、文字列全体が期待どおりにペアリングされているため受け入れ、それ以外の場合は拒否します。

次に、ソースの制限について。ペアリングが必要なキャラクターは、下線が引かれたさまざまな無害な場所に詰め込まれています。

bmn0=f=lambda s,P={0},d=[]:s<" "if(P in d)else+f(s[f<s:],P^{s[0^0]},[P]+d)
_____              _              _      _    _    ___        ___    

f<s評価0オフペアリングしながら、f関数名もあることを利用して、fそれが定義されていていること(関数が呼び出された時点で。)0^0を吸収^シンボル。

0中にはP={0}残念なことです:Pythonで{}私たちが望むように空のdictではなく、空のセットに評価され、ここでは任意の非文字要素に置くことができ、それは無害になります。しかし、私は入れる余地がなく、a 0を入れて複製しましたがbmn0、コストは2バイトです。関数が定義されるときに初期引数が評価されるため、自分で定義する変数をここに入れることはできません。


4

Perl 6、76バイト

*.comb[^*X+(^*).map(^*)].grep({$_&[&]($_)}).none.Bag{*}.none%2#*^+XBob2rec%#

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

真偽値にブール化できるNone JunctionのNone Junctionを返すWhatever lambda。?ただし、返される結果をブール化するを削除しないことをお勧めします。削除しないと、出力がかなり大きくなります。

このソリューションでは、原因いくつかの関与の機能は、例えば、リンク解除されることに、必要とされるよりも少し複雑です..all>>%%などのソース制限がなければ、これは43バイトのようになります。

*.comb[^*X.. ^*].grep(?*).one.Bag{*}.all%%2

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

説明:

*.comb                     # Split the string to a list of characters
      [^*X+(^*).map(^*)]   # Get all substrings, alongside some garbage
                        .grep({$_&[&]($_)})        # Filter out the garbage (empty lists, lists with Nil values)
                                           .none                 # Are none of
                                                .Bag{*}          # The count of characters in each substring
                                                       .none%2   # All not divisible by 2

                                               #*^+XBob2rec%#    And garbage to even out character counts

3

Perlの5 -p94、 86、 78のバイト

m-.+(?{$Q|=@q&grp,$\|=$&eq$_^!grep+/^/&(@m=$g=~/\Q$_/g),($g=$&)=~/./g})(?!)-}{

適切にリンクされている場合は0、そうでない場合は1。

78バイト

86バイト

94バイト

使い方

  • -p}{出力にトリックを終了$\終わり
  • m-.+(?{.. })(?!)-、空ではないすべての部分文字列に対してコードを実行します(.+最初に文字列全体に一致し、強制的に失敗したために(?{.. })バックトラック間でコードを実行した後(?!)
  • $Q|=@q&grp, ソース制限のためのゴミ
  • $\|=整数ビット単位または代入、1がほぼ1の場合、$\1(true)になります。デフォルトでは空(false)です
  • $&eq$_sbustringが文字列全体である場合は、^「奇数文字の発生なし」でビット単位でxorされます
  • ($g=$&)=~/./g一致した部分文字列をコピーし$g(次の正規表現の一致後に上書きされるため)、部分文字列の文字の配列を返します。
  • /^/ 1と評価されるごみ
  • grep&(@m=$g=~/\Q$_/g),部分文字列の各文字に1 を指定$gすると、それ自体に一致する文字の配列が取得され、スカラーの配列はそのサイズに評価され、grep奇数の出現で文字をフィルタリング1&xすることはx%2==1

私はこの満足するソース制限はないと思う。私は、たとえば、オープン括弧の奇数を数える
msh210

@ msh210それがポイントではないですか?偶数がある場合、それがうまくリンクされていない
Quintec

うまくリンクされるための要件の一つ@Quintecがあるということですされている各文字の偶数。
Ørjanヨハンセン

私の最初の答えには要件がありましたが、ゴルフを試みた後、それを失いました。更新されましたが、ゴルフはできます。
ナウエルフワイユ

1
ここでのすべてのソースはソースの制限を満たします。また、リンクが適切であれば、コードは0を返し、各文字の数は偶数です
Nahuel Fouilleul

3

網膜150 96バイト

^(?!(.*)(.+)(.*)$(?<!^\2|^\1(?:(^?(?:(?!\6).)*\6){2})*(|(?!\6).)*(?!.+\6.*\3$)(.){1,}\3)(?!,<)?)

オンラインでお試しください!リンクには、それ自体を含むテストケースが含まれます。編集:@Deadcodeの助けを借りて、元の正規表現をかなり掘り下げた後、ソースレイアウトを維持するために、余分な負担を少し減らして元に戻しました。説明:

^(?!(.*)(.+)(.*)$

\3次の制約に一致するサブストリングが存在しないことをアサートします。

(?<!^\2|

部分文字列が元の文字列全体ではないことを表明します。

^\1(?:(^?(?:(?!\6).)*\6){2})*(|(?!\6).)*(?!.+\6.*\3$)(.){1,}\3)(?!,<)?)

次の\6ようなキャラクターがないことを表明します。

  • 文字自体(排他的)と部分文字列の終わりの間に現れません
  • 部分文字列の先頭とそれ自体の間で偶数回出現します(排他的)

ソースレイアウト制約をパスするためには、私は交換し(((((?:(^?(?:(((して(|(。まだソース制約が1つ残っていて))、文字が!()1<{}残っているので、aを変更し+{1,}、無駄なもの(?!,<)?を挿入して残りを消費します。


2
これは、制限されたソース要件を満たしていないようです。
Ørjanヨハンセン

@ØrjanJohansen最後に、有効なソリューションを思い付きました。しかし、そこにはたくさんのジャンクがあるので、もっと短いものが利用できるかもしれません...
ニール

3

C#の(ビジュアルC#インタラクティブコンパイラ)208の 206 200 198バイト

x=>!x.GroupBy(c=>c).Any(g=>g.Count()%2>0)&!Enumerable.Repeat(x.Count,x.Count*x.Count).Where(
(l,i)=>i%l>0&!x.Skip(i/l).Take(i%l).GroupBy(c=>c).Any(g=>g.Count()%2>0)
).Any()/*>!oyAnC0EmeablR*WhiS/T*/

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

@KevinCruijssenに感謝-2バイト!

最終的に200未満になったので、今はゴルフをするのが終わったかもしれません:)前回の回答に基づいて物事をテストするために2番目のTIOを作成することになりました。

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

このタスクをトリッキーにしたもの:

  • 等号演算子==は許可されませんでした
  • インクリメント/割り当て演算子++は許可されませんでした
  • Linq All()関数は許可されませんでした

以下のコメントコード:

// anonymous function that takes an IList as input
x=>
  // the first condition makes sure the string even
  // counts of each character
  !x.GroupBy(c=>c).Any(g=>g.Count()%2>0)&
  // the second condition generates all proper substrings of x
  // and tests for any that contain even character counts
  // the string length `l` is repeated `l*l` times
  !Enumerable.Repeat(x.Count,x.Count*x.Count)
    .Where((l,i)=>
      // check that the substring length is greater than 0
      i%l>0&
      // use skip/take to generate a substring
      // and check for a character count thats odd
      // negate the result meaning we have found
      // a substring that invalidates the input
      !x.Skip(i/l).Take(i%l)
        .GroupBy(c=>c).Any(g=>g.Count()%2>0)
    )
    // if any invalid substrings are found
    // then the result in invalid
    // the comment string at the end is needed
    // to make the program well-linked
    .Any()/*>!oyAnC0EmeablR*WhiS/T*/

末尾のコメントの2つのスペースを削除できます。
ケビンクルーッセン

@KevinCruijssen-良いもの:)私はすでにスペースを追加したことを忘れていました。私は別のものをソースに投げ込まなければなりませんでした。
ダナ


2

Brachylog、16バイト

sᶠb∋p~j&sᶠb∋p~j&

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

プリントfalse.truthyインスタンスのとtrue.falsyインスタンスの。TIOバージョンは、それ自体を処理するには遅すぎますが、一意の文字が2回繰り返された文字列であるため、明確にリンクされています。

説明

    Input is a string: "abcacbaa"
sᶠ  Find all substrings: ["abcacbaa","abcacba","abcacb",..,"a"]
b   Behead (now the proper substrings remain): ["abcacba","abcacb",..,"a"]
∋   Take one of them: "abcacb"
p   Permute it: "abcabc"
~j  It is some string repeated twice: "abc"
&   Get the input again: "abcacbaa"
    Then repeat the above.
    If the constraints can be satisfied, the result is true, otherwise false.

1

05AB1E22 20 バイト

Œε¢Pà}KŒIKεSIS¢ÈP}àÈ

1文字列が適切にリンクされている0場合、および文字列が適切にリンクされていない場合に出力します。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

基本プログラムはŒsKεsS¢ÈP}à11バイト)であり、0リンクが適切である場合とリンクされ1ていない場合に出力されます。末尾È(is_even)は、出力を反転するセミノーオペレーションです。したがって1、リンクが良好なストリングとリンクが正しく0ないストリングの場合です。他の部分は、チャレンジルールに準拠するためのノーオペレーションです。

Œε¢Pà}K         # No-ops: substrings, map, count, product, maximum, close map, remove
                # Due to the last remove, we're back at the (implicit) input again
Œ               # Take the substrings of the input
 IK             # Remove the input itself from that list of substrings
   ε            # Map each substring to:
    S           #  No-op: transform the substring into a list of characters
     IS         #  Get the input-string as a list of characters
       ¢        #  Count the occurrence of each character in the current substring
        È       #  Check which counts are even (1 if truthy; 0 if falsey)
         P      #  Take the product of that
              # After the map: check if any are truthy by taking the maximum
            È   # Semi no-op: check if this maximum is even (0 becomes 1; 1 becomes 0)
                # (and output the result implicitly)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.