Le labyrinthe peut-il être résolu?


20

Le puzzle

  • Imprimer 0 si un labyrinthe n * m ne peut pas être résolu
  • Imprimer 1 si un labyrinthe n * m peut être résolu (de 1 ou plusieurs façons)

(donc je ne demande pas de chemins mais s'il est possible de les résoudre !!!)

Tableau d'entrée (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

Règle La position de départ est 0,0 et la position de fin est n, m Vous ne pouvez vous déplacer qu'horizontalement et verticalement Les gains de code les plus courts


L'entrée doit-elle être une chaîne ou un tableau?
apsillers

3
S'il y a un 1 (mur) en (n, m) le code doit-il retourner 0?
trichoplax

3
(Idem pour un mur à (0,0)?)
Martin Ender

3
Vous dites que c'est un labyrinthe × m, mais votre indexation implique que c'est un labyrinthe (n + 1) × (m + 1).
Nick Matteo

3
J'attends la solution regex avec impatience =)
flawr

Réponses:


7

CJam, 42 41 39 36 35 octets

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

Basé sur les idées de cette réponse .

4 octets grâce à l'Optimizer.

Format d'entrée:

[[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 Merci pour cela. Mais j'ai trouvé un moyen plus court ...
jimmy23013

1
q2Wts~_s,{{[{_2$+0<{e<_}*}*]}%z}*sW=- 36. Bien qu'il suppose que les trois premiers caractères de l'entrée seront[[0
Optimizer

7

Dyalog APL, 27 caractères

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

entrée évaluée. APL fait la distinction entre une matrice et un vecteur de vecteurs. Ce programme suppose que l'entrée est une matrice.

(~×⍳∘⍴)Aest un fork équivalent à (~A) × ⍳⍴A. Il faut éviter de mentionner deux fois ou d'introduire une variable.

⍴Aest la forme de A. Pour une matrice 4 x 7, la forme est 4 7.

est le générateur d'index. ⍳4est 1 2 3 4. ⍳4 7est les vecteurs (1 1)(1 2)...(4 7)disposés dans une matrice 4 x 7.

~Aretourne les morceaux de A.

×en multipliant ⍳⍴Apar les bits inversés, nous préservons les coordonnées de toutes les cellules libres et transformons tous les murs en 0 0.

,défile la matrice de paires de coordonnées, c'est-à-dire la linéarise en un vecteur. Dans ce cas, le vecteur sera composé de paires.

∘.-⍨Aou A∘.-Asoustrait des éléments de Apaire. Notez qu'ici les éléments de Asont eux-mêmes des paires.

| valeur absolue

+/¨additionner chaque paire de valeurs absolues. Cela nous donne les distances de grille entre chaque paire de cellules dans le labyrinthe, à l'exception des murs.

1≥nous ne sommes intéressés que par des voisins à une distance ne dépassant pas 1, cela exclut également les murs. Nous avons maintenant une matrice d'adjacence de graphe.

∨.∧⍨⍣≡ Floyd - L'algorithme de fermeture transitive de Warshall

(f⍣n)A(non utilisé ici) où nest un entier est l'opérateur de puissance. Il applique fà A ntemps: f f ... f A.

(f⍣g)Agest une fonction, est l'opérateur à virgule fixe, alias "limite de puissance". Il continue à calculer la série A, f A, f f A, ... jusqu'à ce que le ((f⍣i)A) g ((f⍣(i+1))A)rendement vrai pour certains i. Dans ce cas, nous utilisons match ( ) as g.

∨.∧⍨Aou A∨.∧Aest une étape dans l'algorithme de Floyd. f.gest une généralisation de la multiplication matricielle ( +.×), nous utilisons ici la conjonction ( ) et la disjonction ( ) à la place de +et ×.

⊃⌽ Après ⍣≡avoir appliqué l'étape suffisamment de fois et atteint un état stable, nous devons rechercher le coin supérieur droit de la matrice pour obtenir le résultat.Nous le retournons donc ( ) et prenons le premier élément supérieur gauche ( ).

Visualisation des ⍣≡étapes de


5

Python, 164 octets

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

J'étais réticent à poster ceci parce que c'est pratiquement la façon dont je fais normalement le remplissage des inondations, juste un peu au golf. Mais le voici quand même.


4

Perl, 73 octets

69 octets de code + 4 octets pour -n0E(je ne sais pas comment les balises ont été comptées en 2014, donc je les ai comptées pour 4 au lieu de 2, mais cela n'a pas beaucoup d'importance).

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

Essayez-le en ligne! (et si vous remplacez la 1111011ligne par 1111111, le labyrinthe n'est plus résoluble et la sortie sera à la 0place de 1: Essayez-le en ligne! )

Explications:

Ce code trouvera toutes les cellules accessibles du labyrinthe (et les marquera avec un A): si une cellule touche une cellule marquée avec un A, elle est accessible et nous la marquons avec un Aaussi; et nous recommençons ( redo). Cela se fait grâce à deux expressions régulières: s/(^0|A)(.{@{+}})?0/A$2A/svérifie si un espace est à droite ou en bas de a A, tandis que s/0(.{@{+}})?A/A$1A/svérifie si un espace est à gauche ou en haut de a A. À la fin, si la dernière cellule contient un, Ail est accessible, sinon ce n'est pas le cas (c'est ce qui say/A$/+0vérifie; le +0est là pour s'assurer que le résultat sera 0ou 1au lieu d' une chaîne vide et 1).
Notez que /.*/correspondra à une ligne entière, définissant ainsi@+à l'index de la fin de la première ligne, qui se trouve être la taille d'une ligne, ce qui permet à use .{@{+}}de correspondre exactement à autant de caractères qu'il y en a sur une ligne. ( @{+}est équivalent à @+, mais seul le premier peut être utilisé dans l'expression régulière)


Pour ce cas de test , votre code considère le labyrinthe comme solvable même si la position finale est 1.
Jitse

@Jitse Bonne prise. En fait, c'était parce que les liens TIO n'utilisaient pas le bon code (je suppose que c'était une version antérieure et je ne l'ai pas repérée). La réponse est toujours valable et j'ai mis à jour les liens TIO. Votre exemple fonctionne bien: essayez-le en ligne!
Dada

Oh, c'est vrai! Merci pour la clarification, j'aime cette approche.
Jitse

@Jitse merci, c'est l'un de mes golfs préférés :)
Dada

3

Ruby, 133 130 129 caractères

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]

Entrée sur STDIN, sorties 1ou 0sur STDOUT.

Longtemps ennuyeux. Il effectue simplement un remplissage de 1s de (0, 0), puis vérifie si le carré "de fin" est un 1.


Est-ce que cela traitera le labyrinthe comme soluble s'il contient déjà un 1 at (n, m)?
trichoplax

2

Java, 418 octets

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);}}}

Mon premier golf de code. Je ne sais pas pourquoi j'ai choisi Java - c'est si mauvais pour le golf xD

Exemple de labyrinthe serait entré via stdin comme ceci:

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

1
Astuce de pro: nommez votre classe avec un caractère de long, abandonnez l'espace entre String[]et a, et prenez les entrées des arguments de ligne de commande plutôt que StdIn, ce qui est autorisé.
Pavel

1

Python 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))

Cela a pris beaucoup plus de temps que je ne le pensais :( Quoi qu'il en soit, j'ajouterai une explication une fois que je ne pourrai plus jouer au golf.


1

J, 75 caractères

Alimentation de la matrice d'adjacence (très temps et mémoire inefficaces). (Est-ce que cela s'appelle pouvoir en anglais?)

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

Quelques cas de test:

   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


0

Python 3 , 184 octets

f=lambda m,x=0,y=0,n=0:n<len(m)*len(m[0])and m[x][y]<1and((x,y)==(len(m)-1,len(m[0])-1)or any(0<=i<len(m)and 0<=j<len(m[0])and f(m,i,j,n+1)for i,j in[(x-1,y),(x,y-1),(x+1,y),(x,y+1)]))

Essayez-le en ligne!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.