Code-Golf Ascii Art Mini-Golf


13

Вступ

Давайте пограємо в міні-гольф! М'яч для гольфу представлений a, .а отвір - a O. Ви хочете отримати отвір в одному на кожному отворі, але вам не дуже добре. Насправді ви відмовляєтеся від спроби поставити діагонально! Тільки вгору, вниз і в обидві сторони.

Ви плануєте обдурити, розмістивши зайві бампери, \і /таким чином ви можете покласти м'яч одним пострілом. М'яч відскакує від бамперів під прямим кутом, як показано на цьому малюнку.

Гольф

Не забудьте подзвонити пострілом! Розкажіть, у який бік ви рухаєтесь.


Отвори

1: Перший отвір легко, прямий постріл! Тут не потрібно розміщувати бампери.

Вхід:

.         O

Вихід:

right
.         O

2: Ще один базовий - короткий поворот. М'яч ударяється з бампера в отвір.

Вхід:

     .
O

Вихід:

left
/    .
O

або

down
     .
O    /

3: У деяких отворах вже є бампери!

Вхід:

.   \O

Вихід:

right
.   \O
    \/

або

right
   / \
.  /\O

4: Деякі отвори надмірно складні!

Вхід:

    /  \  \    /
   /  . \  \  /
  /  /\/   /\ \  /
 /  /     /  \ \/
/  /   /\ \  /  \  /
\  \  /  \ \/    \/ 
      \  /          /
  /\   \//\ \      /
 /  \   /  \ \     \/
 \  /\  \  /  \     \
  \/  \  \/    \ O/  \
      /         \/

Вихід: (одне можливе рішення, існує більше)

down
    /  \  \    /
   /  . \  \  /
  /  /\/   /\ \  /
 /  /     /  \ \/
/  /   /\ \  /  \  /
\  \  /  \ \/    \/ 
/     \  /          /
  /\   \//\ \      /
\/  \   /  \ \     \/
 \  /\  \  /  \  /  \
  \/  \  \/    \ O/  \
      /  \      \/
                \   /

Правила

  • Вхід є міні-гольф отвір на STDIN.
  • Вихід напрямок ви вдарити по м'ячу і міні-гольф отвір знову розміщених бамперів на STDOUT.
  • Існуючі бампери не можна переміщувати.
  • Ви можете додати будь-яку кількість бамперів для вирішення лунки.
  • Припустимо, що для розміщення бамперів є дійсні місця, які дозволять вирішити хід за один пут.
  • Вихідний отвір може бути більшим, ніж вхідний.
  • Вхід може бути залитий білим пробілом, але, будь ласка, вкажіть у своїй відповіді, якщо це зробити.
  • Вихід повинен виглядати правильним, але може мати провідний або кінцевий пробіл.
  • Ваша програма повинна працювати для будь-яких дійсних дірок. Не соромтеся також розміщувати свої тестові справи!

Оцінка балів

Це . Ваш бал - кількість символів у вашій програмі. Найнижчий рахунок виграє!


1
Я впевнений, що вказівки (вгору, вліво, вправо, вниз) неправильні в наступних прикладах: # 2 приклад 2 повинен бути right, # 3 приклад 1 повинен бути down, а № 3 приклад 2 повинен бути up. Цікавий виклик, хоча!
Дверна ручка

@Doorknob дякую! .це м'яч, в який ви б'єте, і Oце отвір. Я заплутався на прикладі №2, але вони мають бути хорошими зараз.
hmatt1

Відповіді:


6

Javascript (ES6) - 651 байт

G=s=>{Q='\\';S=[[]];n=L=1;s.split(N='\n').map(t=>{j=S[L++]=[];l=t.length;n=n>l?n:l;k=1;t.split('').map(T=>{j[k++]=T})});S[O=L++]=[];n++;for(r=0;r<L;r++)for(c=0;c<=n;c++){v=S[r][c];if(!v)S[r][c]=' ';if(v=='.'){x=c;y=r}if(v=='o'){X=c;Y=r}}f=M=>{J=M?'.':'o';K=M?'o':'.';R=0;for(D=0;1;D++){R=D&4;D=D&3;c=e=D;g=M?X:x;h=M?Y:y;while(c!=K){c=S[h+=[-1,0,1,0][e]][g+=[0,1,0,-1][e]];e=c=='/'?(B=c,e^1):c==Q?(B=c,3-e):e;E=h*(h-O)?g*(g-n)?0:2:1;if(R&&c==' '){S[h][g]=Q;R=D=0;c=K}if(c==J||E){E&&(S[h][g]=(E+M)%2?Q:'/');H=M?E?H:(e+2)&3:D;return}}}};f(0);f(1);S[0][0]=S[O][n]='/';S[0][n]=S[O][0]=Q;return['up','right','down','left'][H]+N+S.map(t=>t.join('')).join(N)}

Створює функцію, Gяка приймає рядок (поле для гольфу) як вхідний і повертає запитуване рішення про введення. Вхідний рядок може мати або не мати провідних рядків, кінцевих ліній та пробілів. Вихідні дані не матимуть пробілу чи пробілів.

Розширений код:

