Avast, ви негідні ваги!


10

Борода був англійський пірат на початку 18 - го століття. Хоча він був відомий тим, що грабував і приймав кораблі, він командував своїми суднами з дозволу їх екіпажів. Немає повідомлень про те, що він ніколи не завдав шкоди чи вбивства своїм полоненим.

Цей виклик на честь сумнозвісної Чорної бороди та натхненний Міжнародною розмовою, як день пірата (19 вересня). Це також зворотне завдання цього Пірри .


Змагання

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


Вхідні дані

Всі входи будуть складатися з v, >, <, ^, пробілу та один X.

Ви можете припустити наступне:

  • карта ніколи не буде циклічно чи перетинатися

  • початкова стрілка завжди буде найменшим символом у крайньому лівому стовпчику

  • завжди буде скарб ( X)

Зразок введення показаний нижче.

  >>v   >>>>>>v
  ^ v   ^     v
  ^ v   ^   v<<
  ^ v   ^   v
  ^ >>>>^   >>X
  ^
>>^

Вихідні дані

Вихід повинен бути ", "розділеним рядком напрямків. Нижче наведено правильний вихід із наведеної вище карти.

E2, N6, E2, S4, E4, N4, E6, S2, W2, S2, E2

Допускається одна затримка нового рядка або пробіл.


Приклади

In:
>>>>>>>>>>>>>>>v
               v
               v
               >>>>X

Out:
E15, S3, E4

In:
>>>>>>v
^     v
^     >>>>X

Out:
N2, E6, S2, E4

In:
X
^
^
^

Out:
N3

In:
>>>>>>v
^     v
^     v
      v
      >>>>>>X

Out:
N2, E6, S4, E6

In:
 X
 ^
 ^
>^

Out:
E1, N3

In:
>X

Out:
E1

In:
v<<<<<
vX<<<^
>>>>^^
>>>>>^

Out:
E5, N3, W5, S2, E4, N1, W3

Щаслива міжнародна розмова, як день пірата!


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

Я додав приклад на ваш запит. Я також додав детальну інформацію про те, що початковий символ буде нижньою частиною стовпця. @RetoKoradi
Zach Gates

Оскільки я викликав певне занепокоєння у відповідному питанні щодо довжини останнього сегмента, я ще раз затхну і скажу, що це не зовсім зворотне питання. Хтось намагається ще раз обдурити піратів, я думаю.
coredump

Єдина відмінність - кількість кроків останнього напрямку. @coredump Принаймні, наскільки я можу сказати.
Zach Gates

1
@ZachGates Так, саме (і просто для того, щоб зрозуміти, я не кажу, що питання слід змінювати, воно добре, як є зараз).
coredump

Відповіді:


3

CJam, 78 байт

qN/_:,$W=:Tf{Se]}s:U,T-{_U="><^vX"#"1+'E1-'WT-'NT+'S0"4/=~_@\}g;;]e`{(+}%", "*

Спробуйте в Інтернеті .

Пояснення

Основна ідея тут - знайти найдовший рядок (ми будемо називати цю довжину T), після чого прокладіть всі рядки на однакову довжину і з'єднайте їх (ця нова рядок є U). Таким чином, для переміщення по карті потрібен лише один лічильник. Додавання / віднімання 1означає переміщення вправо / вліво в тому ж рядку, додавання / віднімання Tозначає переміщення вниз / вгору на один рядок.

qN/    e# Split the input on newlines
_:,    e# Push a list of the line lengths
$W=:T  e# Grab the maximum length and assign to T
f{Se]} e# Right-pad each line with spaces to length T
s:U    e# Concatenate lines and assign to U

Тепер настав час встановити цикл.

,T-    e# Push len(U) - T
       e# i.e. position of first char of the last line
{...}g e# Do-while loop
       e# Pops condition at the end of each iteration

