Bug 3 conditions FOR imbriquées?

brucine Messages postés 17595 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 9 novembre 2024 - 6 juin 2024 à 11:22
brucine Messages postés 17595 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 9 novembre 2024 - 8 juin 2024 à 10:09

Bonjour,

La question a été posée récemment de générer ce qui a été qualifié d'alphabet mais qui est en fait l'ensemble des combinaisons de a à z(n).

Tout le monde sait que seul ce qui est inutile est indispensable, il n'était pas précisé dans la question si n doit avoir une valeur finie (sans quoi la question a encore moins de sens); dans l'affirmative, un certain nombre de logiciels de programmation véritable donnent facilement la solution, mais elle était posée en Batch.

Il existe plusieurs façons simples d'y obtenir le résultat pour n=1 ou 2, au delà, le code va devenir imbuvable puisqu'il est probable qu'il faille en écrire un spécifique pour chaque valeur de n.

Il existe aussi au rang 3 plusieurs manières de retourner toutes les lettres de l'alphabet, mais qu'il faudra ensuite imbriquer dans autant de boucles FOR.

Si, à nouveau, la question particulière est sans grand intérêt, celle générale des boucles l'est davantage.

Par exemple le code suivant me rend le résultat correct:
 

@echo off

Set Letters1=a b c d e f g h i j k l m n o p q r s t

FOR %%G in (%Letters1%) DO (
  FOR %%H in (%Letters1% %G%) DO (
    FOR %%I in (%Letters1% %H% %G%) DO (
    echo.%%G%%H%%I%
)
)
)

:END
pause

Mais quel que soit le contenu des boucles FOR, je me fais planter avec des résultats partiels aberrants dès que ma liste dépasse 20 items (je rajoute u).

Quelqu'un a l'explication et/ou le remède de ce comportement?

Merci.

A voir également:

2 réponses

brucine Messages postés 17595 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 9 novembre 2024 2 565
6 juin 2024 à 18:40

