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
.128013s3_8ufv»y n7aïSû1me(P24:jtw«i][hE)6Oo;bcdg/T0làqp.rL-,=+Nk95Rxé050P0t0A0n0D0U0b0k0O0U0n0b0b0%010A0D0X010406050b0f0s0s0n0Z0j040p0L0U0f130L0l0k020n0s0X0M0k0-0t1d0Z0W0f0t0b050R1a1c1e1g180X041E1L051O0R1O1Q1L180P0D0h0{0}0 110G0D0Q0G0U1(0G0A16050?0N0U0t1Z0~10011%1)1+1)0A1;1?1/0A0N0L0P1g1:0Z1M0A0G0{1j0b0X0n0l110w011^1#010g0^0t0l1r0t1/2g2i2n1`2q1?2t0s2v040a0k0v0Z0L0X0L0b0D1m1o0;2e0Z0Z0t0O2Q1E2x0l1M0R2c2$0A2a292b0P2z111+0l2s2N1/1W1Y0|1_2:0D2=0l261X1/0X2V1M2!2$37192h1o2{2o300Z1d0U160k0r2Z3b173a2y3d1`3f3h3j0w3m2i3o2!2/013t0n3i040k0c3x2#183A3r113D3F0k0x3J3z3b3B3P3j0,3T3L3V3N3C0L3g3E3j0J3!3p3c1!3s3)3u3G0m3.3M3;3O3?3+3G0e3`3$3|3(3*3Q0+423q443X040r0T493:2|453@0r3l1F3n3#4a4i4c0r3w4n3y4p4h3e3~3F0r3I4v3K3/3W4A160r3S4E3U4q4z464J3Z4M4x4H4Q4d3-4T4G3%4s3_4Z3{4r4I4d414(434*4W0r484.4O3=4W0w4f4@4y4_3@0w4m374U4#4+0w4u534!4b564D594)4P504L5e4/5g3 0w4S5j4^3}4`4Y5p4~5r504%5u4V504-5z554`4?5D5b4W0c4|5H4:3@0c524o5a5N3 0c585R5f4 5U5d5X5k5Z3F0c5i5$5q4j5U5o5,5v5.5)5t5;5A5U5y5_5E5O5C5}5I5O5G615T3F0x5L655l675Q4w5S6b160x5W3y1N351E2_2)0P2-3B0O262F0:1X1M340t363n3T056t0;6B5-0*160;0g6D5Y110B3j6N5%3O0g162~0h0t0Z2O1n1D4M6f1`15040u6S5-0l161;6.5=6+0I0y3!0k6|0k6)116J040D6M4M6~6O3C0N162C6?3B6+6-6(776:046=7g6T016^3T767m0L16020U0A0M0%7p6 010s0D4J7c3%6+6`4T6}7K7q6I162V0A0f0Z0l7z777C16694w067K7A7i0)7U7r167y757$79047b7l5-7e7F4b6;0n0N7^4i7o7J6}7$160Q0n0f0O0G0t7)5-7s047,377M5=7i7k39776+0F7I8f82047(7-778c0R0R8a5=7W046j2#7A6+0E6{817h6K2K2P898t7*8d8y3W7`7|7=6@160F7}3e168s8p8u168w8R3%8A8C3G8E160y8G806|8q6X0d8486888+448c8e3n8g8S720l6Y6!0D6$8Z6*167f8k7m7i8|878N9g7?160I8H8^8J960h0d0P8L0A9l937A918 4r6W976Z6#0l6%9m8W6,9c3O8K0L8M9O7n9o3!7!8I9h6;0L0?0U9D2o9C8O5-8A7Y3K7#9s0D8{859k9(1`9*8%7m9-9q944#6W9v9x9z3ya0907+9_119~8@a79E720d8j9A8(8Q9+8z7D049.179X9r7m710B1%1?aa3Ca29j8~am3B8c7u7waz0l7/7;9L7d9e9T9i9@aDaN7G9VaE3%0L6Q042i0PaJa29w9R9yazaG7v0MaJaL2s9T7@8V95a*9Sa_aV046_9 9:au6W749|6/83aSa58D8l8XaQaBb9a@168?b65=a.7w92a68qa{a,a}448mbeagbrba6H9M0E8o4o7LbFae8!7j7{bh048Ybtaf9=ai6kbc04bjaj8Pbo2#bH3sb88}bz8:bMbw9=aCb(bTbV4wbG7L8_9?b%a-160(bY8/7Vao6d9/bG7A710t0_b.7m7Hb1c39s0A9#3Eb`04b|a;7aa?bO2oa^aU7_04b-bL9paXa8040#a(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$9W54440O0r16030k0S1C0A9K6a1`711_6Z0Ae;989If9bSes0u0F0Ecve^1191eW9,aoaqe 4ifc0 fefg9H9a9JbLfm9T8A5:fkc(0$d@ao5^fL9MfNd#8A5|fRcPfTfq7Bao64fXa~focRftan7X4g3Bfz0bfBe79FfhfEfjcHc(fHdBfVbLfZe.44fJg1fO16f%f|fSg704fQgacPf*d#fsgc5#6e0R6F6A6lgp0R6o1E0A6qgu2+2%25272)7{1?2$6o1KcO3%2V0s0d0g0n0*0t0d0G0c161w1y1A1C0kds8D1R3o1L0!000n0X340L9k6~1x042t0o6Y1Eg;0k0V0k0Ug*0D2S0P000f2=0k0P0L0f1=1@25861?0kf7h61@6t0q0A0k1A0n9w0n13gX0Y1Ng%040K1o1l0^0Df=0k0D0O0D0kh41@0s0/2c6uh60f0k0A0j0X1@0Ch61XhB6Z0k2M7R0k0Z0/0Q2=0Z0k0i0k0bg*g,0f0j2ihl1ah,he2*hG0g0f9I0Y0k0H1o0t0g0g0=g}3)0`2S0}0kh 9Ihhhh0f0.hQgD0t85il6E6ucsdbgo3Gi9ir6Gezivh60/0zg|h}0/0$h/hGie0h3E0th$7C0l0D3h1@hC2*h86Y0k85iC0N1lhOimhai!iy6AiAisiI0Oc60niJh*730D1@gX0{c61?0#hFhf0bh_h}2X1x2shl2~0g0/0Zi`7R1@iFh89y0`1?0`iM1?7R0`2Vj3h^h62ijk1@21iohPi,itdTiB0y0k1nhD0;0l132q1@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.