Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Liste a re-ordonner !

16 réponses
Avatar
loiseauthierry
Bonjour, petit devoir de vacacances :)

Soit un fichier text contenant par exemple ceci :

=== txt ===
15: yep (2)
14: a b cdde (5)
13: dqgdqg ... (0)
12: dhhh h (12)
11: dd d (8)
10: ---- dfgs ---- (0)
9: [qdfdd]hsfhfh (5)
8: ddfsqdfsdfs (2)
6: dfq d (1000)
5: M()\ (5)
4: dfqd'/p d'dfd (2)
3: pabcqd qdfqd (2)
2: Pddcé gvpt (7)
1: A l'abcd (2)
===/txt ===

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?

Attention : ici il n'y a que 14 ligne (il manque le numéro 7)

Le programme doit être le plus court et le plus lisible possible :))

Merci et bon jeu !!

le résultat ici doit être ceci :

=== txt ===
6: dfq d (1000)
12: dhhh h (12)
11: dd d (8)
2: Pddcé gvpt (7)
14: a b cdde (5)
9: [qdfdd]hsfhfh (5)
5: M()\ (5)
15: yep (2)
8: ddfsqdfsdfs (2)
4: dfqd'/p d'dfd (2)
3: pabcqd qdfqd (2)
1: A l'abcd (2)
13: dqgdqg ... (0)
10: ---- dfgs ---- (0)
===/txt ===

10 réponses

1 2
Avatar
Olivier Miakinen
Le 04/07/2008 11:31, Thierry Loiseau a écrit :

[...]

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



J'y étais presque, avec un appel à la commande unix sort :
$ sort -t '(' -nr -k 2 -k 1 input.txt -o output.txt

La même chose en plus verbeux mais plus lisible :
$ sort --field-separator='(' --numeric-sort --reverse --key=2 --key=1
input.txt -o output.txt

Il aurait alors suffi de l'appeler par un system(), mais malheureusement
ça ne marche pas à cause des parenthèses de la ligne 5. Je vais donc le
faire directement en PHP.
Avatar
Olivier Miakinen
Le 04/07/2008 11:31, Thierry Loiseau a écrit :

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode("n", $contenu)."n");


Note que tu pourrais utiliser l'option FILE_IGNORE_NEW_LINES pour la
fonction file() et du coup supprimer le [rn]* des regexp, mais il
paraît qu'il peut y avoir des problèmes si tu lis un fichier en format
DOS sur un Unix ou le contraire. Inversement, il faudra peut-être
adapter le "n" au moment de la réécriture.
Avatar
Olivier Miakinen
Le 04/07/2008 12:52, j'ai écrit n'importe quoi :

function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode("n", $contenu)."n");

[...] Inversement, il faudra peut-être
adapter le "n" au moment de la réécriture.



Mais non, justement ! Il vaut mieux garder les r ou n tels
qu'ils existent, et ne surtout pas en rajouter !


Donc :

function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode('', $contenu));


(Est-il besoin de préciser que je n'ai pas testé ?)
Avatar
Pierre Maurette
Olivier Miakinen, le 04/07/2008 a écrit :
Le 04/07/2008 11:31, Thierry Loiseau a écrit :

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode("n", $contenu)."n");


Note que tu pourrais utiliser l'option FILE_IGNORE_NEW_LINES pour la
fonction file() et du coup supprimer le [rn]* des regexp, mais il
paraît qu'il peut y avoir des problèmes si tu lis un fichier en format
DOS sur un Unix ou le contraire. Inversement, il faudra peut-être
adapter le "n" au moment de la réécriture.



J'ai du mal à voir comment ça marche. Je vais faire tourner le truc,
puisque je me remets à faire un peu de PHP, donc que je traîne dans le
coin.

En python, pas particulièrement compact, on doit pouvoir faire proche
en PHP:

tri1 = lambda x, y: cmp(int(y.split('(')[-1].rstrip()[:-1]),
int(x.split('(')[-1].rstrip()[:-1]))
tri2 = lambda x, y: cmp(int(y.split(':')[0]), int(x.split(':')[0]))
tri = lambda x, y: tri1(x, y) or tri2(x, y)

s = open('in.txt', 'r').readlines().sort(cmp=tri)
open('out.txt', 'w').write(''.join(s))

--
Pierre Maurette
Avatar
Bruno Desthuilliers
Pierre Maurette a écrit :
(snip)
En python, pas particulièrement compact, on doit pouvoir faire proche en
PHP:



(snip code Python)

Ah woua l'autre, hé, et moi que j'ai répondu en premier avec une
splendide solution Python mon post il est pas passé ???

<meta>
Allo les modérateurs ? Ma soluce s'est perdue dans l'ether(pas net), ou
bien c'est du favoritisme éhonté ?
</meta>

(non, pas taper...)
Avatar
Pierre Maurette
(supersedes )

