Maison > interface Web > js tutoriel > Colinéarité résonante

Colinéarité résonante

Barbara Streisand
Libérer: 2024-12-29 14:02:18
original
988 Les gens l'ont consulté

Resonant Collinearity

Avènement du Code 2024 Jour 8

Partie 1

Je pense que je comprends. Puis-je le faire ?

Si je comprends bien :

  • Pour chaque paire de ligatures identiques
  • Trouvez le point X où une ligature est 1N et l'autre est 2N - où N est à une certaine distance de X
  • Tant qu'il se trouve dans les limites de la grille, comptez-le pour la réponse

Voici un visuel :

...........
...........
...X.......
...........
.....Y.....   <---1N from top X, 2N from bottom X
...........
.......Y...   <---2N from top X, 1N from bottom X
...........
.........X.
...........
Copier après la connexion
Copier après la connexion

C'est clair visuellement.

Comment pourrais-je le déterminer de manière algorithmique ?

Calcul algorithmique de 1N et 2N

Voici l'exemple de grille :

............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
Copier après la connexion
Copier après la connexion

Je vais me concentrer sur les 0 :

  • Il y en a quatre
  • Les coordonnées sont : 1,8, 2,5, 3,7, 4,4

En comparant les deux premiers :

1,8 vs. 2,5

1 row apart
3 col apart

2 possible antinodes:
0,11: 0 = min(1,2) - 1
3,2

For 0,11
0 = min(1,2) - 1
11 = ....
Copier après la connexion
Copier après la connexion

J'ai réalisé en écrivant que j'avais vraiment besoin de connaître la pente de la droite reliant la paire de points.

De cette façon, je peux savoir s'il faut ajouter ou soustraire de chaque axe pour déterminer où se trouve le ventre.

Rafraîchir ma mémoire sur la pente

La formule est :

(y2 - y1) / (x2 - x1)
Copier après la connexion
Copier après la connexion

Le résultat sera l'un de ces quatre :

  • > 0 signifie pente positive : vers le haut et vers la droite
  • < 0 signifie pente négative : vers le bas et vers la droite
  • 0 signifie ligne horizontale
  • L'infini signifie ligne verticale

Reprenons l'exemple :

1,8 and 2,5

(5 - 8) / (2 - 1) = -3 / 1 = -3
Copier après la connexion
Copier après la connexion

Quoi ? Une pente négative ? Non, cette droite a une pente positive !

Oh... je vois.

L'indexation des tableaux augmente, mais visuellement diminue.

Je dois compter les indices à l'envers.

Au lieu de comme ça :

0 ............
1 ........0...
2 .....0......
3 .......0....
4 ....0.......
5 ......A.....
6 ............
7 ............
8 ........A...
9 .........A..
  ............
  ............
  0123456789
Copier après la connexion
Copier après la connexion

Je dois compter comme ceci :

  ............
  ........0...
9 .....0......
8 .......0....
7 ....0.......
6 ......A.....
5 ............
4 ............
3 ........A...
2 .........A..
1 ............
0 ............
  0123456789
Copier après la connexion
Copier après la connexion

Cela devrait juste nécessiter un peu plus de mathématiques :

array length - current row/col index
Copier après la connexion

Je vais essayer.

Pour les 0 les plus élevés :

12 rows
Row index: 1
12 - 1 = 11

Column index: 8

Coordinates: 8,11
Copier après la connexion

Pour le 0 de la ligne suivante :

Row index: 2
12 - 2 = 10

Column index: 5

Coordinates: 5,10
Copier après la connexion

Et la pente :

(10 - 11) / (5 - 8)
   -1     /    -3
         1/3
Copier après la connexion

Une pente positive ! C'est exact !

Commencer à coder

Construire la liste des coordonnées de l'antenne

Un objet vide rempli d'une boucle for imbriquée :

let graph = input.split('\n').map(el => el.split(''))
let antennas = {}
for (let y = 0; y < graph.length; y++) {
  for (let x = 0; x < graph[0].length; x++) {
    if (graph[y][x] !== '.') {
      if (!(graph[y][x] in antennas)) {
        antennas[graph[y][x]] = []
      }
      antennas[graph[y][x]].push([graph.length - y,x])
    }
  }
}




<p>Crée cet objet pour l'exemple d'entrée :<br>
</p>

<pre class="brush:php;toolbar:false">{
  '0': [ [ 11, 8 ], [ 10, 5 ], [ 9, 7 ], [ 8, 4 ] ],
  A: [ [ 7, 6 ], [ 4, 8 ], [ 3, 9 ] ]
}
Copier après la connexion

Ça a l'air génial !

Ensuite, calcul de la pente.

Écrire un outil de recherche de ventre trop complexe

Ma fonction scope est simple :

function getScope(p1,p2) {
  return (p2[0] - p1[0]) / (p2[1] - p1[1])
}
Copier après la connexion

Il attend deux tableaux et renvoie la portée en utilisant les quatre coordonnées.

Je souhaiterai appeler cette fonction lors de la comparaison de toutes les paires de coordonnées de fréquence similaire.

Cette comparaison se produit dans cette boucle for super imbriquée :

for (let freq in antennas) {
  let f = antennas[freq]
  for (let i = 0; i < f.length; i++) {
    for (let j = i + 1; j < f.length; j++) {
      // Comparing two antennas of the same frequency
    }
  }
}
Copier après la connexion

Confirmer que cela fonctionne sur l'exemple d'entrée :

