Le phénomène de Will Rogers


35

Le phénomène dit de Will Rogers décrit un moyen d'ajuster les statistiques en augmentant la moyenne en deux (multi) ensembles lorsqu'un élément est déplacé entre les deux ensembles. Comme exemple simple, considérons les deux ensembles

A = {1, 2, 3}
B = {4, 5, 6}

Leurs moyennes arithmétiques sont 2et 5, respectivement. Si nous passons le 4à A:

A = {1, 2, 3, 4}
B = {5, 6}

Maintenant, les moyennes sont 2.5et 5.5, respectivement, donc les deux moyennes ont été relevées par un simple regroupement.

Comme autre exemple, considérons

A = {3, 4, 5, 6} --> A = {3, 5, 6}
B = {2, 3, 4, 5} --> B = {2, 3, 4, 4, 5}

Par contre, il n’est pas possible de relever les deux moyennes pour les ensembles

A = {1, 5, 9}
B = {4, 5, 7, 8}

Le défi

À partir de deux listes d’entiers non négatifs, déterminez s’il est possible d’élever les deux moyennes en déplaçant un seul entier d’une liste à l’autre.

La moyenne d'une liste vide n'est pas définie. Par conséquent, si l'une des listes ne contient qu'un seul élément, cet élément ne peut pas être déplacé.

Vous pouvez écrire un programme ou une fonction en prenant l’entrée via STDIN (ou l’alternative la plus proche), un argument de ligne de commande ou une argumentation de fonction et en générant le résultat via STDOUT (ou l’alternative la plus proche), une valeur de retour de fonction ou un paramètre de fonction (out).

La saisie peut être effectuée dans n’importe quelle chaîne ou format de liste.

Vous ne devez pas supposer que les éléments de chaque liste sont uniques, ni qu'ils sont triés. Vous pouvez supposer que les deux listes contiennent au moins un élément.

La sortie devrait être véridique si les deux moyennes peuvent être relevées en déplaçant un seul entier et une fausseté autrement.

C'est le code de golf, donc la réponse la plus courte (en octets) gagne.

Cas de test

Vérité

[1], [2, 3]
[1, 2, 3], [4, 5, 6]
[3, 4, 5, 6], [2, 3, 4, 5]
[6, 5, 9, 5, 6, 0], [6, 2, 0, 9, 5, 2]
[0, 4], [9, 1, 0, 2, 8, 0, 5, 5, 4, 9]

Fausseté:

[1], [2]
[2, 4], [5]
[1, 5], [2, 3, 4, 5]
[2, 1, 2, 3, 1, 3], [5, 1, 6]
[4, 4, 5, 2, 4, 0], [9, 2, 10, 1, 9, 0]

Classements

Voici un extrait de pile permettant de générer un classement régulier et un aperçu des gagnants par langue.

Pour vous assurer que votre réponse apparaît, commencez votre réponse par un titre, en utilisant le modèle Markdown suivant:

# Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores en les effaçant. Par exemple:

# Ruby, <s>104</s> <s>101</s> 96 bytes

<script>site = 'meta.codegolf'; postID = 5314; isAnswer = true; QUESTION_ID = 53913</script><script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)</code></pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>


En tant que mathématicien et non codeur, je ne peux pas vraiment relever le défi, mais la question suivante m'intéresse: si les deux moyennes peuvent être relevées en déplaçant une collection finie d'entiers (par exemple cinq) d'un ensemble à l'autre , en résulte-t-il toujours que les deux moyennes peuvent être augmentées en décalant un seul entier ? Cela montre donc que le défi couvre réellement tous les cas.
Trevor J Richards le

3
@TrevorRichards Je pense que le dernier cas de test de fausseté couvre cela. Vous pouvez déplacer a 1et 9plus, ce qui augmenterait les deux moyennes, mais vous ne pouvez pas le faire en déplaçant une seule.
Martin Ender

@TrevorRichards En général, si les ensembles A et B ont des moyennes a & b avec a <b, les deux moyennes peuvent être relevées s'il existe un sous-ensemble C de B qui a une moyenne c telle que a <c <b. D'autre part, si vous avez besoin que tous les éléments déplacés de B en A aient des valeurs <b, votre hypothèse sera vraie.
Alchymist

Réponses:


11

Pyth, 29 28 26 24 octets

Merci à @Jakube pour m'avoir économisé 3 octets avec .pet L.

Très simple, vérifie si des éléments de la liste 2 sont supérieurs à la moyenne de la liste 1 et inférieurs à la moyenne de la liste 2, puis répète avec la liste 1 et la liste 2 remplacées.

