コンテキストで文字列を連結する


13

コンテキスト付きの文字列

この課題のために、コンテキストを含む文字列は、左コンテキストデータ部分、および右コンテキストと呼ばれるトリプルの文字列です。長い文字列の部分文字列を表します。|セパレータとして垂直パイプを使用するため、コンテキストのある文字列の例はcod|e-go|lfで、左のコンテキストはcod、データはe-go、右のコンテキストはlfです。この例は、の部分文字列e-goを表しcode-golfます。

ここで、2つの文字列をコンテキストに連結するには、とを使用してaa|bcc|dee、次のように進めますcc|de|eee。図のように文字列を揃えます

a a|b c c|d e e
      c c|d e|e e e

データ部分が隣接するようにします。連結のデータ部分は、この場合、データ部分の連結ですbccde。左のコンテキストは、最初のデータ部分の左側にこの部分を拡張する部分です(この場合)aa。同様に、正しいコンテキストはeeeですので、連結はcontextの文字列aa|bccde|eeeです。第二の例では、考えるa|bb|cdと、aabb|cd|2番目の単語は空の右コンテキストを有する場合、。配置図は

  a|b b|c d
a a b b|c d|

ここで、2番目の単語の左側のコンテキストは、最初の単語のコンテキストよりもさらに広がっています。連結はaa|bbcd|です。

しかし、ちょっと待ってください。アライメント図の文字が一致しない場合、連結は存在しません。例としての図aa|bb|cc及びc|c|cIS

a a|b b|c c
      c|c|c

どこbc4列目には同意できないので、それらを連結することができません。

タスク

あなたの仕事は|、上記のように部分で区切られたコンテキストを持つ2つの文字列を取り込み、存在する場合は連結を、存在しない場合は他の何かを出力するプログラムを作成することです。「その他」は、コンテキストを含む有効な文字列でなく、すべての場合で同じである限り、出力なしを含む任意の値にできます。ただし、エラーをスローすることはできません。STDINからSTDOUTへのプログラムまたは関数を指定でき、匿名関数も受け入れられます。最小のバイトカウントが優先され、標準の抜け穴は許可されません。

テストケース

aa|bcc|dee cc|de|eee -> aa|bccde|eee
a|bb|cd    aabb|cd|  -> aa|bbcd|
a|b|cccd   aab|cc|c  -> aa|bcc|cd
a|b|c      b||cd     -> a|b|cd
aa|bb|cc   c|c|c     -> None
aaa|b|c    abb|cd|d  -> None
|bb|cd     abb|c|ed  -> None
a|b|c      a||cd     -> None

回答:


4

ハスケル、184 182 201 199 155

s&t|(a,'|':b)<-f t,(x,'|':y)<-f$r s,x#b,a#y=r(y!r a)++b!r x|0<1=""
r=reverse
a!b=a++drop(length a-1)b
(#)a=and.zipWith(==)(r a).filter h
f=span h
h=(/='|')

実行例:

"|a|"&"|b|" -- returns "|ab|"
"|a|x"&"|b|" -- returns ""

一致しない場合は、空の文字列が返されます。そうでない場合、結果が返されます。

部分的な説明:

# は、2つの文字列を取得し、一致するかどうかを返す関数です。

! 2つの文字列を取得し、2番目の文字列(ある場合)から余分な文字を連結した最初の文字列を返します。

main関数&span (/='|')、入力を2つの部分に分割するために使用し、、コンテキストが一致するかどうかを確認a|b|ca, b|c!2回使用して出力を組み立てます。

編集:魔術後期のリゴルフはかなり効果があるようです。


うーん、エラーをスローすることは、特に関数の場合、許容される出力方法ではないのではないかと心配しています。|1<2=""の定義に追加&することで解決します。仕様でこれを明示的に指定しなかったのが残念です。編集します。
Zgarb 14

@Zgarb実際には、これはそれを修正しません。'|'文字列が一致しない場合、記号が多すぎる文字列を返しますか?
誇りに思ってhaskeller 14

もちろん、一致しないすべての入力に対して同じ文字列である限り。
ズガルブ14

3

Python(242バイト)

import itertools as i
s='|'
j=''.join
r=reversed
m=lambda a,b:j(j(*set(p+q))for p,q in i.izip_longest(a,b,fillvalue=''))
def c(A,B):
 u,v,w,x,y,z=(A+s+B).split(s)
 try:return j(r(m(r(u+v),r(x))))[:-len(v)]+s+v+y+s+m(w,y+z)[len(y):]
 except:0

説明

ラムダ関数mは、共通のプレフィックスを共有している限り、2つの文字列のうち長い方を返します。それは空の文字列を連結することによってこれを行い''、結果回し、欠落している値の代わりに(形態をとることができaaaba、またはb一致/不一致/不等長の場合)の各位置における一意の文字のセットに。joinは単一の引数を想定しているため、複数の要素を持つセットをアンパックすると、が発生しTypeErrorます。

メイン関数

  • 用途はm結合し、左文脈及びデータ部を有する第一ワード左文脈(左上反転文字列に右から)第二のを
  • データ部分を連結し、
  • また、最初の単語の正しいコンテキストを、2番目の単語データ部分と正しいコンテキストとm結合するために使用します

2つの元の単語のデータ部分は、新しいコンテキストの右側と左側からトリミングされます。

ミスアライメントによりmaが発生することがわかっているため、TypeErrorこれらの場合、例外をキャッチして暗黙的に戻りNoneます。

テスト中

TESTCASES = [
    ('aa|bcc|dee', 'cc|de|eee', 'aa|bccde|eee'),
    ('a|bb|cd', 'aabb|cd|', 'aa|bbcd|'),
    ('a|b|cccd', 'aab|cc|c', 'aa|bcc|cd'),
    ('a|b|c', 'b||cd', 'a|b|cd'),
    ('aa|bb|cc', 'c|c|c', None),
    ('aaa|b|c', 'abb|cd|d', None),
    ('|bb|cd', 'abb|c|ed', None),
    ('a|b|c', 'a||cd', None),
]

for A, B, R in TESTCASES:
    print '{:<10} {:<9} -> {}'.format(A, B, c(A, B))

出力

aa|bcc|dee cc|de|eee -> aa|bccde|eee
a|bb|cd    aabb|cd|  -> aa|bbcd|  
a|b|cccd   aab|cc|c  -> aa|bcc|cd 
a|b|c      b||cd     -> a|b|cd    
aa|bb|cc   c|c|c     -> None      
aaa|b|c    abb|cd|d  -> None      
|bb|cd     abb|c|ed  -> None      
a|b|c      a||cd     -> None  
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.