パターンを交互にする


8

問題

色付きのボールのシーケンス(赤Rと緑G)が与えられます。そのような可能なシーケンスの1つは次のとおりです。

RGGGRRGGRGRRRGGGRGRRRG

できるだけ少ない動きで、各ボールが隣のボールとは異なる色になるように(つまり、シーケンスが交互になるように)する必要があります。

RGRGRGRGRGRGRGRGRGRGRG

「R」と「G」の等しい番号を持つ順序付けられていないシーケンス(この場合は文字列)を、アイテムが交互に並ぶシーケンスに変換できるプログラムを作成する必要があります。単純なアルゴリズムの場合のセッションの例を以下に示します(<プログラム>への入力、出力です。入力または出力にキャレットを含める必要はありません)。

< RGGGRRGGRGRRRGGGRGRRRG
> RGGRGRGGRGRRRGGGRGRRRG
> RGRGGRGGRGRRRGGGRGRRRG
> RGRGRGGGRGRRRGGGRGRRRG
> RGRGRGGRGGRRRGGGRGRRRG
> RGRGRGGRGRGRRGGGRGRRRG
> RGRGRGGRGRGRGRGRGGRRRG
> RGRGRGGRGRGRGRGRGRGRRG
> RGRGRGGRGRGRGRGRGRGRGR
> RGRGRGRGGRGRGRGRGRGRGR
> RGRGRGRGRGGRGRGRGRGRGR
> RGRGRGRGRGRGGRGRGRGRGR
> RGRGRGRGRGRGRGGRGRGRGR
> RGRGRGRGRGRGRGRGGRGRGR
> RGRGRGRGRGRGRGRGRGGRGR
> RGRGRGRGRGRGRGRGRGRGGR
> RGRGRGRGRGRGRGRGRGRGRG (15 moves)

別の可能性は、例えば、位置5と7の入れ替えを示すために「5,7」を出力することです。

最初に赤または緑のいずれかを配置できますが、一貫している必要はありません。各シーケンスは、他のすべてのシーケンスと同じ長さになります。

各移動で2文字だけを入れ替えることができます(それらは隣接している必要はありません)。

受賞基準

プログラムは、ソートプロセスの各ステップを示す必要があります。以下のすべての文字列の合計移動が最も少ないプログラムが勝利します。同点の場合は、最短のコードが優先されます。

入力文字列

次の文字列を使用してプログラムをテストします。

GGGGGGGGGGRRRRRRRRRR
GGRRGGRRGGRRGGRRGGRR
RRGGGGRRRRGGGGRRRRGG
GRRGRGGGGRRRGGGGRRRR
GRGGGRRRRGGGRGRRGGRR
RGRGRGRGRGRGRGRGRGRG

最後のシーケンスはゼロムーブになります。


「各移動で交換できるのは2つのペアのみです」「各移動で交換できるのは2つの文字のみ」ではありませんか?
DavidC 2013年

@dude非常に良い、私はそれを修正します。
Thomas O

特定の文字がソートされたシーケンスを開始するという要件はありますか?
dmckee ---元モデレーターの子猫2013

@dmckee質問から-「最初に赤または緑を配置することができ、一貫している必要はありません。」
トーマスO

2
取り組むべき素晴らしい問題。人々に彼らのインプットとアウトプットのいくつかの例を投稿するよう依頼することをお勧めします。このようにして、選択した言語でプログラミングしない人は、それぞれの入力に対する出力の適合性について評価を行うことができます。
DavidC 2013年

回答:


5

Python、140 122 119 115

r=raw_input()
f=lambda x:[i for i in range(x,len(r),2)if x-(r[i]!=max('RG',key=r[::2].count))]
print zip(f(0),f(1))

1
技術的にはの割り当ては必要ありませんs。それはあなたにいくつかの文字を節約するでしょう。
小次郎2013年

どういたしまして。あなたが私が取り組んでいることを断った後、私は何賢いことをしなければなりませんでした。
小次郎2013年

3

APL 46

