8
votes

Détermination de la valeur basée sur des cellules adjacentes dans la matrice

entrée: strong> Un labyrinthe représenté par une matrice de taille arbitraire de bools. (Hors limites compte comme 0)

   ┌─┐
   │1│
  ┌┘1└┐
 ┌┘111└┐
 |11111|
 └┐111┌┘
  └┐1┌┘
   └─┘


4 commentaires

Une table de recherche serait la manière typique d'aller ici, bien que de travailler à partir d'un tableau de Bool nécessite un peu de twiddling. Je ne suis pas absolument clair sur la substitution, mais cela semble être 1-> 1 tandis que 0 -> {une valeur de 4 bits}, il pourrait donc y avoir une portée de compression. Comme R Pate dit ci-dessous, cependant, cela ne semble guère de la peine.


Vous êtes correct sur la partie de substitution (1-> 1 pendant 0 -> une valeur de 4 bits}). Et oui, je vais bien sûr devoir retourner sur la solution plus simple, mais je suis vraiment curieux de voir s'il y a un meilleur ...


Comment un 0 entouré de 1s de tous les côtés ressemblerait-il à la sortie?


Bonne question ... Je crois que "┼ 'serait la seule option appropriée.


7 Réponses :


1
votes

Vous pouvez le gérer en regardant certaines cellules avant d'autres, mais honnêtement, 256 n'est pas si nombreux. Écrivez un programme qui les génère ou le fait à la main et utilisez une table de recherche, les 256 octets supplémentaires (vous pouvez faire la carte de recherche à un autre index pour obtenir le caractère actuel) est suffisamment faible pour ne pas vous inquiéter.


2 commentaires

Oui, c'est ce que j'étais sur le point de faire quand je pensais "... Il doit y avoir une meilleure façon de faire ça ...". Donc, fondamentalement, ce que vous dites, c'est qu'il n'y a pas?


Je ne dis pas qu'il n'y a pas une belle formule mathématique que vous pouvez utiliser, je ne dis que des tables de recherche sont en fait élégantes! Pour un, ils sont faciles à comprendre et à résoudre facilement, et vous ferez de la résolution de problèmes réels (TM) au lieu de vous gratter la tête.



0
votes

Si vous trouvez pour la première fois quelles carreaux sont des murs, cochez un cas spécial pour chaque type de mur que vous avez, comme étant vertical s'il y a une sur la gauche et / ou la droite, mais aucune en haut ou en bas. < / p>

qui devrait le réduire un peu, j'espère. :) Vertical, horizontal et quatre bords différents. C'est 6 cas une fois que vous avez détecté lesquels sont des bords du tout.

moins de 256 au moins. :)


1 commentaires

Je ne peux pas vraiment suivre comment cela fonctionnerait .. Pourriez-vous fournir un exemple de code ou pseudo-algorithme?



1
votes

Au lieu de numériser chaque ligne pour un 1 et de dessiner chaque cellule, vous pouvez "marcher" les murs.