[ 11, 8 ] [ 10, 5 ]
[ 11, 8 ] [ 9, 7 ]
[ 11, 8 ] [ 8, 4 ]
[ 10, 5 ] [ 9, 7 ]
[ 10, 5 ] [ 8, 4 ]
[ 9, 7 ] [ 8, 4 ]
[ 7, 6 ] [ 4, 8 ]
[ 7, 6 ] [ 3, 9 ]
[ 4, 8 ] [ 3, 9 ]
Copier après la connexion

Neuf comparaisons. C'est vrai !

Et les périmètres pour chacun ?

Ceux-ci ont l'air bien aussi, heureusement.

Maintenant, la partie trop compliquée, je pense.

Gestion des quatre types de pente

Ils sont :

...........
...........
...X.......
...........
.....Y.....   <---1N from top X, 2N from bottom X
...........
.......Y...   <---2N from top X, 1N from bottom X
...........
.........X.
...........
Copier après la connexion
Copier après la connexion

Gérons ça.

C'est beaucoup, mais les subtilités sont importantes au sein de chaque clause :

............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
Copier après la connexion
Copier après la connexion

Heureusement, tous les ventres identifiés semblent correctement placés.

Ensuite, en excluant ceux qui sont hors limites

Exclure les ventres hors limites

Entrez...plus de conditions !

1,8 vs. 2,5

1 row apart
3 col apart

2 possible antinodes:
0,11: 0 = min(1,2) - 1
3,2

For 0,11
0 = min(1,2) - 1
11 = ....
Copier après la connexion
Copier après la connexion

Je vérifie si chaque coordonnée est comprise entre 0 et la longueur des lignes ou des colonnes.

Ensuite, au bas de chaque clause dans mon ventre-finder, j'appelle la fonction sur les deux nœuds possibles :

(y2 - y1) / (x2 - x1)
Copier après la connexion
Copier après la connexion

Et ma réponse sera la taille de mon ensemble valide.

Est-ce que cela fonctionne réellement ?

L'exécuter génère 12. Pas 14.

Pourquoi pas ?

...

Après quelques débogages, j'ai trouvé mon erreur :

1,8 and 2,5

(5 - 8) / (2 - 1) = -3 / 1 = -3
Copier après la connexion
Copier après la connexion

Je m'éloigne d'un dans mon affectation du rang. J'ai besoin d'une valeur de moins :

0 ............
1 ........0...
2 .....0......
3 .......0....
4 ....0.......
5 ......A.....
6 ............
7 ............
8 ........A...
9 .........A..
  ............
  ............
  0123456789
Copier après la connexion
Copier après la connexion

Cela corrige les choses.

J'en vois 14 maintenant.

Il est temps de l'exécuter sur mon entrée de puzzle.

...

Bonne réponse !!!

Cela a pris beaucoup plus de temps que prévu, mais je l'ai fait !

Je ne peux qu'imaginer ce que nécessitera la partie 2.

Avaler.

Partie 2

Ouais. Beaucoup plus de ventres à identifier.

Cela semble plus difficile, même si cela peut être un ajustement relativement simple.

Il est temps d'y réfléchir.

...

Entrer avec une faible confiance dans la génération de la bonne réponse

Principalement à cause de ce piège :

exactement en ligne avec au moins deux antennes de même fréquence

Je pense Je comprends ce critère.

Mon intuition est que tant qu'il y en a trois d'une fréquence donnée, les trois antennes sont également des ventres.

Si je me trompe, c'est probablement pour cela que ma réponse sera erronée : confondre une antenne avec un ventre.

Mais je pense avoir une stratégie pour identifier tous les nouveaux ventres.

Entrez : plus de boucles while pour parcourir les lignes

Mon algorithme actuel trouve les ventres à chaque extrémité de deux antennes.

Je veux plutôt marcher le long de la ligne dans les deux sens jusqu'à ce que je sois sur le point de sortir des limites.

Cela nécessitera une refactorisation.

Je suis prêt.

Voici ma condition mise à jour pour les lignes à pente positive :

  ............
  ........0...
9 .....0......
8 .......0....
7 ....0.......
6 ......A.....
5 ............
4 ............
3 ........A...
2 .........A..
1 ............
0 ............
  0123456789
Copier après la connexion
Copier après la connexion

Ce qui a changé :

  • J'effectue les mathématiques une fois à l'avance
  • À l'intérieur de la boucle while, j'ajoute la coordonnée, puis j'incrémente ou décrémente simplement chaque coordonnée du diff correspondant
  • La condition utilise ma fonction mise à jour qui renvoie un booléen au lieu d'ajouter automatiquement les coordonnées

Je devais faire ça pour chaque clause.

J'en ai légèrement raté une, ce qui m'a amené à obtenir une réponse décalée par 1 en utilisant l'exemple d'entrée et à voir une grille vraiment étrange, ce qui m'a aidé à diagnostiquer quelle clause fonctionnait mal.

Finalement, je l'ai fait fonctionner sur l'exemple d'entrée.

Ensuite, je l'ai exécuté sur mon entrée de puzzle.

Et...

J'ai généré la bonne réponse !!!

Je suis tellement fière de moi !

Et je suis tellement reconnaissant qu'il n'y ait pas eu de cas sournois dans ma contribution au puzzle !

Wow, il a fallu plusieurs jours de réflexion passive pour y parvenir.

En route vers une autre journée avec deux étoiles d'or durement gagnées.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal