Обмін номерами [закрито]


10

Це звичайна головоломка, яку багато з вас вирішили вручну. Тепер саме час написати алгоритм для вирішення того ж.

Є однакові за кількістю сірники палички, вишикувані у дві різні сторони, спрямовані один на одного. Між ними є єдиний порожній простір. Скажіть щось на зразок наступного малюнка (якщо загальна кількість сірників - 4).

введіть тут опис зображення

Кожна палиця може або ковзати на один крок у напрямку вперед (якщо прямий передній простір вільна), або її можна перестрибнути через одну палицю в передній частині, і приземлитися у вільний простір (якщо цей простір вільний). Рух у зворотному напрямку неможливий (навіть вільний простір). Не допускається також зворотний стрибок. Допускається лише один хід за один крок.

Тепер вам слід написати алгоритм, щоб знайти мінімально необхідні кроки, за допомогою яких усі палиці сірника з лівої сторони будуть розташовуватися в правій частині, а всі палички з правою стороною - у лівій частині.

Наприклад: Якщо всього 2 палички (по одній стороні), то кроки будуть:

введіть тут опис зображення

Примітка. На наведеному малюнку перша ліва палиця була переміщена. Ще одне рішення існує, коли правий бічний палиця рухається першим. Але для цієї проблеми ви повинні дати лише одне рішення, і це також припускати, що ліва бічна палиця рухається першою.

На наступному малюнку описані ходи 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
Я зробив кілька швидких зображень. Сподіваємось, вони відповідають оригінальним намірам автора.
примо

3
Умова перемоги?
Шміддті

Відповіді:


3

129 APL

Нижче наведений код приймає екранні введення та виводить на екран у вказаному форматі:

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)),¨⊂'|')~' '

Добру третину коду займає форматування виводу. Логіка завершена появою символу ⋄ в коді.

Нижче наведено результат для введення 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 тощо, швидше за все, виграє код гольфу проти більш багатослівних мов на основі слів;)
Грем

3

Javascript 178 174 161

prompts, nтоді alertвідповідь s. (Без 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 до 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/Rі m/j. Мені подобається ідея відокремити відстань, просунуту від напрямку
Гордон Бейлі,

2

С - 216 213

Моє рішення ґрунтується на двох фактах:

  1. Поле "до" - це поле "від" попереднього ходу (оскільки ви завжди створюєте порожній слот у просторі, з якого ви рухаєтесь, і завжди переходите на порожній слот)

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

Коли я запускаю вашу версію для гольфу, я отримую segfault.
artistoex

Пробачте, я забув згадати, що вхід подається як аргумент командного рядка - якщо ви запускаєте його без аргументів, він буде сегментарно. Але насправді тепер, коли ви це згадуєте, я не знаю, чому я думав, що аргументи командного рядка будуть коротшими, ніж scanf. Я оновлюю свою відповідь кращою версією.
Гордон Бейлі

Картина більш помітний при використанні L / R / L / R (великий істота "стрибок"): N(2)=rLr, N(4)=rLlRRlLr, N(6)=rLlRRrLLLrRRlLrі т.д.
Shmiddty

2

Математика

Цей підхід будує Nestпослідовність розмірів і напрямків ходів, відформатованих як {fromPosition,toPosition}, починаючи з положення n, де nпосилається на кількість пар збігу. Потім Foldпослідовність переходить у функцію, яка починається з переміщення {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,, bі 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]

swapsстворює список станів, використовуючи впорядковані пари в zякості команд для перестановки початкового списку та наступних списків.

swaps[1]

свопи1

swapMatches відображає стани в сітці.

swapMatches[2]

свопи2

swapMatches[3]

свопи3


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значення є правильними, але в ньому відсутнє контур |. Для двох інших випадків значення відхиляються, а форматування 10також неправильне. Також не впевнений у своєму методі підрахунку персонажів. Чому ви рахуєте лише тіло функції за мінусом повернення?
Гордон Бейлі

@gordon На жаль, я помилився в останній оптимізації. Дякуємо, що вказали. Я рахую тіло лише тому, що на REPL це все, що вам потрібно. Я поставив функцію прикраси лише заради зручності.
artistoex

Вам потрібно порахувати відповідні пробіли (наприклад, нові рядки) до загальної суми.
Шміддті

@shmiddty tr -d \ |wc -cвраховує нові рядки
artistoex
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.