Чи можна вирішити лабіринт?


20

Загадка

  • Роздрукуйте 0, якщо лабіринт n * m не вдається вирішити
  • Роздрукуйте 1, якщо лабіринт n * m можна вирішити (1 або більше способів)

(тому я не прошу шляхів, але якщо це можливо вирішити !!!)

Вхідний масив (2d):

[[0,0,0,0,0,0,1],[0,0,0,0,0,1,0],[0,0,0,0,1,0,0],[1,0,0,0,0,0,0]]

XXXXXXXXX
XS     XX
X     X X
X    X  X
XX     FX
XXXXXXXXX

0 = can pass through
1 = can not pass trough
[0][n] is the last block of the first line
[m][0] is the first block of the last line

Правило Стартове положення дорівнює 0,0, а кінцеве положення - n, м. Ви можете рухатись лише горизонтально і вертикально Найкоротший код виграє


Чи слід вводити рядок або масив?
апсилери

3
Якщо в (n, m) є 1 (стінка), код повинен повертати 0?
трихоплакс

3
(Те саме для стіни за адресою (0,0)?)
Мартін Ендер

3
Ви кажете, що це × m лабіринт, але ваше індексація означає, що це (n + 1) × (m + 1) лабіринт.
Нік Маттео

3
Я з нетерпінням чекаю рішення регулярного
виразу

Відповіді:


7

CJam, 42 41 39 36 35 байт

Wq3>~_s,{{[{_2$+0<{e<_}*}*]}%z}*sW=

Виходячи з ідей цієї відповіді .

4 байти завдяки оптимізатору.

Формат введення:

[[0 0 0 0 0 0 1] [0 0 0 0 0 1 0] [0 0 0 0 1 0 0] [1 0 0 0 0 0 0]]

@Optimizer Дякую за це. Але тоді я знайшов коротший шлях ...
jimmy23013

