Maison interface Web js tutoriel Fragments de disque

Fragments de disque

Jan 03, 2025 am 08:38 AM

Disk Fragmenter

Avènement du Code 2024 Jour 9

Partie 1

Un gant en trois phases. Passionnant!??

Les phases telles que je les vois énoncées :

  1. Représenter la mémoire sous forme de liste
  2. Déplacer les valeurs de la fin au début
  3. Parcourir la ligne pour calculer la somme de contrôle

Rien de tout cela ne semble particulièrement difficile.

Et certains d'entre eux semblent être encore un autre défi algorithmique amusant !

Faire la liste

Je veux transformer ceci :

12345
Copier après la connexion
Copier après la connexion
Copier après la connexion

Dans ceci :

0..111....22222
Copier après la connexion
Copier après la connexion
Copier après la connexion

Je dois considérer :

  • Utiliser une boucle
  • Vérification des indices pairs et impairs
  • Incrémenter une valeur de 1, en partant de 0

Voici mon algorithme de génération de disque :

let id = 0
let disk = []
for (let i = 0; i < input.length; i++) {
    if (i % 2 == 1) {
        // Odd
        for (let j = 0; j < +input[i]; j++) {
            disk.push('.')
        }
    } else {
        // Even 
        for (let j = 0; j < +input[i]; j++) {
            disk.push(id)
        }
        id++
    }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

Fonctionne à merveille !

Déplacer les valeurs de la fin au début

Ce qui rendrait cela plus facile, c'est d'avoir une liste de tous les emplacements vides sur le disque.

Je dois mettre à jour mon algorithme à deux endroits :

  1. Une nouvelle variable : laisser vide = []
  2. Une nouvelle action après l'insertion d'un .: empty.push(disk.length - 1)

Le tester sur l'exemple montre les numéros d'index attendus de chacun.!

C'est la liste que je vais parcourir en déplaçant les valeurs de la fin de la liste au début et au-delà.

Mais attendez.

Cela pourrait être plus difficile que je ne le pensais.

Comment saurai-je quand arrêter d'essayer de déplacer des valeurs ?

  • Est-ce que je parcourt la liste des index vides ? Quand dois-je arrêter ?
  • Est-ce que je parcourt les disques en arrière ? Quand dois-je arrêter ?

Une révélation : le chiffre magique 10

Voici le dernier état du court exemple :

022111222......
Copier après la connexion
Copier après la connexion

Et du premier exemple :

0099811188827773336446555566..............
Copier après la connexion
Copier après la connexion

Ce qui signifie qu'il arrive un moment où tous les identifiants sont à gauche et tous les espaces vides sont à droite.

Comment puis-je vérifier cet état ?

Entrez : le chiffre 10.

Le nombre d'espaces vides contigus ne sera jamais supérieur à 9.

Donc, si je tombe sur un espace vide, que j'attends 9 espaces (ou la fin de la liste des disques) et que je vois tous les espaces vides, je sais que j'aurai fini de fragmenter.

Je pense savoir comment écrire le reste de cet algorithme !

Écrire mon algorithme de fragmentation

Voici l'algorithme de travail :

let diskI = disk.length - 1
let emptyI = 0
while (true) {
    while (disk[diskI] == '.') {
        diskI--
    }
    disk[empty[emptyI]] = disk[diskI]
    disk[diskI] = '.'
    emptyI++
    diskI--
    if (disk.slice(empty[emptyI],empty[emptyI] + 10).every(el => el == '.')) {
        break;
    }
}
Copier après la connexion
Copier après la connexion

Comment ça marche :

Two trackers: 
- one for my place in the disk
- one for my place in the list of empty slots
Do until manually escaped
  Do as long as the current place in the disk is an empty slot
    Adjust the tracker one to the left
  Swap the values at each tracker
  Decrement the disk tracker
  Increment the empty tracker
  If there are 9 empty slots contiguous with the current empty slot
    Escape the loop
Copier après la connexion
Copier après la connexion

Heureusement, je vois le même résultat que dans les deux exemples !

Calcul de la somme de contrôle

Cela semble assez simple et direct :

let part1 = disk.slice(0, disk.indexOf('.')).reduce((checksum, id, position) => {
    checksum += (+id * position)
    return checksum
}, 0)
Copier après la connexion
Copier après la connexion

En pseudocode :

Extract all values up to the first empty cell
Iterate through each value, amassing a total
Increment the accumulator by the product of the value and its index
Copier après la connexion
Copier après la connexion

Succès ! Il génère la réponse correcte pour l'exemple d'entrée !

Est-ce que cela fera la même chose pour ma saisie de puzzle ?

...

OUI !!!

Woohoo!!!

Quelle sera la tournure de la deuxième partie ? Un léger ajustement des règles ou un défi d’échelle ?

Partie 2

Une tournure intéressante

Il y avait des pièces. Maintenant entier.

Cela nécessitera certainement quelques ajustements de mon algorithme.

Suivi probablement plus robuste de la taille des espaces et des blocs.

Travailler sur ma première stratégie

Je suivi où se trouvait chaque vide.

Je pense que je dois savoir où - et quelle est la taille - de chaque vide.

À quoi cela ressemblerait-il ?

Grattez ça. Peut-être une nouvelle stratégie.

En utilisant le premier exemple :

12345
Copier après la connexion
Copier après la connexion
Copier après la connexion

Les tailles des blocs de fichiers sont les nombres impairs :

0..111....22222
Copier après la connexion
Copier après la connexion
Copier après la connexion

Les tailles de cellules vides sont les nombres pairs :

let id = 0
let disk = []
for (let i = 0; i < input.length; i++) {
    if (i % 2 == 1) {
        // Odd
        for (let j = 0; j < +input[i]; j++) {
            disk.push('.')
        }
    } else {
        // Even 
        for (let j = 0; j < +input[i]; j++) {
            disk.push(id)
        }
        id++
    }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion

En partant de la fin des nombres impairs et du début des nombres pairs, je recherche un nombre pair supérieur ou égal au nombre impair :

022111222......
Copier après la connexion
Copier après la connexion

Je trouve immédiatement une correspondance.

En conséquence :

  • Le nombre impair bouge
  • Le nombre pair diminue
  • Mais maintenant les deux nombres impairs n'ont plus d'écart
  • Et j'ai perdu la deuxième pièce d'identité 2s
0099811188827773336446555566..............
Copier après la connexion
Copier après la connexion

Cette stratégie ne fonctionnera certainement pas.

Travailler sur ma deuxième stratégie

Je n'aime pas les implications de celui-ci en termes de performances.

Mais j'espère que cela fonctionnera... tant qu'il aura fini de fonctionner.

Pour chaque numéro dans l'entrée disque, j'enregistrerai comme élément de liste :

  1. Bloc de fichiers ou cellule vide
  2. Longueur
  3. Pièce d'identité

À titre d'exemple :

let diskI = disk.length - 1
let emptyI = 0
while (true) {
    while (disk[diskI] == '.') {
        diskI--
    }
    disk[empty[emptyI]] = disk[diskI]
    disk[diskI] = '.'
    emptyI++
    diskI--
    if (disk.slice(empty[emptyI],empty[emptyI] + 10).every(el => el == '.')) {
        break;
    }
}
Copier après la connexion
Copier après la connexion

Deviendra :

Two trackers: 
- one for my place in the disk
- one for my place in the list of empty slots
Do until manually escaped
  Do as long as the current place in the disk is an empty slot
    Adjust the tracker one to the left
  Swap the values at each tracker
  Decrement the disk tracker
  Increment the empty tracker
  If there are 9 empty slots contiguous with the current empty slot
    Escape the loop
Copier après la connexion
Copier après la connexion

Ew, nettoyons ça :

let part1 = disk.slice(0, disk.indexOf('.')).reduce((checksum, id, position) => {
    checksum += (+id * position)
    return checksum
}, 0)
Copier après la connexion
Copier après la connexion

Je distinguerai les lacunes des blocs de fichiers en fonction du type de données.

Le déplacement de blocs de fichiers ressemblera à ceci dans un exemple d'entrée modifié :

Extract all values up to the first empty cell
Iterate through each value, amassing a total
Increment the accumulator by the product of the value and its index
Copier après la connexion
Copier après la connexion

Cela impliquera dans chaque 100 000 itérations :

  • Recherche d'éléments dans un large éventail
  • Muter un tableau sur place

Les deux sont des tâches très coûteuses.

Mais c'est la seule façon à laquelle je peux penser pour résoudre cette énigme.

Donc, ce sera mon approche.

Codifier ma stratégie

Voici le JavaScript qui me permet d'obtenir l'architecture de données ci-dessus :

2333133121414131402
Copier après la connexion

Comment vais-je commencer et terminer ma boucle principale ?

Essayez de déplacer chaque fichier exactement une fois par ordre décroissant de numéro d'identification de fichier en commençant par le fichier avec le numéro d'identification de fichier le plus élevé

On dirait que passer de l'arrière vers l'avant fera ce dont j'ai besoin.

Ce squelette de boucle for devrait fonctionner :

[2,4,1,4,2,5,5,3,5,2]
Copier après la connexion
Rechercher, déplacer et remplacer
[3,3,3,1,1,1,1,1,0]
Copier après la connexion

Cette deuxième clause du if était mon dernier débogage. Cela mettait les identifiants les plus bas trop tôt.

Codage d'une imprimante à disque

J'ai réalisé que je devais voir mon disque se fragmenter en temps quasi réel. Au moins un journal, comme dans l'exemple de procédure pas à pas.

Heureusement, le coder n’a pas été difficile. Juste la partie où j'ai mélangé deux indices et vu un résultat vraiment bizarre :

12345
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • Je construis une chaîne
  • Basé sur le type d'élément sur le disque
  • Quoi qu'il en soit, je crée un tableau et le remplis avec .s ou l'ID du bloc

Ça marche très bien ! Je pouvais voir où les fichiers étaient déplacés et dépanner mon code beaucoup plus facilement !

J'aime ce que je vois
0..111....22222
Copier après la connexion
Copier après la connexion
Copier après la connexion

On dirait que mon algorithme de déplacement de fichiers fonctionne !

La dernière étape consiste à calculer la nouvelle somme de contrôle.

Enfin, plus de maths

En guise de double réduction :

let id = 0
let disk = []
for (let i = 0; i < input.length; i++) {
    if (i % 2 == 1) {
        // Odd
        for (let j = 0; j < +input[i]; j++) {
            disk.push('.')
        }
    } else {
        // Even 
        for (let j = 0; j < +input[i]; j++) {
            disk.push(id)
        }
        id++
    }
}
Copier après la connexion
Copier après la connexion
Copier après la connexion
  • La première réduction me donne un tableau étendu d'identifiants et de .s
  • La deuxième réduction effectue les calculs appropriés lorsque l'élément est un identifiant et aucun calcul lorsqu'il s'agit d'un .

Est-ce que ça marche ?

Sur l'exemple de saisie de puzzle ? OUI !

Sur ma contribution au puzzle ?

...

OUIESSSSSS !

Wow. Je suis surpris. Le nombre que j'ai soumis pour la partie 2 est presque identique à celui de la partie 1. Je pensais qu'il serait plus élevé.

Je ne suis pas intéressé à enquêter davantage.

Je préfère prendre mes deux étoiles d'or durement gagnées et marcher jusqu'au jour 10.

Au revoir, jour 9 !

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!

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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

<🎜>: Grow A Garden - Guide de mutation complet
3 Il y a quelques semaines By DDD
<🎜>: Bubble Gum Simulator Infinity - Comment obtenir et utiliser les clés royales
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Système de fusion, expliqué
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Whispers of the Witch Tree - Comment déverrouiller le grappin
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Tutoriel Java
1670
14
Tutoriel PHP
1276
29
Tutoriel C#
1256
24
Python vs JavaScript: la courbe d'apprentissage et la facilité d'utilisation Python vs JavaScript: la courbe d'apprentissage et la facilité d'utilisation Apr 16, 2025 am 12:12 AM

Python convient plus aux débutants, avec une courbe d'apprentissage en douceur et une syntaxe concise; JavaScript convient au développement frontal, avec une courbe d'apprentissage abrupte et une syntaxe flexible. 1. La syntaxe Python est intuitive et adaptée à la science des données et au développement back-end. 2. JavaScript est flexible et largement utilisé dans la programmation frontale et côté serveur.

De C / C à JavaScript: comment tout cela fonctionne De C / C à JavaScript: comment tout cela fonctionne Apr 14, 2025 am 12:05 AM

Le passage de C / C à JavaScript nécessite de s'adapter à la frappe dynamique, à la collecte des ordures et à la programmation asynchrone. 1) C / C est un langage dactylographié statiquement qui nécessite une gestion manuelle de la mémoire, tandis que JavaScript est dynamiquement typé et que la collecte des déchets est automatiquement traitée. 2) C / C doit être compilé en code machine, tandis que JavaScript est une langue interprétée. 3) JavaScript introduit des concepts tels que les fermetures, les chaînes de prototypes et la promesse, ce qui améliore la flexibilité et les capacités de programmation asynchrones.

Javascript et le web: fonctionnalité de base et cas d'utilisation Javascript et le web: fonctionnalité de base et cas d'utilisation Apr 18, 2025 am 12:19 AM

Les principales utilisations de JavaScript dans le développement Web incluent l'interaction client, la vérification du formulaire et la communication asynchrone. 1) Mise à jour du contenu dynamique et interaction utilisateur via les opérations DOM; 2) La vérification du client est effectuée avant que l'utilisateur ne soumette les données pour améliorer l'expérience utilisateur; 3) La communication de rafraîchissement avec le serveur est réalisée via la technologie AJAX.

JavaScript en action: Exemples et projets du monde réel JavaScript en action: Exemples et projets du monde réel Apr 19, 2025 am 12:13 AM

L'application de JavaScript dans le monde réel comprend un développement frontal et back-end. 1) Afficher les applications frontales en créant une application de liste TODO, impliquant les opérations DOM et le traitement des événements. 2) Construisez RestulAPI via Node.js et Express pour démontrer les applications back-end.

Comprendre le moteur JavaScript: détails de l'implémentation Comprendre le moteur JavaScript: détails de l'implémentation Apr 17, 2025 am 12:05 AM

Comprendre le fonctionnement du moteur JavaScript en interne est important pour les développeurs car il aide à écrire du code plus efficace et à comprendre les goulots d'étranglement des performances et les stratégies d'optimisation. 1) Le flux de travail du moteur comprend trois étapes: analyse, compilation et exécution; 2) Pendant le processus d'exécution, le moteur effectuera une optimisation dynamique, comme le cache en ligne et les classes cachées; 3) Les meilleures pratiques comprennent l'évitement des variables globales, l'optimisation des boucles, l'utilisation de const et de locations et d'éviter une utilisation excessive des fermetures.

