Можете ли вы цикл без сбоев?


14

Многие из нас знакомы с игрой Tron. Вы управляете «световым циклом», размещенным на сетке. Световой цикл всегда движется вперед (хотя вы контролируете направление) и оставляет за собой постоянный след. Если вы столкнетесь с тропой, вы упадете!

Цель здесь состоит в том, чтобы определить, является ли данный путь допустимым циклом, то есть он возвращается к своей начальной точке без «сбоя». Для этого мы предполагаем, что мы начинаем с этой точки (0,0). Входные данные задаются в форме N2E1S2W1с рядом основных направлений ( Nесть north, Eесть eastи т. Д.), Каждое из которых следует расстоянием для перемещения в этом направлении. В этом примере вы бы путешествовали

N2 : North 2 to (0,2)
E1 : East 1  to (1,2)
S2 : South 2 to (1,0)
W1 : West 1  to (0,0)

Путь считается действительным, если он заканчивается (0,0)без посещения какой-либо другой координаты более одного раза (он (0,0)проходит ровно дважды. Один раз в начале и один раз в конце). Имейте в виду, чем в приведенном выше примере, чтобы добраться (0,0)до (0,2), мы обязательно посетим (0,1)также.

Другие примеры:

input        -> output
N1E1S1W1     -> true
N1E1N1E1S2W2 -> true
N1S1E1W1     -> false     // Visits (0,0) 3 times
N4E2S2W4S2E2 -> false     // Visits (0,2) twice
N3E2S3       -> false     // Does not return to (0,0)
N1S1         -> anything  //I don't care how you evaluate this case

Ваш вывод может быть в любой форме, при условии, что он дает одинаковый вывод для любого истинного или ложного значения.

Входные данные могут быть приняты в виде строки или в виде списка символов, либо в форме S1N2E3... или SNNEEE... Также нет жесткого ограничения на размер сетки, но предположим, что входные данные ничего не переполняют. До тех пор, пока код является в основном надежным, не важно обрабатывать подобные случаи N99999999999999.

Примечание: Вы можете оценить случаи N1S1, E1W1, S1N1иW1E1 тем не менее вы хотели. Это технически правильные пути, но они идут вразрез с духом «Трона».

счет

Это , поэтому выигрывает самый короткий ответ!


N1S1должно быть истинным, чтобы соответствовать вашим определениям, потому что оно достигает (0, 0)дважды и (0, 1)один раз, что действительно в соответствии с вашим определением.
HyperNeutrino

Могу ли я принять Nкак 1j, Eкак 1, Sкак -1jи Wкак -1?
Утренняя монахиня

@ LeakyNun Я думаю, что я в порядке с этим, так как все должны более или менее делать что-то вроде этого, в любом случае. Просто убедитесь, что вы указали это в своем ответе.
Лорд Фаркваад

1
@HyperNeutrino, но с точки зрения Tron ваш световой цикл проходит (0, 0,5) дважды, даже если вход никогда не поставит вас в такую ​​точку. Вот почему я думаю, что у каждого есть гибкий вывод (хотя для большинства языков будет проще вернуть true)
Value Ink

1
@steenbergh (0,0) не в углу, так что вы можете пойти под ним или слева от него; даже оба, если вы чувствуете себя сумасшедшим! Кроме того, нет никаких жестких ограничений на размер сетки, но просто предположим, что входные данные ничего не переполняют. Пока код в основном N99999999999999
надежный

Ответы:



6

JavaScript, 247 200 байт

n=s=>{r=s.match(/\w\d+/g)
x=y=z=0
e=""
for(d of r){a=d[0]
b=d.slice(1)
while(b--){
y+=a=="N"
y-=a=="S"
x+=a=="E"
x-=a=="W"
p=[x,y]+";"
if(~e.indexOf(p))if(!x&!y)z++
else return 0
e+=p}}return!x&!y&!z}

nявляется функцией входной строки, sкоторая возвращает 1истину и 0ложь

Вот незагрязненная версия для справки / объяснения:

function n(s)
{
    var dir = s.match(/\w\d+/g);
    var x = y = z = 0;
    var been = "";
    for (d of dir)
    {
        var a = d[0];
        var b = 1*d.substring(1);
        while(b-- > 0)
        {
            if (a == "N") y++;
            if (a == "S") y--;
            if (a == "E") x++;
            if (a == "W") x--;
            var pt = [x,y] + ";";
            if (~been.indexOf(pt))
                if (x==0 && y==0)
                    z++;
                else
                    return false;
            been += pt;
        }
    }
    return (x == 0 && y==0 && z == 0);
}

n=s=>{r=s.match(/\w\d+/g)
x=y=z=0
e=""
for(d of r){a=d[0]
b=d.slice(1)
while(b--){
y+=a=="N"
y-=a=="S"
x+=a=="E"
x-=a=="W"
p=[x,y]+";"
if(~e.indexOf(p))if(!x&!y)z++
else return 0
e+=p}}return!x&!y&!z}