Тіло циклу використовує таблицю пошуку та eval, щоб вибрати, що робити. На початку кожної ітерації верхній елемент стека - це поточне положення. Під ним знаходяться всі оброблені напрямки NSWE. В кінці ітерації новий напрямок розміщується під положенням, а його копія використовується як умова для циклу. Ненульові символи є правдоподібними. Коли зустрічається X, 0 рухається як напрямок, закінчуючи цикл.

_U=      e# Push the character in the current position
"><^vx"# e# Find the index in "><^Vx"
"..."4/  e# Push the string and split every 4 chars
         e# This pushes the following list:
         e# [0] (index '>'): "1+'E" pos + 1, push 'E'
         e# [1] (index '<'): "1-'W" pos - 1, push 'W'
         e# [2] (index '^'): "T-'N" pos - T, push 'N'
         e# [3] (index 'v'): "T+'S" pos + T, push 'S'
         e# [4] (index 'X'): "0"    push 0
=~       e# Get element at index and eval
_@\      e# From stack: [old_directions position new_direction]
         e# To stack: [old_directions new_direction position new_direction]
         e# (You could also use \1$)
         e# new_direction becomes the while condition and is popped off

Тепер стек виглядає наступним чином : [directions 0 position]. Давайте генеруємо вихід.

;;    e# Pop position and 0 off the stack
]     e# Wrap directions in a list
e`    e# Run length encode directions
      e# Each element is [num_repetitions character]
{     e# For each element:
 (+   e#   Swap num_repetitions and character
}%    e# End of map (wraps in list)
", "* e# Join by comma and space

3

CJam, 86 байт

qN/_,{1$=cS-},W=0{_3$3$==_'X-}{"^v<>"#_"NSWE"=L\+:L;"\(\ \)\ ( )"S/=~}w];Le`{(+}%", "*

Спробуйте в Інтернеті

Пояснення:

qN/     Get input and split into rows.
_,      Calculate number of rows.
{       Loop over row indices.
  1$=     Get row at the index.
  c       Get first character.
  S-      Compare with space.
},      End of filter. The result is a list of row indices that do not start with space.
W=      Get last one. This is the row index of the start character.
0       Column number of start position. Ready to start tracing now.
{       Start of condition in main tracing loop.
  _3$3$   Copy map and current position.
  ==      Extract character at current position.
  _'X-    Check if it's the end character `X.
}       End of loop condition.
{       Start of loop body. Move to next character.
  "^v<>"  List of directions.
  #       Find character at current position in list of directions.
  _       Copy direction index.
  "NSWE"  Matching direction letters.
  =       Look up direction letter.
  L\+:L;  Append it to directions stored in variable L.
  "\(\ \)\ ( )"
          Space separated list of commands needed to move to next position for each of
          the 4 possible directions.
  S/      Split it at spaces.
  =       Extract the commands for the current direction.
  ~       Evaluate it.
}w      End of while loop for tracking.
];      Discard stack content. The path was stored in variable L.
Le`     Get list of directions in variable L, and RLE it.
{       Loop over the RLE entries.
  (+      Swap from [length character] to [character length].
}%      End of loop over RLE entries.
", "*   Join them with commas.

2

Javascript (ES6), 239 байт

a=>(b=a.split`
`,b.reverse().some((c,d)=>c[0]!=' '&&((e=d)||1)),j=[],eval("for(g=b[e][f=0];b[e][f]!='X';g=b[e][f],j.push('NSEW'['^v><'.indexOf(i)]+h))for(h=0;g==b[e][f];e+=((i=b[e][f])=='^')-(i=='v'),f+=(i=='>')-(i=='<'),h++);j.join`, `"))

Пояснення:

a=>(
    b = a.split('\n'),
    // loops through list from bottom to find arrow
    b.reverse().some(
        (c, d)=>
            // if the leftmost character is not a space, saves the index and exit
            // the loop
            // in case d == 0, the ||1 makes sure the loop is exited
            c[0] != ' ' && ((e = d) || 1)
    ),
    j = [], // array that will hold the instructions
    eval("  // uses eval to allow a for loop in a lambda without 'return' and {}

        // loops through all sequences of the same character
        // e is the first coordinate of the current character being analyzed
        // f is the second coordinate
        // defines g as the character repeated in the sequence
        // operates on reversed b to avoid using a second reverse
        // flips ^ and v to compensate

        for(g = b[e][f = 0];
            b[e][f] != 'X'; // keep finding sequences until it finds the X
            g = b[e][f],    // update the sequence character when it hits the start of a
                            // new sequence
            j.push('NSEW'['^v><'.indexOf(i)] + h)) // find the direction the sequence is
                                                   // pointing to and add the
                                                   // instruction to j

            // loops through a single sequence until it hits the next one
            // counts the length in h
            for(h = 0;
                g == b[e][f]; // loops until there is a character that isn't part of
                              // the sequence
                // updates e and f based on which direction the sequence is pointing
                // sets them so that b[e][f] is now the character being pointed toward
                e += ((i = b[e][f]) == '^') - (i == 'v'),
                f += (i == '>') - (i == '<'),
                // increments the length counter h for each character of the sequence
                h++);

            // return a comma separated string of the instructions
            j.join`, `
    ")
)

0

JavaScript (ES6), 189

Випробуйте запуск фрагмента нижче у веб-переглядачі, сумісному з EcmaScript 6.

f=m=>{(m=m.split`
`).map((r,i)=>r[0]>' '?y=i:0);for(x=o=l=k=p=0;p!='X';++l,y+=(k==1)-(k<1),x+=(k>2)-(k==2))c=m[y][x],c!=p?(o+=', '+'NSWE'[k]+l,l=0):0,k='^v<>'.search(p=c);alert(o.slice(7))}

// Testable version, no output but return (same size)
f=m=>{(m=m.split`
`).map((r,i)=>r[0]>' '?y=i:0);for(x=o=l=k=p=0;p!='X';++l,y+=(k==1)-(k<1),x+=(k>2)-(k==2))c=m[y][x],c!=p?(o+=', '+'NSWE'[k]+l,l=0):0,k='^v<>'.search(p=c);return o.slice(7)}


// TEST
out = x => O.innerHTML += x+'\n';

test = 
[[`>>>>>>>>>>>>>>>v
               v
               v
               >>>>X`,'E15, S3, E4']
,[`>>>>>>v
^     v
^     >>>>X`,'N2, E6, S2, E4']
,[`X
^
^
^`,'N3']
,[`>>>>>>v
^     v
^     v
      v
      >>>>>>X`,'N2, E6, S4, E6']
,[` X
 ^
 ^
>^`,'E1, N3']
,[`>X`,'E1']
,[`v<<<<<
vX<<<^
>>>>^^
>>>>>^`,'E5, N3, W5, S2, E4, N1, W3']];

test.forEach(t=>{
  var k = t[1];
  var r = f(t[0]);
  out('Test ' + (k==r ? 'OK' : 'Fail')
      +'\n'+t[0]+'\nResult: '+r
      +'\nCheck:  '+k+'\n');
})
<pre id=O></pre>

Менше гольфу

f=m=>{
  m=m.split('\n'); // split in rows

  x = 0; // Starting column is 0
  m.forEach( (r,i) => r[0]>' '? y=i : 0); // find starting row

  o = 0; // output string
  p = 0; // preceding character
  l = 0; //  sequence length (this starting value is useless as will be cutted at last step)
  k = 0; //  direction (this starting value is useless as will be cutted at last step)
  while(p != 'X') // loop until X found
  {
    c = m[y][x]; // current character in c
    if (c != p) // changing direction
    {  
      o +=', '+'NSWE'[k]+l; // add current direction and length to output
      l = 0 // reset length
    );
    p = c;
    k = '^v<>'.search(c); // get new current direction
    // (the special character ^ is purposedly in first position)
    ++l; // increase sequence length
    y += (k==1)-(k<1); // change y depending on direction
    x += (k>2)-(k==2); // change x depending on direction
  }
  alert(o.slice(7)); // output o, cutting the useless first part
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.