Olivier Miakinen, le 04/07/2008 a écrit :
Le 04/07/2008 11:31, Thierry Loiseau a écrit :

Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');
file_put_contents($outputfile, implode("n", $contenu)."n");


Note que tu pourrais utiliser l'option FILE_IGNORE_NEW_LINES pour la
fonction file() et du coup supprimer le [rn]* des regexp, mais il
paraît qu'il peut y avoir des problèmes si tu lis un fichier en format
DOS sur un Unix ou le contraire. Inversement, il faudra peut-être
adapter le "n" au moment de la réécriture.



J'ai du mal à voir comment ça marche. Je vais faire tourner le truc,
puisque je me remets à faire un peu de PHP, donc que je traîne dans le
coin.

Puisque je corrige, j'ajoute:
J'ai quand même fait tourner le truc, et effectivement, il me semble
que ça ne trie pas sur le second niveau. A moins que je n'ai pas pigé
l'énoncé...

En python, pas particulièrement compact, on doit pouvoir faire proche
en PHP:

tri1 = lambda x, y: cmp(int(y.split('(')[-1].rstrip()[:-1]),
int(x.split('(')[-1].rstrip()[:-1]))
tri2 = lambda x, y: cmp(int(y.split(':')[0]), int(x.split(':')[0]))
tri = lambda x, y: tri1(x, y) or tri2(x, y)

s = open('in.txt', 'r').readlines().sort(cmp=tri)
open('out.txt', 'w').write(''.join(s))

Correction:

...

s = open('in.txt', 'r').readlines()
s.sort(cmp=tri)
open('out.txt', 'w').write(''.join(s))

--
Pierre Maurette
Avatar
loiseauthierry
Thierry Loiseau wrote:

Bonjour, petit devoir de vacacances :)



Merci à vous de vous prêter au jeu par vos cogitations !!!
(mais je ne connais pas de bonnes solutions)

:((

Thierry
Avatar
loiseauthierry
Thierry Loiseau wrote:

Merci à vous de vous prêter au jeu par vos cogitations !!!
(mais je ne connais pas de bonnes solutions)



... bon je n'y arrive pas ! Pas facile, je n'ai pas PHP5 à la maison,
aussi...

Comment, plutôt que de créer un fichier de sortie, afficher le résultat
à l'écran !

Bonne fin de nuit :)

zzzzZZZzzz
--
* * __*__ *
* * * -----oOOo---°O°---oOOo------ * *
<http://astrophoto.free.fr> *
* * -------- oOOo oOOo -------- *
Avatar
SAM
Thierry Loiseau a écrit :

Comment, plutôt que de créer un fichier de sortie, afficher le résultat
à l'écran !

Bonne fin de nuit :)



Heu, après la sieste, j'imagine qu'on fait qque chose comme :

function cmp($a, $b)
{
preg_match("/([0-9]+).[rn]*$/", $a, $ma);
preg_match("/([0-9]+).[rn]*$/", $b, $mb);
return $mb[1] - $ma[1]; // b - a car ordre inverse
}
$contenu = file($inputfile);
usort($contenu, 'cmp');

$contenu = explode(/nr/, $contenu); // tableau (array) des lignes
foreach($contenu as $ligne) echo $ligne.'<br>';

<http://fr.php.net/foreach>
<http://fr.php.net/manual/fr/function.explode.php>

Comme Olivier je te laisse tester ;-)
En particlier, peut-être faut-il : explode("nr", $contenu);


Peut-être aussi tout simplement :

<pre>
<?php
$contenu = file($inputfile);
usort($contenu, 'cmp');
printf($contenu);
?>
</pre>

<http://fr.php.net/manual/fr/function.printf.php>
avec ses 72351 fonctions, ce php nous offre trop de possibilités.

Autant, echo ou print feront le job ?

--
sm
Avatar
Jacques Haddi
> Comment faire pour réordonner ceci, réenregistrer dans un autre fichier
texte de telle sorte que la première ligne représente le numéro le plus
grand qui se trouve entre parenthèses et en sous-ordre, le numéro se
trouvant en début de la ligne ?



je propose :

<?
function compare($a, $b)
{
ereg("([0-9]+)","$a",$ta);
ereg("([0-9]+)","$b",$tb);
$a2=str_replace(")","",str_replace("(","",$ta[count($ta)-1]));
$b2=str_replace(")","",str_replace("(","",$tb[count($tb)-1]));
if ($a2==$b2)
{
$a1=intval($a);
$b1=intval($b);
if($a1==$b1)
{
return 0;
}
else
{
return ($a1 > $b1) ? -1 : 1;
}
}
else
{
return ($a2 > $b2) ? -1 : 1;
}
}
usort ($tab=file("fichier_texte.txt"), "compare");
fputs(fopen("fichier_texte_2.txt","w"), implode("", $tab));
?>

J.H.
1 2