console.log(n("N1E1S1W1"))
console.log(n("N1E1N1E1S2W2"))
console.log(n("N1S1E1W1"))
console.log(n("N4E2S2W4S2E2"))
console.log(n("N3E2S3"))



не заметил этого, спасибо
WaffleCohn

Кажется, что containsэто не функция в любом диалекте JavaScript. Не могли бы вы указать диалект?
Утренняя монахиня

Я просто использовал консоль Chrome для тестирования - он отлично работает там
WaffleCohn

На самом деле это работает и в моей chrome консоли ... но, может быть, вы бы хотели изменить его на более универсальный ответ?
Утренняя монахиня

5

Python 3 , 236 161 150 байт

import re
p=0
a=[]
for i in''.join(s[0]*int(s[1:])for s in re.findall(r".\d+",input())):p+=1j**"NESW".find(i);a+=[p]
print(len({*a})-len(a)==0==a[-1])

Попробуйте онлайн!

-75 байтов благодаря Leaky Nun
-11 байтов благодаря Leaky Nun Или, если нам разрешено принимать входные данные в виде списка декодированных комплексных чисел длины серии:

Python 2 , 85 73 байта

c=0;k=[]
for i in input():c+=i;k+=[c]
print(k[-1]==0==len(set(k))-len(k))

Попробуйте онлайн!

-12 байт благодаря Mr. Xcoder / -9 байт благодаря Leaky Nun (объединено в одну правку)

Это слишком долго для меня LOL


3
Пока оно короче 10-кратного решения Pyth, оно не слишком длинное.
Утренняя монахиня

@LeakyNun lol ладно: P
HyperNeutrino


@ LeakyNun ооочень хорошо. вижу слишком долго, как я уже сказал: P
HyperNeutrino


3

Желе , 14 12 байт

Œṙ+\µQ⁼ȧṛ/¬$

Я впервые играю в гольф в желе. Предложения приветствуются.

Входные данные представляют собой массив [direction, distance]пар, где направление задается в виде комплексного числа.

Объяснение:

Œṙ+\µÇȧṛ/¬$   Main link. Argument: n     = [[i, 3], [1, 2], [-i, 3]]
Œṙ            Run-length decode          = [i, i, i, 1, 1, -i, -i, -i]
  +\          Cumulative sum             = [i, 2i, 3i, 3i+1, 3i+2, 2i+2, i+2, i]
    µ         Begin a new monadic chain
     Q        Remove duplicates          = [i, 2i, 3i, 3i+1, 3i+2, 2i+2, i+2]
      ⁼       Equal to original?         = 0
           $  Make a monadic link:
        ṛ/      Reduce by right argument   = i
                (Gets the last element)
          ¬     Logical NOT:               = 0
       ȧ      Logical AND the two values = 0

Должен провалиться последний случай.
Утренняя монахиня

0

Сетчатка , 86 байт

\d+
$*
1(1*)
$1
+`(.)1
$1$1
.
 $`$&¶
%O`.
+`NS|E(.*)W
$1
M`\w$|(?m)(^.+$)(?s).+^\1$
^0

Попробуйте онлайн! Ссылка включает в себя тестовые случаи. Объяснение:

\d+
$*

Преобразовать числа в одинарные.

1(1*)
$1
+`(.)1
$1$1

Длина строки декодирует буквы. N111нужно превратить в NNN, так что из каждого унарного числа вычитается одно, а затем каждый 1 дублирует предыдущую букву.

.
 $`$&¶

Создайте все префиксы (т.е. точки на пути) в виде отдельных строк. Пробел имеет префикс, чтобы избежать проблем с пустыми строками.

%O`.
+`NS|E(.*)W
$1

Сортируйте все буквы в каждой строке по порядку, а затем удалите соответствующие пары. В итоге мы получаем уникальный код для любой заданной точки на сетке.

M`\w$|(?m)(^.+$)(?s).+^\1$

Проверьте одну из двух вещей: a) последняя точка не заканчивается пробелом (т. Е. Цикл не закрылся) или две повторяющиеся точки на пути. Если путь действителен, все проверки не пройдены, и результат равен нулю.

^0

Инвертировать результат.


0

Perl, 140

Работает со строковым вводом. Возможно, я могу сократить с массивом, но я сомневаюсь в этом. Рад за любую дополнительную помощь в гольф :)

sub w{$i=$_[0];%d=(E,[0],S,[1,-1],W,[0,-1]);$i=~s/(.)(.)/($d,$o)=(@{$d{$1}},1,1);for(1..$2){$s[$d]+=$o;$r+=$d{"@s"}++}/eg;!($s[0]+$s[1]+$r)}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.