Python vs JavaScript: communauté, bibliothèques et ressources Python vs JavaScript: communauté, bibliothèques et ressources Apr 15, 2025 am 12:16 AM

Python et JavaScript ont leurs propres avantages et inconvénients en termes de communauté, de bibliothèques et de ressources. 1) La communauté Python est amicale et adaptée aux débutants, mais les ressources de développement frontal ne sont pas aussi riches que JavaScript. 2) Python est puissant dans les bibliothèques de science des données et d'apprentissage automatique, tandis que JavaScript est meilleur dans les bibliothèques et les cadres de développement frontaux. 3) Les deux ont des ressources d'apprentissage riches, mais Python convient pour commencer par des documents officiels, tandis que JavaScript est meilleur avec MDNWEBDOCS. Le choix doit être basé sur les besoins du projet et les intérêts personnels.

Python vs JavaScript: environnements et outils de développement Python vs JavaScript: environnements et outils de développement Apr 26, 2025 am 12:09 AM

Les choix de Python et JavaScript dans les environnements de développement sont importants. 1) L'environnement de développement de Python comprend Pycharm, Jupyternotebook et Anaconda, qui conviennent à la science des données et au prototypage rapide. 2) L'environnement de développement de JavaScript comprend Node.js, VScode et WebPack, qui conviennent au développement frontal et back-end. Le choix des bons outils en fonction des besoins du projet peut améliorer l'efficacité du développement et le taux de réussite du projet.

Le rôle de C / C dans les interprètes et compilateurs JavaScript Le rôle de C / C dans les interprètes et compilateurs JavaScript Apr 20, 2025 am 12:01 AM

C et C jouent un rôle essentiel dans le moteur JavaScript, principalement utilisé pour implémenter des interprètes et des compilateurs JIT. 1) C est utilisé pour analyser le code source JavaScript et générer une arborescence de syntaxe abstraite. 2) C est responsable de la génération et de l'exécution de bytecode. 3) C met en œuvre le compilateur JIT, optimise et compile le code de point chaud à l'exécution et améliore considérablement l'efficacité d'exécution de JavaScript.

See all articles