G = s => {
    Q = '\\';
    S = [[]];
    n = L = 1;
    s.split( N = '\n' ).map( t => {
        j = S[L++] = [];
        l = t.length;
        n = n > l ? n : l;
        k = 1;
        t.split('').map( T => {
            j[k++] = T;
        } );
    } );
    S[O = L++] = [];
    n++;
    for( r = 0; r < L; r++ )
        for( c = 0; c <= n; c++ ) {
            v = S[r][c];
            if( !v )
                S[r][c] = ' ';
            if( v == '.' ) {
                x = c;
                y = r;
            }
            if( v == 'o' ) {
                X = c;
                Y = r;
            }
        }
    f = M => {
        J = M ? '.' : 'o';
        K = M ? 'o' : '.';
        R = 0;
        for( D = 0; 1; D++ ) {
            R = D & 4;
            D = D & 3;
            c = e = D;
            g = M ? X : x;
            h = M ? Y : y;
            while( c != K ) {
                c = S[h += [-1,0,1,0][e]][g += [0,1,0,-1][e]];
                e = c == '/' ? (B=c,e^1) : c == Q ? (B=c,3-e) : e;
                E = h*(h-O) ? g*(g-n) ? 0 : 2 : 1;
                if( R && c == ' ' ) {
                    S[h][g] = B;
                    R = D = 0;
                    c = K;
                }
                if( c == J || E ) {
                    E && (S[h][g] = (E+M)%2 ? Q : '/');
                    H = M ? E ? H : (e+2)&3 : D;
                    return;
                }
            }
        }
    };
    f(0);
    f(1);
    S[0][0] = S[O][n] = '/';
    S[0][n] = S[O][0] = Q;
    return ['up','right','down','left'][H] + N + S.map( t => t.join('') ).join( N );
}

Розв’язувач працює за умови, що будь-який шлях від кулі (отвору) буде будь-яким

  1. знову повернути до кулі (лунки)
  2. привести в отвір (куля)
  3. вийти з курсу

Простежуємо шлях кулі у всіх чотирьох напрямках. Якщо ми знайдемо випадок 3, проблема вирішена. Якщо ми знайдемо випадок 2, відзначимо місце виходу кулі. Якщо всі чотири напрямки призводять до випадку 1, ми перетворюємо перший простір, що не перебуває у бампері, вздовж будь-якої траєкторії, на бампер (якщо проблема вирішена, такий простір завжди гарантовано існує) і повторюємо спробу. Бампер, до якого ми перетворюємо, матиме той самий тип, що і останній бампер, з яким траєкторія зустрічалася *. Якщо куля все-таки застрягла в петлі, процес повторюємо стільки разів, скільки потрібно. Якщо проблема вирішується, ця процедура гарантовано врешті-решт призведе до результату 2 або 3.

(* Зауважте, що якщо ми просто перетворимо на фіксований бампер [скажімо, \], існують надзвичайно надумані, але все-таки можливі випадки, коли рішення існує, але ми не зможемо його знайти.)

Ми виконуємо аналогічний слід з лунки, що призводить до результату 2 або результату 3.

Якщо і кульовий слід, і сліди отворів приводять до результату 2, ми розміщуємо бампери на периферії ходу, які зв'язують дві точки виходу (насправді ці периферійні бампери розміщуються незалежно від результатів сліду, щоб скоротити код). Це завершує рішення.

Тестові випадки та результати

В

   /   \   / \ /\    
   \\      /    \  \ 
       /     / o   / 
   /   \       /     
   \   .  \  \    \\ 
       /  /     \ \  
       \          /  
           \      /  
 \ /\     /  \/  //\

Вийшов

right
/   /               \
   /   \   / \ /\    
   \\      /    \  \ 
       /     / o   / 
   /   \       /     
   \   .  \  \    \\ 
       /  /     \ \  
       \          / /
           \      /  
 \ /\     /  \/  //\ 
\                   /

В

  / \   / /    /  \    / \  /  \\ /
\   \ /  \  // \    \   /   /\   \
/ \   // \  //   \ \   \ /  / \\ \
 \  / \    /   \  \  / / \\ / /  //
/ /   /\ \\ //  / \   /  \ / \\ \ \
\   \  \ \ // \ /  /    \ \  /  / /
/ \ /   /  / \     / \ /\   /  \  /
\ /\  //\   .\  \ \ //\ /  \  / \ /
/ \/ \ /\ //\   /   \   / o// \ / \
/   / \    / \ / \\ / \   / \   \ \
/ /   / \  / \ //   \    / \/  /\/
   / \   / \  /   \\  / \    /\ / \
/ \/   \   /   \/  \   /  \    /\\
/ /\\ //\  / \  /\ /\   /  / \ / \/

Вийшов

left
/                                   \
   / \   / /    /  \    / \  /  \\ / 
 \   \ /  \  // \    \   /   /\   \  
 / \   // \  //   \ \   \ /  / \\ \  
  \  / \    /   \  \  / / \\ / /  // 
 / /   /\ \\ //  / \   /  \ / \\ \ \ 
 \   \  \ \ // \ /  /    \ \  /  / / 
 / \ /   /  / \     / \ /\   /  \  / 
 \ /\  //\   .\  \ \ //\ /  \  / \ / 
 / \/ \ /\ //\   /   \   / o// \ / \ 
 /   / \    / \ / \\ / \   / \   \ \ 
 / /   / \  / \ //   \    / \/  /\/  
    / \   / \  /   \\  / \    /\ / \ 
 / \/   \   /   \/  \   /  \    /\\  
 / /\\ //\  / \  /\ /\   /  / \ / \/ 
\         \                         /

В

/\/ \      
\  \ \     
 \ \\ \   o
  \ .\ \   
   \ / /   
    \ /    

Вийшов

down
/   \      /\
 /\/\\       
 \ \\ \      
  \ \\ \   o 
   \ .\ \    
    \ / /    
     \ /     
\           /

Невдача у цьому тестовому випадку:"/\\/\\\n\\.//\n// \\\n\\/ \no \\/"
Андерс Касеорг
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.