Lcsblbff&>YyhT<YyeTeT.pQ

Imprime une liste non vide pour la vérité et []pour Falsey.

L                    Define y(b). Pyth has no builtin for mean
 c                   Float div
  sb                 Sum of b
  lb                 Length of b
f        .pQ         Filter all permutations of input
 f     eT            Filter the last element of the filter var
  &                  Logical and
   >Y                Inner filter var greater than
    y                Call the mean function we defined earlier
     hT              First element of outer filter var
   <Y                Inner filter var less than
    y                Mean of
     eT              Last element of outer filternvar

Essayez-le en ligne ici .

Suite de tests.


7

Python 3, 74

lambda*L:any(sum(C)/len(C)>x>sum(D)/len(D)for(C,D)in[L,L[::-1]]for x in C)

Prend deux listes en entrée. Vérifie si la première liste a un élément plus grand que la moyenne mais plus petit que l'autre. Ensuite, fait la même chose pour les deux entrées permutées. Avoir une compréhension de liste à deux couches était plus court que de définir une fonction séparée pour essayer les deux ordres (82):

f=lambda A,B:any(sum(A)/len(A)>x>sum(B)/len(B)for x in A)
lambda A,B:f(A,B)|f(B,A)

7

Haskell, 58 ans 57

x%y=any(\n->(\g->g x<0&&g y>0)$sum.map(n-))x
x?y=x%y||y%x

nous pouvons vérifier si nous augmentons ou diminuons la moyenne en vérifiant si l'élément à supprimer ou à inclure est plus grand ou plus petit que la moyenne.

nous pouvons vérifier cela en vérifiant si la moyenne est plus petite ou plus grande qu'un élément en supprimant cet élément du tableau et en vérifiant si la moyenne du nouveau tableau est négative ou positive, ce qui revient tout autant à vérifier si la somme est positive ou négative. .

vérifier que c'est mis très simplement comme sum.map(-n+).


6

Mathematica, 49 47 octets