((2|y)/y←(i≠↑i)/n),[.1](~2|y)/y←(i=↑i)/n←⍳⍴i←⍞

指定されたテストケースを実行すると、次の結果が得られます。

GGGGGGGGGGRRRRRRRRRR
11 13 15 17 19
 2  4  6  8 10

GGRRGGRRGGRRGGRRGGRR
3 7 11 15 19
2 6 10 14 18

RRGGGGRRRRGGGGRRRRGG
3 5 11 13 19
2 8 10 16 18

GRRGRGGGGRRRGGGGRRRR
3 5 11 17 19
4 6  8 14 16

GRGGGRRRRGGGRGRRGGRR
7  9 13 15 19
4 10 12 14 18

RGRGRGRGRGRGRGRGRGRG

上記のソリューションでは、結果の行列の列に示されているスワップを使用して、インデックス原点1を使用しています。入力ベクトルiが実行時に入力されるのではなく、実行前に入力文字列で初期化される場合、2文字を保存できます。


3

GolfScript(47文字)

:S;4,{S,,{.S=1&3*\1&2*^1$=},\;}%2/{zip}%{,}$0=`

例(正解のチェックがはるかに簡単なテストケースを使用してください)。

< RRGGRGRGRGRGRGRGRGRG
> [[1 2]]

出力は、スワップするゼロインデックスのペアのリストです。


[[1 2]]が位置1と2の文字を交換することを意味する場合、結果は入力と同じように見えます。どうか明らかにしてください。
DavidC 2013年

4
@おい、どんな変人が1から数え始めるの?
Peter Taylor

3
(私の手を上げます)。
DavidC 2013年

2

Python、213文字

I=raw_input()
def M(S,T):
 S=list(S);m=[]
 while S!=list(T):z=zip(S,T);x=z.index(('R','G'));y=z.index(('G','R'));m+=[(x,y)];S[x],S[y]='GR'
 return m
N=len(I)/2
x=M(I,N*'RG')
y=M(I,N*'GR')
print[x,y][len(x)>len(y)]

Mに変換するSために必要な移動を見つけTます。これは、繰り返し見つけることによってこれを行いRそしてG位置から、それらを交換します。次に、RGRG...RGまたはに到達するための短い移動シーケンスを見つけますGRGR...GR

すべての入力に対して最適な動きのシーケンスを見つける必要があります。


2

Mathematica 238

コード

f[x_] := With[{g = "GRGRGRGRGRGRGRGRGRGR", c = Characters, p = Position},
y = c[x]; s = c[g]; {v = Equal @@@ ({s, y}\[Transpose]), 
w = Not /@ v}; {vv = Thread[{y, v}], ww = Thread[{y, w}]};
((Flatten /@ {p[#, {"R", False}], p[#, {"G", False}]}) &[If[Count[Equal @@@ 
({s, y}\[Transpose]), False] < 10, vv, ww]])\[Transpose]]

注意:Mathematica\[Transpose]では単一の文字であり、上付きの "t"である]

f@"GGGGGGGGGGRRRRRRRRRR"
f@"GGRRGGRRGGRRGGRRGGRR"
f@"RRGGGGRRRRGGGGRRRRGG"
f@"GRRGRGGGGRRRGGGGRRRR"
f@"GRGGGRRRRGGGRGRRGGRR"
f@"RGRGRGRGRGRGRGRGRGRG"
f@"GRGRGRGRGRGRGRGRGRGR"

{{12、1}、{14、3}、{16、5}、{18、7}、{20、9}}
{{4、1}、{8、5}、{12、9}、 {16、13}、{20、17}}
{{2、3}、{8、5}、{10、11}、{16、13}、{18、19}}
{{2、1}、 {10、7}、{12、9}、{18、13}、{20、15}}
{{2、1}、{6、3}、{8、5}、{16、11}、{ 20、17}}
{}
{}


2

Mathematica 134または124

Mathematicaでは「トランスポーズ[]」を数える方法に応じて、Mathematicaでは1文字だけです(ここでは表現なし)。わかりやすくするためにスペースを追加

G = 0; R = 1; 
x_~ d ~ y__:= Transpose[Position[Symbol /@ Characters@x - PadLeft[{}, 20, {y}], #, 1] &
                                                                                 /@ {1, -1}]
f = SortBy[{d[#, 0, 1], d[#, 1, 0]}, Length][[1]] &

サンプル:

f@"GGGGGGGGGGRRRRRRRRRR"
f@"GGRRGGRRGGRRGGRRGGRR"
f@"RRGGGGRRRRGGGGRRRRGG"
f@"GRRGRGGGGRRRGGGGRRRR"
f@"GRGGGRRRRGGGRGRRGGRR"
f@"RGRGRGRGRGRGRGRGRGRG"
f@"GRGRGRGRGRGRGRGRGRGR"

出力

{{{11}, {2}}, {{13}, {4}}, {{15},  {6}}, {{17},  {8}}, {{19}, {10}}}
{{{3},  {2}}, {{7},  {6}}, {{11}, {10}}, {{15}, {14}}, {{19}, {18}}}
{{{1},  {4}}, {{7},  {6}}, {{9},  {12}}, {{15}, {14}}, {{17}, {20}}}
{{{2},  {1}}, {{10}, {7}}, {{12},  {9}}, {{18}, {13}}, {{20}, {15}}}
{{{2},  {1}}, {{6},  {3}}, {{8},   {5}}, {{16}, {11}}, {{20}, {17}}}
{}
{}

非常に経済的なコーディング。純粋な関数の素敵な使い方。
DavidC 2013年

@dudeありがとう:) きっとPadLeft[{}, 20, {y}], #, 1]もう少し圧縮できると
思い

2

JavaScript-173文字

a=prompt(w=[[],[]]).split('');for(i=a.length,f=a[0];i--;)if(i%2<1&&a[i]!=f)w[0].push(i);else if(i%2>0&&a[i]==f)w[1].push(i);for(i=w[0].length;i--;)alert(w[0][i]+','+w[1][i])

大きな挑戦で、しばらくの間私を忙しくしていました。
ここで、コードはテストケースの結果です。

GGGGGGGGGGRRRRRRRRRR: [10, 1] [12, 3] [14, 5] [16, 7] [18, 9]
GGRRGGRRGGRRGGRRGGRR: [ 2, 1] [ 6, 5] [10, 9] [14,13] [18,17]
RRGGGGRRRRGGGGRRRRGG: [ 2, 1] [ 4, 7] [10, 9] [12,15] [18,17]
GRRGRGGGGRRRGGGGRRRR: [ 2, 3] [ 4, 5] [10, 7] [16,13] [18,15]
GRGGGRRRRGGGRGRRGGRR: [ 6, 3] [ 8, 9] [12,11] [14,13] [18,17]
RGRGRGRGRGRGRGRGRGRG:

1

PHP-34動き-193文字

$l=strlen($a=$_GET["a"]);$n=$a[0]=="R"?"G":"R";while($i<$l){if($a[++$i]!=$n){echo$o."
";$o=$a=substr($a,0,$i).$n.preg_replace("/".$n."/",$n=="R"?"G":"R",substr($a,$i+1),1);}$n=$n=="R"?"G":"R";}

まだこれを改善しようとするかもしれません...

red_green.php?a=GGGGGGGGGGRRRRRRRRRR

GRGGGGGGGGGRRRRRRRRR
GRGRGGGGGGGGRRRRRRRR
GRGRGRGGGGGGGRRRRRRR
GRGRGRGRGGGGGGRRRRRR
GRGRGRGRGRGGGGGRRRRR
GRGRGRGRGRGRGGGGRRRR
GRGRGRGRGRGRGRGGGRRR
GRGRGRGRGRGRGRGRGGRR
GRGRGRGRGRGRGRGRGRGR

$argv[0]代わりに使用すると、それぞれ2バイト節約できます。$argvCMD経由の入力によく使用されるため、より有効になります
RedClover
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.