数字の入れ替え[終了]


10

これは、多くの人が手動で解決した一般的なパズルです。これが、同じことを解決するアルゴリズムを書く時です。

同数のマッチ棒が、お互いの方向を向いた2つの異なる側面に並んでいます。それらの間に単一の空のスペースがあります。次の図のように言います(マッチ棒の総数が4の場合)。

ここに画像の説明を入力してください

各スティックは、前の方向に1ステップスライドするか(すぐ前のスペースが空いている場合)、またはスティックを前に1スティック飛び越えて、空いているスペースに着地することができます(そのスペースが空いている場合)。逆方向への移動はできません(スペースが空いていても)。リバースジャンプも許可されていません。1つのステップで許可される移動は1つだけです。

ここで、すべての左側のマッチスティックが右側に着地し、すべての右側のマッチスティックが左側に着地するために必要な最小ステップを見つけるアルゴリズムを記述する必要があります。

例:マッチスティックが2つある場合(両側に1つずつ)、ステップは次のようになります。

ここに画像の説明を入力してください

注:上の図では、左側のスティックが最初に移動されています。右側のスティックが最初に動くときに別の解決策が存在します。しかし、この問題では、1つのソリューションのみを与える必要があります。これは、左側のスティックが最初に動くことを前提としています。

次の図は、4つのマッチスティック(各サイドに2つ)を使用した動きを示しています。

ここに画像の説明を入力してください

注:上の図では、左側のスティックが最初に移動されています。右側のスティックが最初に動くときに別の解決策が存在します。しかし、この問題では、1つのソリューションのみを与える必要があります。これは、左側のスティックが最初に動くことを前提としています。

[仮定:入力は、02から14までの任意の偶数にすることができます(つまり、両側に1から7のマッチスティック)。この範囲外の入力の場合、検証を行う必要はなく、エラーメッセージを提供する必要もありません。注:出力では、各ステップは「|」で区切られています (パイプ)キャラクター。COBOLプログラマーは常にPIC 9(2)を入力サイズとして想定し、出力が最大長450文字で、右側にスペースが埋め込まれていると想定する場合もあります。]


入力例:

02  

出力例:

01To02|03To01|02To03|


入力例:

04  

出力例:

02To03|04To02|05To04|03To05|01To03|02To01|04To02|03To04|


入力例:

06  

出力例:

03To04|05To03|06To05|04To06|02To04|01To02|03To01|05To03|07To05|06To07|04To06|02To04|03To02|05To03|04To05|

画像を直接含めることができない場合、他の人がそれらを編集するためのリンクを提供できますか?
Peter Taylor

2
簡単な画像をいくつか作りました。うまくいけば、彼らは元の作者の意図に準拠しています。
プリモ2013

3
勝利の条件は?
Shmiddty、2013

回答:


3

APL 129

以下のコードは、画面入力を受け取り、指定された形式で画面に出力します。

n←n,n++\1↓z←(⌽z),((¯1*~2|n)×n⍴2),z←⌽∊(¯1*2|⍳n)ר1,((⍳(n←.5×⍎⍞)-1)⍴¨2),¨1⋄(∊(((¯2↑¨'0',¨⍕¨n),¨⊂'To'),¨(¯2↑¨'0',¨⍕¨n-z)),¨⊂'|')~' '

コードの3分の1は、出力のフォーマットに使用されます。ロジックは、コード内の⋄記号の出現によって完了します。

以下は、チェックとして08を入力した場合の結果です。

04To05|06To04|07To06|05To07|03To05|02To03|04To02|06To04|08To06|09To08|07To09|05To07|03To05|01To03|02To01|04To02|06To04|08To06|07To08|05To07|03To05|04To03|06To04|05To06|

1
私はいつもAPLが不正行為をしているように感じます>。<
Shmiddty '21

@Shmiddty APL、J、GolfScriptなどの純粋な記号ベースの言語は、より詳細な単語ベースの言語に対してコードゴルフに勝つ可能性が高いと思います;)
Graham

3

Javascriptを178 174 161

prompts for nthen alerts答え。(0パディングなし)

最新:

