Код-Гольф Ascii Art Мини-Гольф


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 пример 1, но теперь они должны быть хорошими.
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.