m=Mean;MemberQ[#2,x_/;m@#<x<m@#2]&@@#~SortBy~m&

Evalue en une fonction pure qui attend une entrée dans le formulaire {list1, list2}.


4

APL, 45 40 octets

5 octets sauvés grâce à Moris Zucca!

{U←∊⍺⍵[⊃⍒M←(+/÷≢)¨⍺⍵]⋄1∊(U<⌈/M)∧(U>⌊/M)}

Cela crée une fonction dyadique non nommée qui accepte les tableaux à gauche et à droite et renvoie 1 ou 0.

{
  M←(+/÷≢)¨⍺⍵          ⍝ Compute the mean of each array
  U←∊⍺⍵[⊃⍒M]           ⍝ Get the array with the larger mean
  1∊(U<⌈/M)∧(U>⌊/M)    ⍝ Any smaller mean < U < larger mean
}

Vous pouvez l' essayer en ligne .


1
vous pouvez écrire la moyenne comme suit: (+ / ≢)
Moris Zucca

@MorisZucca Merci! Edité pour utiliser votre suggestion.
Alex A.

3

R, 66 52 octets

En tant que fonction non nommée, elle accepte 2 vecteurs. Je me suis débarrassé de quelques trucs parasites.

function(a,b)any(a<(m=mean)(a)&a>m(b),b<m(b)&b>m(a))

Des tests

> f=
+ function(a,b)any(a<(m=mean)(a)&a>m(b),b<m(b)&b>m(a))
> f(c(1), c(2, 3))
[1] TRUE
> f(c(1, 2, 3), c(4, 5, 6))
[1] TRUE
> f(c(3, 4, 5, 6), c(2, 3, 4, 5))
[1] TRUE
> f(c(6, 5, 9, 5, 6, 0), c(6, 2, 0, 9, 5, 2))
[1] TRUE
> f(c(0, 4), c(9, 1, 0, 2, 8, 0, 5, 5, 4, 9))
[1] TRUE
> 
> f(c(1), c(2))
[1] FALSE
> f(c(2, 4), c(5))
[1] FALSE
> f(c(1, 5), c(2, 3, 4, 5))
[1] FALSE
> f(c(2, 1, 2, 3, 1, 3), c(5, 1, 6))
[1] FALSE
> f(c(4, 4, 5, 2, 4, 0), c(9, 2, 10, 1, 9, 0))
[1] FALSE
> 

3

SAS / IML, 67 ans

start m(a,b);return((a>b[:]&&a<a[:])||(b>a[:]&&b<b[:]))[<>];finish;

Il utilise des opérateurs de réduction en indice pour obtenir la réponse. Il renvoie 0 si aucun élément correspondant aux exigences n'est trouvé ou 1 si un est trouvé.

Non-golfé, je renvoie ici la valeur réelle elle-même en utilisant la multiplication matricielle:

proc iml;
  b={1 2 3 4 5 6 7 8 9 };
  a={2 3 4 5 6};
  start m(a,b);
  return (a#(a>b[:] && a < a[:]) || b#(b>a[:] && b < b[:]))[<>];
  finish;

  z= m(a,b);
  print z;
quit;

Tests:

%macro test(a,b,n);
  z&n=m({&a},{&b});
  print z&n;
%mend test;

proc iml;
  b={1 2 3 4 5 };
  a={2 3 4 5 6 7};
start m(a,b);return((a>b[:]&&a<a[:])||(b>a[:]&&b<b[:]))[<>];finish;

* True;
 %test(1,2 3,1);
 %test(1 2 3,4 5 6,2);
 %test(3 4 5 6, 2 3 4 5,3);
 %test(6 5 9 5 6 0,6 2 0 9 5 2,4);
 %test(0 4, 9 1 0 2 8 0 5 5 4 9,5);
* False;
 %test(1,2,6);
 %test(2 4, 5,7);
 %test(1 5, 2 3 4 5,8);
 %test(2 1 2 3 1 3, 5 1 6,9);
 %test(4 4 5 2 4 0, 9 2 10 1 9 0,10);

quit;

(Condensé pour la lisibilité)

z1 1

z2 1

z3 1

z4 1

z5 1

z6 0

z7 0

z8 0

z9 0

z10 0


2

Python 2.7, 102 98 96

lambda p:any([1for i in 0,1for e in p[i]if g[i^1]<e<g[i]]for g in[[sum(l)*1./len(l)for l in p]])

Prend l'entrée en tant que tableau des 2 entrées et retourne un booléen.
La logique est la suivante: recherchez l'avg des 2 listes, puis recherchez un élément tel qu'il soit inférieur à l'avg de sa propre liste et supérieur à la moyenne de l'autre liste.

Le tester pour les entrées données est démontré ici


2
Vous pouvez faire *1.au lieu de *1.0sauvegarder un octet. Sinon, si vous faites cela dans Python 3, la division retournera un float par défaut, de sorte que vous n'auriez pas besoin de cette multiplication du tout. (Je ne pense pas que vous deviez changer votre code pour utiliser Python 3.)
mathmandan

@mathmandan m'a sauvé un octet. Merci :)
Kamehameha

Vous pouvez en faire une fonction anonyme en supprimant f=et en remplaçant in[0,1]forpar in 0,1for. Puisque vous êtes actuellement à 101 octets, cela vous ramène à 98.
Kade

@ Vioz- Merci, je ne savais pas que je pouvais faire ça :)
Kamehameha le

2

CJam, 28 octets

{{_:+1$,d/\+}%$~(m],@0=i)>&}

Il s'agit d'une fonction anonyme qui ouvre un tableau à deux dimensions de la pile et laisse un tableau d'éléments mobiles en retour.

Dans les navigateurs pris en charge, vous pouvez vérifier tous les tests en même temps dans l’ interpréteur CJam .

Cas de test

Code

q~]{{_:+1$,d/\+}%$~(m],@0=i)>&}%:p

Contribution

[[1] [2 3]]
[[1 2 3] [4 5 6]]
[[3 4 5 6] [2 3 4 5]]
[[6 5 9 5 6 0] [6 2 0 9 5 2]]
[[0 4] [9 1 0 2 8 0 5 5 4 9]]
[[1] [2]]
[[2 4] [5]]
[[1 5] [2 3 4 5]]
[[2 1 2 3 1 3] [5 1 6]]
[[4 4 5 2 4 0] [9 2 10 1 9 0]]

Sortie

[2]
[4]
[4]
[5]
[4]
""
""
""
""
""

Comment ça marche

Si A et B sont les tableaux et avg (A) ≤ avg (B), nous vérifions simplement si B ∩ {⌊avg (A) + 1,…, avg (B)-1} est non vide. Tout élément de cette intersection peut être déplacé de B vers A pour augmenter les deux moyennes.