1
q2Wts~_s,{{[{_2$+0<{e<_}*}*]}%z}*sW=- 36. Хоча передбачається, що перші три символи вводу будуть[[0
Оптимізатор

7

Діалог APL, 27 символів

⊃⌽∨.∧⍨⍣≡1≥+/¨|∘.-⍨,(~×⍳∘⍴)⎕

оцінений вхід. APL розрізняє матрицю і вектор векторів. Ця програма передбачає, що вхід є матрицею.

(~×⍳∘⍴)Aє виделкою, еквівалентною (~A) × ⍳⍴A. Потрібно уникати згадування двічі або введення змінної.

⍴Aце форма A. Для матриці 4 на 7 форма є 4 7.

є генератором індексів. ⍳4є 1 2 3 4. ⍳4 7- це вектори, (1 1)(1 2)...(4 7)розташовані в матриці 4 на 7.

~Aгортає шматочки A.

×помноживши ⍳⍴Aна перевернуті біти, ми зберігаємо координати всіх вільних комірок і перетворюємо всі стінки на 0 0.

,розгортає матрицю пар координат, тобто лінеаризує її у вектор. У цьому випадку вектор буде складатися з пар.

∘.-⍨Aабо A∘.-Aвіднімати елементи Aпопарно. Зауважимо, що тут елементи Aсамих пар.

| абсолютне значення

+/¨підсумовуйте кожну пару абсолютних значень. Це дає нам відстані сітки між кожною парою комірок у лабіринті, окрім стін.

1≥нас цікавлять лише сусіди на відстані не більше 1, це також виключає стіни. Тепер у нас є матриця суміжності графіка.

∨.∧⍨⍣≡ Флойд - алгоритм транзитивного закриття Варшалла

(f⍣n)A(не використовується тут), де nціле число - це оператор електроенергії. Це відноситься fдо A nчасу: f f ... f A.

(f⍣g)Aде gфункція - це оператор нерухомої точки, він же "обмеження потужності". Він продовжує обчислення серії A, f A, f f A, ... до ((f⍣i)A) g ((f⍣(i+1))A)повернення вірно для деяких i. У цьому випадку ми використовуємо match ( ) як g.

∨.∧⍨Aабо A∨.∧Aє кроком в алгоритмі Флойда. f.gє узагальненням матричного множення ( +.×), тут ми використовуємо сполучник ( ) і диз'юнкцію ( ) замість +і ×.

⊃⌽ Після ⍣≡того, як достатньо разів застосували крок і досягли стабільного стану, ми повинні шукати верхній правий кут матриці, щоб отримати результат, тому перевертаємо його ( ) і беремо перший, лівий верхній елемент ( ).

Візуалізація ⍣≡кроків Росії


5

Пітон, 164 байти

def s(a):
 d=[(0,0)]
 while d:i,j=d.pop();a[i][j]=2;d+=[(x,y)for x,y in[(i-1,j),(i,j-1),(i+1,j),(i,j+1)]if len(a[0])>y>-1<x<len(a)and a[x][y]<1]
 return a[-1][-1]>1

Я неохоче публікував це, оскільки це практично, як я зазвичай роблю заливку, просто злегка гольфуючи. Але ось це все одно.


4

Perl, 73 байти

69 байт коду + 4 байти для -n0E(не впевнений, як теги де підраховували в 2014 році, тому я порахував їх за 4 замість 2, але це не має великого значення).

/.*/;s/(^0|A)(.{@{+}})?0/A$2A/s||s/0(.{@{+}})?A/A$1A/s?redo:say/A$/+0

Спробуйте в Інтернеті! (і якщо ви заміните 1111011рядок на 1111111, лабіринт вже не вирішується, а вихід буде 0замість 1: Спробуйте в Інтернеті! )

Пояснення:

Цей код знайде кожну досяжну клітинку лабіринту (і позначимо їх а A): якщо клітина торкається клітини, позначеної символом a A, вона є доступною, і ми також її позначаємо A; і робимо це знову ( redo). Це робиться завдяки двом регулярним виразам: s/(^0|A)(.{@{+}})?0/A$2A/sперевіряє, чи пробіл знаходиться праворуч або внизу A, а s/0(.{@{+}})?A/A$1A/sперевіряється, чи пробіл знаходиться зліва чи вгорі A. Зрештою, якщо останній осередок містить Aце були досяжні, інакше це не (це те, що say/A$/+0чеки, а +0тут , щоб переконатися , що результат буде 0або 1замість порожнього рядка і 1).
Зверніть увагу, що це /.*/буде відповідати цілому рядку, таким чином налаштовуючи@+до індексу кінця першого рядка, який буває розміром рядка, які дозволяють використовувати, щоб використовувати, .{@{+}}щоб відповідати рівно стільки символів, скільки їх є на рядку. ( @{+}еквівалентно @+, але в регулярному вираженні можна використовувати лише колишній)


У цьому тестовому випадку ваш код вважає лабіринт вирішеним, навіть якщо є остаточне положення 1.
Jitse

@Jitse Хороший улов. Насправді, це було тому, що посилання TIO не використовували правильний код (я думаю, це була якась більш рання версія, і я її не помітив). Відповідь все ще справедлива, і я оновив посилання TIO. Ваш приклад працює тоді чудово: Спробуйте в Інтернеті!
Дада

О, так! Дякую за роз’яснення, мені подобається такий підхід.
Jitse

@Jitse дякую, це один з моїх улюблених гольфів :)
Дада

3

Рубі, 133 130 129 символів

a=eval gets
f=->x,y{a[x][y]=1
[[-1,0],[1,0],[0,-1],[0,1]].map{|o|d,e=x+o[0],y+o[1]
f[d,e]if a[d]&&a[d][e]==0}}
f[0,0]
p a[-1][-1]

Вхід на STDIN, виходи 1або 0на STDOUT.

Дратівливо довго. Він просто заповнює заливку 1s (0, 0), а потім перевіряє, чи є "кінцевим" квадрат a 1.


Чи вважатиме це лабіринт розв'язуваним, якщо він вже містить 1 at (n, m)?
трихоплакс

2

Java, 418 байт

import java.util.Scanner;public class Solvable{static int w,h;public static void main(String[] a){String[]i=new Scanner(System.in).nextLine().split(";");h=i.length+2;w=i[0].length()+2;int[]m=new int[w * h];for(int x=1;x<w-1;x++)for(int y=1;y<h-1;y++)m[y*w+x]=i[y-1].charAt(x-1)<'.'?0:1;f(m,w+1);System.out.println(m[w*h-w-2]>0?0:1);}static void f(int[]m,int i){if(m[i]>0){m[i]--;f(m,i-1);f(m,i+1);f(m,i-w);f(m,i+w);}}}

Мій перший гольф-код. Я не знаю, чому я вибрав Java - це так погано для гольфу в xD

Приклад лабіринту буде введено через stdin так:

......#;.....#.;....#..;#......

1
Підказка: назвіть своєму класу щось, що має один символ, і вирийте пробіл між String[]іa та заберіть аргументи командного рядка, а не StdIn, що дозволено.
Павло

1

Пітон 184 188

def f(a,x=0,y=0,h=[]):s=h+[[x,y]];X,Y=len(a[0]),len(a);return([x,y]in h)==(x>=X)==(y>=Y)==(x<0)==(y<0)==a[y][x]<(x==X-1and y==Y-1or f(a,x-1,y,s)|f(a,x+1,y,s)|f(a,x,y-1,s)|f(a,x,y+1,s))

Це стало набагато довше, ніж я думав, що це буде :( У будь-якому разі, я додам пояснення, як тільки більше не можу гольфу.


1

J, 75 символів

Підключення матриці суміжності (неефективний час і пам'ять). (Це англійською мовою називається живлення?)

   ({.@{:@(+./ .*.^:_~)@(+:/~@,*2>(>@[+/@:|@:->@])"0/~@,@(i.@#<@,"0/i.@#@|:)))

Деякі тестові випадки:

   m1=. 0 0 0 0 0 0 1,. 0 0 0 0 0 1 0,.  0 0 0 0 1 0 0,. 1 0 0 0 0 0 0
   m2=. 0 1 1 ,. 0 0 0
   m3=. 0 1 0 ,. 1 1 0
   m4=. 0 1 1 0 ,. 0 0 1 0
   ({.@{:@(+./ .*.^:_~)@(+:/~@,*2>(>@[+/@:|@:->@])"0/~@,@(i.@#<@,"0/i.@#@|:))) every m1;m2;m3;m4
1 1 0 0


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.