t=1+(m=prompt(s=i='')/2);for(z=Math.abs;i++<m*2;)for(j=m-z(m-i),s+=(t+=a=(m%2^z(m+.5-i)%2-.5)*-2+1)+'To'+(t-a)+'|';j--;)s+=(t+=a=i%2*4-2)+'To'+(t-a)+'|';alert(s)

2:

z=Math.abs;t=m=prompt(o=[])/2;t++;for(s=i='';i++<m*2;)for(j=m-z(m-i),o.push((z(m+.5-i)%2-.5)?-1:1);j--;)o.push(i%2?2:-2);o.map(function(a){s+=(t+=a)+'To'+(t-a)+'|'});alert(s)

1:

t=m=prompt(o=[])/2+1;for(s=i='';++i<m;)for(j=i,o.push(i%2?-1:1);j--;)o.push(i%2?2:-2);o.concat(o.slice().reverse().slice(m-1)).map(function(a){s+=(t+=a)+'To'+(t-a)+'|'});alert(s)

これは、パターンがミラーリングされるという概念を使用しています。

Key
R='Jump Right'
r='Shift Right'
L='Jump Left'
l='Shift Left'
m='Move'
j='Jump'

したがって、ここn=2で、動きのパターンは次のとおりです。

rLr
mjm

これは

+1 -2 +1