{          }%              e# For each of the arrays:
 _:+                       e#   Compute the sum of its elements.
    1$,                    e#   Compute its length.
       d/                  e#   Cast to Double and perform division.
         \+                e#   Prepend the computed average to the array.
             $             e# Sort the arrays (by the averages).
              ~            e# Dump both arrays on the stack.
               (           e# Shift out the higher average.
                m]         e# Round up to the nearest integer b.
                  ,        e# Push [0 ... b-1].
                   @0=     e# Replace the array with lower average by its average.
                      i)   e# Round down to the nearest integer a and add 1.
                        >  e# Skip the first a integer of the range.
                           e# This pushes [a+1 ... b-1].
                         & e# Intersect the result with the remaining array.

Cela pousse le tableau de tous les éléments du tableau avec une moyenne plus élevée qui peut être déplacé pour augmenter les deux moyennes. Ce tableau est vide / faux si et seulement si aucun élément ne peut être déplacé pour atteindre ce résultat.


1

Ruby, 86

A=->x{x.reduce(0.0,:+)/x.size}
F=->q{b,a=q.sort_by{|x|A[x]};a.any?{|x|x<A[a]&&x>A[b]}}

Prend en entrée un tableau contenant les deux tableaux.

Essaie de trouver un élément de sous moyenne dans le groupe avec la moyenne la plus élevée qui est supérieure à la moyenne de l'autre groupe.

Test: http://ideone.com/444W4U


J'ai commencé à travailler là-dessus sans m'apercevoir qu'il existait déjà une solution Ruby, mais il a abouti à quelque chose de très similaire, mais il génère deux caractères de moins en laissant la fonction supposer que la première liste est 'meilleure', puis s'appelle elle-même à l'envers. f=->a,s=1{i,j=a.map{|x|x.inject(0.0,:+)/x.size};a[0].any?{|y|i>y&&j<y}||s&&f[b,a,p]}
histocrat

@histocrat Nice approche! Je reçois un NameError concernant la variableb . Je pense que l'appel récursif devrait être quelque chose comme f[a.rotate,p].
Cristian Lupascu le

1
Oups, c'est ainsi que j'ai obtenu un meilleur score en trichant.
Histocrat

1

Matlab, 54 ans

Utiliser une fonction anonyme:

f=@(A,B)any([B>mean(A)&B<mean(B) A>mean(B)&A<mean(A)])

Exemples:

>> f=@(A,B)any([B>mean(A)&B<mean(B) A>mean(B)&A<mean(A)])
f = 
    @(A,B)any([B>mean(A)&B<mean(B),A>mean(B)&A<mean(A)])

>> f([1 2 3],[4 5 6])
ans =
     1

>> f([3 4 5 6],[2 3 4 5])
ans =
     1

>> f([1 5 9],[4 5 7 8])
ans =
     0

1

C #, 104

bool f(int[]a,int[]b){double i=a.Average(),j=b.Average();return a.Any(x=>x<i&&x>j)||b.Any(x=>x<j&&x>i);}

Exemple d'appels:

f(new []{1,2,3}, new []{4,5,6})
f(new []{1}, new []{2, 3})
f(new []{1, 2, 3}, new []{4, 5, 6})
f(new []{3, 4, 5, 6}, new []{2, 3, 4, 5})
f(new []{6, 5, 9, 5, 6, 0}, new []{6, 2, 0, 9, 5, 2})
f(new []{0, 4}, new []{9, 1, 0, 2, 8, 0, 5, 5, 4, 9})

f(new []{1}, new []{2})
f(new []{2, 4}, new []{5})
f(new []{1, 5}, new []{2, 3, 4, 5})
f(new []{2, 1, 2, 3, 1, 3}, new []{5, 1, 6})
f(new []{4, 4, 5, 2, 4, 0}, new []{9, 2, 10, 1, 9, 0})

0

C ++ 14, 157 octets

Comme lambda sans nom, retourne par le dernier paramètre r. Suppose A, Bêtre des conteneurs comme vector<int>ou array<int,>.

[](auto A,auto B,int&r){auto m=[](auto C){auto s=0.;for(auto x:C)s+=x;return s/C.size();};r=0;for(auto x:A)r+=x<m(A)&&x>m(B);for(auto x:B)r+=x<m(B)&&x>m(A);}

Ungolfed:

auto f=
[](auto A,auto B,int&r){
  auto m=[](auto C){
   auto s=0.;
   for(auto x:C) s+=x;
   return s/C.size();
  };
  r=0;
  for (auto x:A) r+=x<m(A)&&x>m(B);
  for (auto x:B) r+=x<m(B)&&x>m(A);
}
;

Usage:

int main() {
  std::vector<int>
    a={1,2,3}, b={4,5,6};
  //  a={1,5,9}, b={4,5,7,8};
  int r;
  f(a,b,r);
  std::cout << r << std::endl;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.