Commentaire d'étape, les boucles FOR plantent soit s'il y a plus de 31 tokens incluant le caractère final de retour chariot (ce n'est ici pas le cas, chacune de a à z vaut 26+1), soit s'il y a plus, cela ne s'invente pas, de 8191 bits cumulés et voilà pourquoi votre fille est muette: de a à t en 3 boucles 20x20x20=8000, de a à u 21x21x21=9261 dépasse le mur du son.

Les solutions ne sont pas simples, soit essayer de découper la syntaxe pour qu'elle s'applique successivement par exemple à la moitié des tokens, soit un contournement par des batchs annexes très savants qui feraient perdre à la démarche tout intérêt si tant est qu'elle en ait.

à suivre si j'ai le courage de m'y plonger...

0
brucine Messages postés 17595 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 9 novembre 2024 2 565
7 juin 2024 à 21:23

ça ne passionne visiblement pas les foules, mais je conclus moi-même au cas où quelqu'un aurait un problème similaire pas d'ailleurs forcément lié à une histoire d'alphabet.

En saucissonnant comme indiqué précédemment 3 suites de boucles FOR indépendantes pour dans la première les lettres de a à i, dans la seconde celles de j à r et dans la dernière celles de s à z, chacune fonctionne indépendamment mais on se fait planter quand on veut en afficher les résultats là aussi indépendamment.

Peu importe, c'est comme j'ai pensé précédemment et de façon incompréhensible les boucles FOR bien qu'indépendantes qui nous plantent: au lieu de les afficher à l'écran, balançons le contenu dans 3 fichiers alpha1.txt à alpha3.txt qui ne contiendront que les lettres et qu'on va afficher par autant de syntaxes TYPE.

Encore perdu, on se fait encore planter, moralité ce n'est pas la commande FOR qui est en cause mais la console dont l'affichage plante quoi qu'on fasse si on dépasse un certain nombre de caractères à afficher.

La seule solution est alors de concaténer les fameuses boucles dans un seul fichier texte qu'on ne pourra lire que par le bloc-notes, comme suit dans l'exemple de vouloir lister toutes les combinaisons de lettres de a à zzz.

@echo off
Setlocal EnableDelayedExpansion

:UN
FOR /L %%A in (97,1,122) DO (
    cmd /C exit %%A
    CALL echo.%%^=exitcodeAscii%% >> %~dp0alpha.txt
)

:DEUX
SET /A "number=number+1"
IF %number% GTR 26 GOTO TROIS
FOR /F "tokens=%number%" %%A IN ("a b c d e f g h i j k l m n o p q r s t u v w x y z") DO (
        SET first=%%A & CALL :PROCESS2
)
GOTO DEUX

:PROCESS2
SET first=%first:~0,-1%
FOR %%B IN (a b c d e f g h i j k l m n o p q r s t u v w x y z) DO SET second=%%B & ECHO.%first%!second! >> %~dp0alpha.txt
exit /b

:TROIS
Set Letters1=a b c d e f g h i j k l m n o p q r s t u v w x y z
FOR %%G in (%Letters1%) DO (
  FOR %%H in (%Letters1% %G%) DO (
    FOR %%I in (%Letters1% %H% %G%) DO (
    SET un=%%G & SET deux=%%H & SET trois=%%I & CALL :PROCESS3
)
)
)
GOTO RESULT

:PROCESS3
SET un=%un:~0,-1%
SET deux=%deux:~0,-1%
SET trois=%trois:~0,-1%
ECHO.%un%%deux%%trois% >> %~dp0alpha.txt
exit /b

:RESULT
notepad %~dp0alpha.txt

:END


 

0
PierrotLeFou
8 juin 2024 à 04:56

Je l'ai fait en Python en supposant qu'on pourrait se servir de quelques fichiers et seulement 3 boucles imbriquées.

J'avoue ne pas être bon en commandes batch. ...

-

from string import ascii_uppercase as lettres
n = 5
A = list(lettres)     # Fichier de départ. Une lettre par ligne.
C = A[:]     # Fichier cumulatif. Contient déjà le contenu du fichier A.
for _ in range(1, n):
    B = []      # On fait un del() sur le fichier B
    for a in A     # On lit le fichier A.:
        for b in lettres:
            B.append(a+b)     # On écrit à la fin de B (echo) la concaténation.
    C.extend(B)     # On ajoute le fichier B au cumul.
    A = B     # On interchange les noms de fichiers.
# Ici, on peut utiliser sort pour trier C en ordre alphabétique.

0
brucine Messages postés 17595 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 9 novembre 2024 2 565
8 juin 2024 à 07:48

Oui, tu as sûrement raison, je ne suis pas allé vérifier, moi c'est en Python en particulier et dans tous les langages de programmation en général que je suis nul.

Comme je l'ai évoqué initialement, la solution semble être simple dans plusieurs d'entre eux, c'est vouloir le faire en Batch qui est difficile et à dire vrai absurde.

En aparté, y compris d'ailleurs des problèmes relativement simples ne peuvent pas être résolus en Batch pur sans tricher et passer par PowerShell pour au moins une partie des commandes (par exemple pour rendre une partie des espaces disque ou des propriétés système): c'est un "langage" qui a le mérite d'être simple à comprendre mais l'inconvénient d'être limité; historiquement, une poignée de sorciers y ont démontré pour le seul plaisir que l'on pouvait y accomplir certaines choses réputées impossibles, mais de manière antinomique avec alors des codes devenant très complexes et imbuvables.

De manière triviale et sans passer par des utilitaires tiers, Dos est fâché avec l'arithmétique sur les dates et rendant très complexe de l'y réaliser.

0
brucine Messages postés 17595 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 9 novembre 2024 2 565 > brucine Messages postés 17595 Date d'inscription lundi 22 février 2021 Statut Membre Dernière intervention 9 novembre 2024
8 juin 2024 à 10:09

à noter aussi que si on ne veut pas installer un langage de programmation et/ou qu'on y est nul et qu'on ne veut pas non plus passer par les "langages" de script intégrés à Windows (cscript, vbscript) qui offrent différentes solutions, PowerShell rend lui un affichage correct.

 

$asciiNum = 97..122
$letters = $asciiNum | ForEach-Object { [char]$_ }
Foreach ($1letter in $letters)
{
$1letter
}
Foreach ($2letter in $letters)
{
Foreach ($3letter in $letters)
{[array]$letterCombinations2 += "$2letter$3letter"} }
$letterCombinations2
Foreach ($4letter in $letters)
{
 Foreach ($5letter in $letters)
{
 Foreach ($6letter in $letters)
{[array]$letterCombinations3 += "$4letter$5letter$6letter"} } } 
$letterCombinations3
0