Inversions dans un grand tableau

On considère dans cet exercices des tableaux d'entiers.

Soit tab un tel tableau. On appelle inversion un couple d'indices distincts iet j tel que :

  • i est plus petit que j ;
  • tab[i] est strictement plus grand que tab[j].

Considérons par exemple dans le tableau :

🐍 Script Python
# indices  0  1  2  3
tab     = [7, 5, 9, 6]

Ce tableau compte 3 inversions :

  • pour les indices 0 et 1 car tab[0] (qui vaut 7) est strictement supérieur à tab[1] (qui vaut 5),
  • pour les indices 0 et 3 car tab[0] (qui vaut 7) est strictement supérieur à tab[3] (qui vaut 6),
  • pour les indices 2 et 3 car tab[2] (qui vaut 9) est strictement supérieur à tab[3] (qui vaut 6).

On demande d'écrire la fonction inversions qui prend en argument un tableau d'entiers et renvoie son nombre d'inversions.

On convient qu'un tableau vide compte 0 inversions.

Les tableaux utilisés dans les tests sont de grande taille (1 000 éléments ou plus). Ainsi, une approche naïve à l'aide d'une double boucle effectuera de trop nombreuses comparaisons (près de 500 000 pour un tableau de 1 000 valeurs !). À titre de comparaison, le corrigé de cet exercice effectue moins de 10 000 comparaisons pour un tableau de même taille.

Afin de mesurer l'efficacité de l'algorithme utilisé, les tests de cet exercice comptent donc le nombre de comparaisons de valeurs effectuées. Le test échoue si ce nombre est supérieur à deux fois le nombre de comparaisons effectuées par l'algorithme du corrigé.

