숫자 교환 [폐쇄]


10

이것은 많은 사람들이 수동으로 해결 한 일반적인 퍼즐입니다. 이제는이를 해결하기 위해 알고리즘을 작성해야합니다.

서로 다른 방향을 향한 두 개의 다른면에 등번호가 일치하는 스틱이 있습니다. 그들 사이에 하나의 빈 공간이 있습니다. 다음 그림과 같이 말합니다 (총 성냥개비가 4 개인 경우).

여기에 이미지 설명을 입력하십시오

각 스틱은 앞쪽으로 한 걸음 앞으로 이동하거나 (즉시 앞 공간이 비어있는 경우) 앞쪽에있는 하나의 스틱 위로 튀어 나와서 빈 공간으로 이동할 수 있습니다 (해당 공간이없는 경우). 빈 공간이 있어도 반대 방향으로 이동할 수 없습니다. 리버스 점프도 허용되지 않습니다. 한 번에 한 번만 이동할 수 있습니다.

이제 모든 왼쪽 성냥개비가 오른쪽에 착륙하고 모든 오른쪽 성냥개비가 왼쪽에 착륙하는 데 필요한 최소 단계를 찾기위한 알고리즘을 작성해야합니다.

예를 들어 : 총 2 개의 성냥개비 (각 측면에 1 개)가있는 경우 단계는 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

참고 : 위 그림에서 왼쪽 스틱이 먼저 움직였습니다. 오른쪽 스틱이 먼저 움직일 때 다른 해결책이 있습니다. 그러나이 문제의 경우 하나의 솔루션 만 제공해야하며 왼쪽 스틱이 먼저 움직이는 것으로 가정합니다.

다음 그림은 4 개의 성냥 스틱 (양쪽에 2 개)이있는 움직임을 설명합니다.

여기에 이미지 설명을 입력하십시오

참고 : 위 그림에서 왼쪽 스틱이 먼저 움직였습니다. 오른쪽 스틱이 먼저 움직일 때 다른 해결책이 있습니다. 그러나이 문제의 경우 하나의 솔루션 만 제공해야하며 왼쪽 스틱이 먼저 움직이는 것으로 가정합니다.

[가정 : 입력은 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|

이미지를 직접 포함 할 수없는 경우 다른 사람이 이미지를 편집 할 수있는 링크를 제공 할 수 있습니까?
피터 테일러

2
나는 빠른 이미지를 만들었다. 그들이 원래 저자의 의도를 따르기를 바랍니다.
primo

3
승리를위한 조건?
Shmiddty

답변:


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

@Shmiddty 나는 APL, J, GolfScript 등과 같은 순수한 기호 기반 언어가 더 장황한 단어 기반 언어에 비해 코드 골프에서 승리 할 가능성이 가장 높습니다;)
Graham

3

자바 스크립트 178 174 161

prompts는 n다음 alert의 대답. ( 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/23 회 반복 된 다음 다시 1로 감소합니다.
  3. 이동 유형은 이동과 점프 사이에서 번갈아 가며 행의 이동 횟수는 일정 1하며 순차적으로 점프하는 횟수는 1에서 증가한 n/2다음 다시 1로 감소합니다.
  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/Rand로 패턴이 더 명확하다는 것이 맞습니다 m/j. 나는 방향에서 이동 거리 분리의 생각처럼
고든 베일리

2

C - 216 213

내 솔루션은 두 가지 사실을 기반으로합니다.

  1. "to"필드는 이전 이동의 "from"필드입니다 (이동하는 공간에 항상 빈 슬롯을 만들고 항상 빈 슬롯으로 이동하기 때문에)

  2. 이동하는 거리와 방향에는 매우 규칙적인 패턴이 있습니다. 처음 세 가지 테스트 사례의 경우 다음과 같습니다.

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

골프 버전을 실행하면 segfault가 나타납니다.
artistoex

죄송합니다. 입력이 명령 행 인수로 제공된다는 것을 언급하지 않았습니다. 인수없이 실행하면 segfault가됩니다. 그러나 실제로 당신이 그것을 언급 했으므로, 나는 왜 명령 줄 인수가보다 짧을 것이라고 생각했는지 모르겠습니다 scanf. 더 나은 버전으로 답변을 업데이트하고 있습니다.
Gordon Bailey

: 당신은 L / R / L / R (큰 존재 "점프")를 사용할 때 패턴은 더 눈에 띄는 N(2)=rLr, N(4)=rLlRRlLr, N(6)=rLlRRrLLLrRRlLr, 등
Shmiddty

2

매스 매 티카

이 방법은 position으로 시작하는 Nest형식으로 이동의 크기와 방향의 일련의 시퀀스를 작성합니다 . 여기서 일치 쌍의 수를 나타냅니다. 그러므로 이동 시작 함수로 시퀀스이야 .{fromPosition,toPosition}nnFold{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}}


스왑 시각화

r, bo이미지 나 각각 빨간색 일치 파란색 일치없이 일치이다.

성냥

다음 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]

swapsz명령으로 정렬 된 쌍을 사용 하여 초기 목록과 후속 목록을 치환 하여 상태 목록을 생성 합니다.

swaps[1]

스왑 1

swapMatches 그리드에 상태를 표시합니다.

swapMatches[2]

스왑 2

swapMatches[3]

스왑 3


0

자바 스크립트 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
codegolf에 오신 것을 환영합니다! 귀하의 솔루션이 테스트 사례 ( jsfiddle.net/SJwaU )에 대한 올바른 출력을 생성하지 못한다고 생각합니다 . 입력 02의 경우 값이 정확하지만 후행이 누락되었습니다 |. 다른 두 경우에는 값이 꺼져 있고 형식 10도 잘못되었습니다. 또한 캐릭터 카운팅 방법에 대해 확실하지 않습니다. 함수 본문에서 리턴을 뺀 것만 계산하는 이유는 무엇입니까?
Gordon Bailey

@gordon Oops, 가장 최근 최적화에서 실수를 한 것 같습니다. 지적 해 주셔서 감사합니다. REPL에서는 몸만으로 충분합니다. 편의를 위해서만 기능 장식을 넣었습니다.
artistoex

총계에 대해 관련 공백 (예 : 줄 바꿈)을 계산해야합니다.
Shmiddty 2013

@shmiddty tr -d \ |wc -c는 개행을 고려합니다
artistoex
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.