このパターンはこのように繰り返されます(n=8

rLlRRrLLLlRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjmjjmjm
+1 -2 -1 +2 +2 +1 -2 -2 -2 -1 +2 +2 +2 +2 -1 -2 -2 -2 +1 +2 +2 -1 -2 +1

ここでいくつかのパターンに気付くことができます:

  1. 動きは左と右で交互に
  2. 特定の方向の動きの数は1からn/2に増加し、これは3回繰り返され、その後1に減少します。
  3. 移動のタイプは、シフトとジャンプの間で交互になり、行内のシフトの数は一定で1、順次ジャンプの数は1から増加して1にn/2減少します。
  4. 動きの合計は常に0です(これが実際に関連しているかどうかはわかりません)。

n=14

rLlRRrLLLlRRRRrLLLLLlRRRRRRrLLLLLLLrRRRRRRlLLLLLrRRRRlLLLrRRlLr
mjmjjmjjjmjjjjmjjjjjmjjjjjjmjjjjjjjmjjjjjjmjjjjjmjjjjmjjjmjjmjm

出力例:

f(2)

1To2|3To1|2To3| 

f(8)

4To5|6To4|7To6|5To7|3To5|2To3|4To2|6To4|8To6|9To8|7To9|5To7|3To5|1To3|2To1|4To2|6To4|8To6|7To8|5To7|3To5|4To3|6To4|5To6|

f(40)

20To21|22To20|23To22|21To23|19To21|18To19|20To18|22To20|24To22|25To24|23To25|21To23|19To21|17To19|16To17|18To16|20To18|22To20|24To22|26To24|27To26|25To27|23To25|21To23|19To21|17To19|15To17|14To15|16To14|18To16|20To18|22To20|24To22|26To24|28To26|29To28|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|12To13|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|31To30|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|10To11|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|33To32|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|8To9|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|35To34|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|6To7|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|37To36|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|4To5|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|39To38|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|2To3|4To2|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|40To38|41To40|39To41|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|1To3|2To1|4To2|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|40To38|39To40|37To39|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|3To5|4To3|6To4|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|38To36|37To38|35To37|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|5To7|6To5|8To6|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|36To34|35To36|33To35|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|7To9|8To7|10To8|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|34To32|33To34|31To33|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|9To11|10To9|12To10|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|32To30|31To32|29To31|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|11To13|12To11|14To12|16To14|18To16|20To18|22To20|24To22|26To24|28To26|30To28|29To30|27To29|25To27|23To25|21To23|19To21|17To19|15To17|13To15|14To13|16To14|18To16|20To18|22To20|24To22|26To24|28To26|27To28|25To27|23To25|21To23|19To21|17To19|15To17|16To15|18To16|20To18|22To20|24To22|26To24|25To26|23To25|21To23|19To21|17To19|18To17|20To18|22To20|24To22|23To24|21To23|19To21|20To19|22To20|21To22|

メソッドを示すいくつかの擬似コードを次に示します。

var mid=cursor=N/2,delta
cursor++                 // the cursor is where the empty space is.
for(i=0; i++<N;){
  delta = (mid%2^abs(mid+.5-i)%2-.5)*-2+1;  // 1 or -1
  print((cursor+delta) + 'To' + cursor + '|')
  cursor+=delta
  for(j=mid-abs(mid-i);j--;)
  {
    delta = i%2*4-2  // 2 or -2
    print((cursor+delta) + 'To' + cursor + '|')
    cursor+=delta
  }
}

2
とを使用すると、パターンがより明確にl/L/r/Rなりm/jます。私は方向から移動した距離を分離するアイデアが好きです
ゴードンベイリー

2

C- 216 213

私の解決策は2つの事実に基づいています:

  1. 「to」フィールドは、前の移動の「from」フィールドです(移動元のスペースには常に空のスロットを作成し、常に空のスロットに移動するため)。

  2. 移動する距離と方向には非常に規則的なパターンがあります。最初の3つのテストケースについては、次のとおりです。

    1 -2 1

    1 -2 -1 2 2 -1 -2 1

    1 -2 -1 2 2 1 -2 -2 -2 1 2 2 -1 -2 1

それを念頭に置いて、私は基本的にそのパターンを作成して継続するプログラムを書いただけです。これを書くには本当に美しく、はるかにエレガントな再帰的な方法があるに違いないと私は確信していますが、まだわかりません:

#include <stdio.h>

int main(int argc, const char *argv[])
{
   int upper_bound = atoi(argv[1]) / 2;
   int len;
   int from;
   int to = upper_bound + 1;
   int direction = 1;
   int i;

   for(len = 1; len <= upper_bound; ++len){
      for(i = len-1; i >=0; --i){
         from = to - direction*(1 + (i!=0));
         printf("%02dTo%02d|",from,to);
         to = from;
      }
      direction*=-1;
   }
   for(i=1; i < len; ++i){
      from = to - direction*2;
      printf("%02dTo%02d|",from,to);
      to = from;
   }
   direction*=-1;
   for(--len; len >= 0; --len){
      for(i = 0; i < len; ++i){
         from = to - direction*(1 + (i!=0));
         printf("%02dTo%02d|",from,to);
         to = from;
      }
      direction*=-1;
   }
   return 0;
}

そして、ゴルフをしました(これはゴルフではなくコードチャレンジでしたが):

#define B {F=T-D*(1+(i!=0));printf("%02dTo%02d|",F,T);T=F;}D*=-1;
L,F,T,D,i;main(int U,char**A){U=atoi(A[1])/2;T=U+1;D=1;for(L=1;L<=U;++L){for(i=L-1;i>=0;--i)B}for(i=1;i<L;++i)B for(--L;L>=0;--L){for(i=0;i<L;++i)B}}

#define B {F=T-D*(1+(i!=0));printf("%02dTo%02d|",F,T);T=F;}D*=-1;
L,F,T,D,i;main(int U){scanf("%d",&U);U/=2;T=U+1;D=1;for(L=1;L<=U;++L){for(i=L-1;i>=0;--i)B}for(i=1;i<L;++i)B for(--L;L>=0;--L){for(i=0;i<L;++i)B}}

ゴルフバージョンを実行すると、セグメンテーション違反が発生します。
artistoex

申し訳ありませんが、入力がコマンドライン引数として指定されていることを忘れていました。引数なしで実行すると、セグメンテーション違反になります。しかし、実際にはあなたがそれを言及したので、なぜコマンドライン引数がよりも短いと思ったのかはわかりませんscanf。私はより良いバージョンで私の答えを更新しています。
ゴードンベイリー

あなたはL / R / L / R(ビッグビーイング"ジャンプ")を使用したときにパターンがより顕著である:N(2)=rLrN(4)=rLlRRlLrN(6)=rLlRRrLLLrRRlLr、など
Shmiddty

2

Mathematica

このアプローチNestは、移動のサイズと方向のedシーケンスを構築{fromPosition,toPosition}します。位置nは、nマッチペアの数を指します。次にFold、シーケンスをmoveで始まる関数に入れます{n, n+1}

z@n_:=(p=1;h@t_:=Append[{Table[2 (-1)^t,{t}]},{(-1)^(t+1)}];
k=Join[Reverse@Drop[#,n],#]&[Flatten@Nest[Prepend[#,h[p++]]&,{},n]];
Fold[Append[#,{#[[-1,1]]-#2,#[[-1,1]]}]&,{{n,n+k[[1]]}},Rest@k])

z[1]

{{1、2}、{3、1}、{2、3}}


z[4]

{{4、5}、{6、4}、{7、6}、{5、7}、{3、5}、{2、3}、{4、2}、{6、4}、{ 8、6}、{9、8}、{7、9}、{5、7}、{3、5}、{1、3}、{2、1}、{4、2}、{6、 4}、{8、6}、{7、8}、{5、7}、{3、5}、{4、3}、{6、4}、{5、6}}


z[7]

{{7、8}、{9、7}、{10、9}、{8、10}、{6、8}、{5、6}、{7、5}、{9、7}、{ 11、9}、{12、11}、{10、12}、{8、10}、{6、8}、{4、6}、{3、4}、{5、3}、{7、 5}、{9、7}、{11、9}、{13、11}、{14、13}、{12、14}、{10、12}、{8、10}、{6、8} 、{4、6}、{2、4}、{1、2}、{3、1}、{5、3}、{7、5}、{9、7}、{11、9}、{ 13、11}、{15、13}、{14、15}、{12、14}、{10、12}、{8、10}、{6、8}、{4、6}、{2、 4}、{3、2}、{5、3}、{7、5}、{9、7}、{11、9}、{13、11}、{12、13}、{10、12} 、{8、10}、{6、8}、{4、6}、{5、4}、{7、5}、{9、7}、{11、9}、{10、11}、{ 8、10}、{6、8}、{7、6}、{9、7}、{8、9}}


スワップの視覚化

rb、及びo画像又はそれぞれ赤一致、青色一致、および不一致があります。

マッチ

次の出力はz、一致するスワップを表示するようにフォーマットされます。

swaps[n_]:=FoldList[Grid[{Permute[#[[1,1]],Cycles[{#2}]],Range[2n+1]}]&,
Grid[{Join[Table[r,{n}],{o},Table[b,{n}]],Range[2n+1]}],z[n]]

swapMatches[n_]:=Grid[Partition[swaps[n],2,2,1,""],Dividers->All]

swapszasコマンドの順序付けられたペアを使用して状態のリストを作成し、最初のリストと後続のリストを並べ替えます。

swaps[1]

スワップ1

swapMatches 状態をグリッドに表示します。

swapMatches[2]

swaps2

swapMatches[3]

swaps3


0

JavaScript 191

function f(N) {
    n=N>>=i=c=a='1';n++
    s=z='0'
    for(k=b='34';i<N;k=i%2?a+=z+z:b+='44',i++)c=k+c
    t=''
    i=N*(N+1)/2
    l=2*i+N
    for(;l;n+=(i>=1?r=c[i-1]:i<=-N?c[-i-N]:k[1])-2,t+=(s=n>9?'':z)+n+a+'|',--l,--i)a='To'+s+n
    return t
}

使用してカウントされる文字 grep =|tr -d \ |wc -c


1
こんにちは、コードゴルフへようこそ!私はあなたの解決策がどのテストケース(jsfiddle.net/SJwaU)に対しても正しい出力を生成しないことに気付くと思います。入力の02場合、値は正しいですが、末尾が欠落してい|ます。他の2つのケースでは、値がかなりずれており、のフォーマット10も間違っています。また、文字カウント方法についても不明です。関数の本体から戻り値を引いた数だけを数えるのはなぜですか?
ゴードンベイリー

@gordonおっと、最近の最適化でミスをしたようです。ご指摘いただきありがとうございます。REPLでは必要なのはそれだけだからです。便宜上、機能装飾を入れています。
artistoex

合計に対して、関連する空白(たとえば、改行)を数える必要があります。
Shmiddty、2013

@shmiddty tr -d \ |wc -cは改行を考慮に入れます
artistoex
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.