Exemples
>>> inversions([])
0
>>> inversions([5, 6, 7, 9])
0
>>> inversions([7, 5, 9, 6])
3
###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 10/10
.128013:Lp(40ed3;N 1Ejo5_n)h]6,qc[yu»vïài2+xms7=«ûwlSatf-9ORrg.TéPkb8/050i0h0W0V0I0T0N0m0A0T0V0N0N0P010W0I0d010406050N0D0M0M0V0$0C040U0q0T0D130q0t0m020V0M0d0k0m0#0h1d0$0z0D0h0N050/1a1c1e1g180d041E1L051O0/1O1Q1L180i0I0F0{0}0 110v0I0%0v0T1(0v0W16050?0-0T0h1Z0~10011%1)1+1)0W1;1?1/0W0-0q0i1g1:0$1M0W0v0{1j0N0d0V0t110J011^1#010X0^0h0t1r0h1/2g2i2n1`2q1?2t0M2v040a0m0+0$0q0d0q0N0I1m1o0;2e0$0$0h0A2Q1E2x0t1M0/2c2$0W2a292b0i2z111+0t2s2N1/1W1Y0|1_2:0I2=0t261X1/0d2V1M2!2$37192h1o2{2o300$1d0T160m0n2Z3b173a2y3d1`3f3h3j0J3m2i3o2!2/013t0V3i040m0j3x2#183A3r113D3F0m0f3J3z3b3B3P3j0r3T3L3V3N3C0q3g3E3j0x3!3p3c1!3s3)3u3G0O3.3M3;3O3?3+3G0.3`3$3|3(3*3Q0Z423q443X040n0g493:2|453@0n3l1F3n3#4a4i4c0n3w4n3y4p4h3e3~3F0n3I4v3K3/3W4A160n3S4E3U4q4z464J3Z4M4x4H4Q4d3-4T4G3%4s3_4Z3{4r4I4d414(434*4W0n484.4O3=4W0J4f4@4y4_3@0J4m374U4#4+0J4u534!4b564D594)4P504L5e4/5g3 0J4S5j4^3}4`4Y5p4~5r504%5u4V504-5z554`4?5D5b4W0j4|5H4:3@0j524o5a5N3 0j585R5f4 5U5d5X5k5Z3F0j5i5$5q4j5U5o5,5v5.5)5t5;5A5U5y5_5E5O5C5}5I5O5G615T3F0f5L655l675Q4w5S6b160f5W3y1N351E2_2)0i2-3B0A262F0:1X1M340h363n3T056t0;6B5-0,160;0X6D5Y110S3j6N5%3O0X162~0F0h0$2O1n1D4M6f1`15040e6S5-0t161;6.5=6+0u0b3!0m6|0m6)116J040I6M4M6~6O3C0-162C6?3B6+6-6(776:046=7g6T016^3T767m0q16020T0W0k0P7p6 010M0I4J7c3%6+6`4T6}7K7q6I162V0W0D0$0t7z777C16694w067K7A7i0l7U7r167y757$79047b7l5-7e7F4b6;0V0-7^4i7o7J6}7$160%0V0D0A0v0h7)5-7s047,377M5=7i7k39776+0B7I8f82047(7-778c0/0/8a5=7W046j2#7A6+0w6{817h6K2K2P898t7*8d8y3W7`7|7=6@160B7}3e168s8p8u168w8R3%8A8C3G8E160b8G806|8q6X0s8486888+448c8e3n8g8S720t6Y6!0I6$8Z6*167f8k7m7i8|878N9g7?160u8H8^8J960F0s0i8L0W9l937A918 4r6W976Z6#0t6%9m8W6,9c3O8K0q8M9O7n9o3!7!8I9h6;0q0?0T9D2o9C8O5-8A7Y3K7#9s0I8{859k9(1`9*8%7m9-9q944#6W9v9x9z3ya0907+9_119~8@a79E720s8j9A8(8Q9+8z7D049.179X9r7m710S1%1?aa3Ca29j8~am3B8c7u7waz0t7/7;9L7d9e9T9i9@aDaN7G9VaE3%0q6Q042i0iaJa29w9R9yazaG7v0kaJaL2s9T7@8V95a*9Sa_aV046_9 9:au6W749|6/83aSa58D8l8XaQaBb9a@168?b65=a.7w92a68qa{a,a}448mbeagbrba6H9M0w8o4o7LbFae8!7j7{bh048Ybtaf9=ai6kbc04bjaj8Pbo2#bH3sb88}bz8:bMbw9=aCb(bTbV4wbG7L8_9?b%a-160KbY8/7Vao6d9/bG7A710h0_b.7m7Hb1c39s0W9#3Eb`04b|a;7aa?bO2oa^aU7_04b-bL9paXa8040Ya(agctadb=8qbRbbc9bdcnb#agcGbAaObUchb}b!9P04bybLbNcqbPa3a+c89ncQcDcc9Zbxa4chcjcw4i8Ac117cE9;ahbKc;9)b{cS7Ac?9Wb27N04aw2rcAb,bgc}9`7ta/ck7:cmcZcoaPcKcUcCdj9da bDb;c+b7bJ8Udp11bvdmaAcMc|dy9Uc)bkaFa9dcdndbdFdAdF7idab_dB8FcbatdvdS9^dL018cc:dI8,c0dWcTdCbQdEbW8bc azd24Tasd-avaxbzd-dRc#a|d)cxaHa:d#aKcl7TdUdldQ9Qe26CbTb0c*dX8h8TcXb+c{dxegcIdHd;bldKe3afcWebb*dBe0ezdObid,b@eEeudJcid0b 7Eejd a2cNd-d%eN9}d+d_d45=717P7ReaexbI8`doeKaYb{d997e1bse*ddcicAce9$9W54440A0n16030m0)1C0W9K6a1`711_6Z0We;989If9bSes0e0B0wcve^1191eW9,aoaqe 4ifc0 fefg9H9a9JbLfm9T8A5:fkc(0yd@ao5^fL9MfNd#8A5|fRcPfTfq7Bao64fXa~focRftan7X4g3Bfz0NfBe79FfhfEfjcHc(fHdBfVbLfZe.44fJg1fO16f%f|fSg704fQgacPf*d#fsgc5#6e0/6F6A6lgp0/6o1E0W6qgu2+2%25272)7{1?2$6o1KcO3%2V0M0s0X0V0,0h0s0v0j161w1y1A1C0mds8D1R3o1L0c000V0d340q9k6~1x042t0G6Y1Eg;0m0H0m0Tg*0I2S0i000D2=0m0i0q0D1=1@25861?0mf7h61@6t0R0W0m1A0V9w0V13gX0(1Ng%040!1o1l0^0If=0m0I0A0I0mh41@0M0*2c6uh60D0m0W0C0d1@0Qh61XhB6Z0m2M7R0m0$0*0%2=0$0m0E0m0Ng*g,0D0C2ihl1ah,he2*hG0X0D9I0(0m0o1o0h0X0X0=g}3)0`2S0}0mh 9Ihhhh0D0LhQgD0h85il6E6ucsdbgo3Gi9ir6Gezivh60*0pg|h}0*0yh/hGie0F3E0hh$7C0t0I3h1@hC2*h86Y0m85iC0-1lhOimhai!iy6AiAisiI0Ac60ViJh*730I1@gX0{c61?0YhFhf0Nh_h}2X1x2shl2~0X0*0$i`7R1@iFh89y0`1?0`iM1?7R0`2Vj3h^h62ijk1@21iohPi,itdTiB0b0m1nhD0;0t132q1@0@9JhG0;0`6XfD6$htg$18gs0=0@0_04.
Conseil (1)

On pourra utiliser une méthode de tri efficace (de coût non quadratique).

Conseil (2)

Il est facile de repérer les inversions en utilisant le tri fusion...

Conseil (3)

Commencez par compter les inversions dans la partie gauche du tableau, celles dans la partie droite puis celles existant entre les deux parties.