Bien que pas à la fin de votre réseau BOOL: p>

  • Scannez jusqu'à ce que vous trouviez un 1 li> ul>

    Définir une fonction appelée "Draw" qui: p>

    • dessine chaque adjacent 0 (ou hors limites) comme un mur li>
    • Modifiez le courant de 1 à A 3 (cela vous obligerait à utiliser autre chose qu'un tableau de bools) li>
    • Basculez le curseur actuel sur un 1 adjacent
      • recueille dans "Draw" LI> ul> li>
      • Si aucun adjacent aussi adjacent n'existe, retournez du tirage au sort. de mur. li> ul>

        -Pon retour, reprenez Scan jusqu'à la prochaine ou la fin de l'entrée. P>

        Peut-être pas le plus efficace, mais vous avez dit élégant. Récursion est toujours élégante! (Jusqu'à ce que vous obteniez un piquantflow qui est). p>

        Voici un code piraté de sortie (n'utilisez pas de nombres magiques comme je l'ai fait :)) Pour vous aider à sortir: P>

        0 1 0
        0 1 1
        0 1 0 
        


3 commentaires

Cela semble prometteur. Bien que après un test sur mon papier, je me suis très confus sur l'opération. Comment puis-je dessiner exactement les 0 sur des murs? Comment gérerais-je les coins? Qu'en est-il du 0 partage par plus d'un 1 ?


Donc, je devrais toujours créer manuellement une table de verrouillage de taille 256 de taille 256?


Oui, je ne pense pas que ce soit évitable.



0
votes

juste un piratage rapide. À l'aide d'un tableau 3x3 et de certains arithmétiques modulo, vous pourriez probablement réduire beaucoup le nombre d'accès à la mémoire, mais cela pourrait sembler moche. AVERTISSEMENT Je ne l'ai pas exécuté à travers un compilateur afin qu'il puisse contenir des fautes de frappe.

wchar_t maze_wall(int** input,int rows, int cols){

   wchar_t** output;
   int i,j;
   int N,E,S,W,NE,SE,NW,SW;

   output = (wchar_t**) malloc(sizeof(wchar_t*)*rows);
   for(i=0;i<cols;i++)
      output[i]= (wchar_t*) malloc(sizeof(wchar_t)*cols);
   for(i=0;i<rows;i++){
      for(j=0;j<cols;j++){
        if(input[i][j] ==1)
           {output[i][j] = '1'; continue;}
        N=E=S=W=NE=SE=NW=SW=0;
        if(i != 0) /*We are not at the top*/
           N = input[i-1][j];
        if(i != rows-1) /* We are not at the bottom*/
          S = input[i+1][j];
        if(j != rows-1) /* We are not at the right side*/
          E = input[i][j+1];
        if(j != 0) /* We are not at the left side*/
          W = input[i][j-1];
      /*Expand this for the corners*/

      if(N+E+S+W+NE+SE+SW+NE+NW == 0)
          {output[i][j] = ' '; continue;}

      /*Fill it in for the other six cases {'└', '┐', '┌', '┘', '-', '|'} */
      } 
   }
   return output; 
}  


0 commentaires

2
votes

inspiré de Doug T. La solution que j'ai écrite moi-même. Fondamentalement, je passe à travers la matrice deux fois (performances médiocres: /). La première fois que je dessinerai des murs autour de chaque 1 code> dans la matrice, je le fais avec des masques bit. La deuxième fois que je nettoie tous les "Points intérieurs" -walls.

Exemple de configuration: p> xxx pré>

la boucle de murs: p> xxx pré>

la boucle de nettoyage: P>

map<unsigned int, wchar_t> p;
p[0] = ' ';
p[N] = '.';
// ...
p[N|S] = L'\u2502'; // │
p[E|W] = L'\u2500'; // ─
// ...
p[N|E|S|W] = L'\u253C'; // ┼


0 commentaires

2
votes

J'ai implémenté cela dans Mon entrée gagnante pour l'ICOCC 2004. Je suis sûr que vous trouverez le code bien documenté et facile à suivre.

Si vous voulez juste la réponse, si je me souviens, l'approche que j'ai prise était de calculer un bitmap de cellules occupées entourant chaque cellule et d'utiliser cela comme un index dans une gamme de caractères muraux (ou de manière équivalente, des glyphes). Si, comme ma solution, vous ne permettez pas de déplacement diagonal, le bitmap est de 4 bits de long, et donc la matrice a 2 ^ 4 = 16 éléments. Si vous autorisez les déplacements en diagonale, vous avez besoin d'un bitmap 8 bits et de 256 entrées.


0 commentaires

1
votes

première exécution via la matrice en ajoutant la matrice de noyau suivante, centrage du 0 code> du noyau sur chaque 1 code> et ajoute les chiffres aux carrés adjacents (c'est-à-dire de faire une représentation binaire de tous les voisins).

s = s_ij  # the sum at the location of interest
if not s & 16:  # never write a symbol over a 1
    if s & 8 and not (s & 128 or s & 2): 
        c = "|"
    elif s ==128:
        c = “┌─┐”
    # etc


1 commentaires

Je pense qu'il y a beaucoup moins. Prenant votre exemple, il y a 5 formes mais 12 motifs binaires uniques. Et autre que ce que vous avez déjà montré, quelles formes supplémentaires auront besoin? Une barre horizontale, éventuellement les huit formes de L, et c'est à peu près tout, non? 14 formes totales. (Ou peut-être que j'ai manqué quelques-uns, mais probablement pas 242.)