Чи можете ви петлю, не збиваючись?


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

Вихід може бути в будь-якій формі, якщо він дає однаковий вихід для будь-якого значення truthy або falsey.

Введення можна сприймати як рядок або як список символів, або у формі S1N2E3... або SNNEEE... Також немає жорсткого обмеження щодо розміру сітки, але припустимо, що вхід нічого не переповнює. Поки код є принципово надійним, не важливо обробляти такі випадки N99999999999999.

ПРИМІТКА. Ви можете оцінити справи N1S1,E1W1 , S1N1і W1E1тим НЕ менш ви хотіли. Вони технічно справедливі шляхи, але вони йдуть проти духу виклику "трону".

Оцінка балів

Це , тому найкоротша відповідь виграє!


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

Чи можна приймати Nяк 1j, Eяк 1, Sяк -1jі Wяк -1?
Leaky Nun

@LeakyNun Я думаю, що я з цим все гаразд, оскільки всі люди повинні так чи інакше робити щось подібне. Просто переконайтеся, що ви вказали це у своїй відповіді.
Lord Farquaad

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

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

Відповіді:



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для true та 0for false

Ось незворушена версія для довідки / пояснення:

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. Чи можете ви вказати діалект?
Leaky Nun

Я просто використовував хромову консоль для тестування - вона прекрасно працює там
WaffleCohn

Насправді це працює і в моїй хромованій консолі ... але, можливо, ви б розглядали можливість змінити її на більш універсальну відповідь?
Leaky Nun

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 Або, якщо нам дозволено приймати дані як список декодованих складних чисел по довжині:

Пітон 2 , 85 73 байт

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

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

-12 байт завдяки містеру Xcoder / -9 байт завдяки Leaky Nun (об'єднані в одну редакцію)

Мені це здається занадто довго, хай


3
Поки воно коротше, ніж у 10 разів більше, ніж рішення Pyth, воно не надто довге.
Leaky Nun

@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

Слід провалити останній випадок.
Leaky Nun

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$

Перевірте одну з двох речей: а) остання точка не закінчується в просторі (тобто цикл не закрився) або дві повторювані точки на шляху. Якщо шлях дійсний, всі перевірки провалюються, а результат дорівнює нулю.

^0

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


0

Перл, 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.