Fenomena Will Rogers

35

Fenomena yang disebut Will Rogers menggambarkan cara untuk mengubah statistik dengan menaikkan rata-rata dalam dua (multi) set ketika satu elemen dipindahkan antara dua set. Sebagai contoh sederhana, perhatikan dua set

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

Berarti aritmatika mereka adalah 2dan 5, masing-masing. Jika kami memindahkan 4ke A:

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

Sekarang rata-rata adalah 2.5dan 5.5, masing-masing, sehingga kedua rata-rata telah dinaikkan melalui pengelompokan ulang sederhana.

Sebagai contoh lain, pertimbangkan

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

Di sisi lain, tidak mungkin menaikkan kedua rata-rata untuk set

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

Tantangan

Diberikan dua daftar bilangan bulat non-negatif, tentukan apakah mungkin untuk menaikkan kedua rata-rata dengan memindahkan satu bilangan bulat dari satu daftar ke yang lain.

Rata-rata daftar kosong tidak ditentukan, jadi jika salah satu daftar hanya berisi satu elemen, elemen ini tidak dapat dipindahkan.

Anda dapat menulis sebuah program atau fungsi, mengambil input melalui STDIN (atau alternatif terdekat), argumen baris perintah atau argumen fungsi dan mengeluarkan hasilnya melalui STDOUT (atau alternatif terdekat), nilai pengembalian fungsi atau parameter function (out).

Input dapat diambil dalam format string atau daftar yang nyaman.

Anda tidak boleh berasumsi bahwa elemen dalam setiap daftar adalah unik, atau bahwa mereka diurutkan. Anda dapat mengasumsikan bahwa kedua daftar berisi setidaknya satu elemen.

Output harus truthy jika kedua rata-rata dapat diangkat dengan memindahkan satu bilangan bulat dan falsy sebaliknya.

Ini adalah kode golf, jadi jawaban tersingkat (dalam byte) menang.

Uji Kasus

Benar:

[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]

Falsy:

[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]

Papan peringkat

Berikut ini adalah Stack Snippet untuk menghasilkan leaderboard biasa dan gambaran umum pemenang berdasarkan bahasa.

Untuk memastikan bahwa jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama, menggunakan templat Penurunan harga berikut:

# Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda dapat menyimpan skor lama di headline, dengan mencoretnya. Contohnya:

# 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>

Martin Ender
sumber
Sebagai ahli matematika dan bukan pembuat kode, saya tidak bisa menjawab tantangan itu, tetapi saya tertarik dengan pertanyaan berikut: Jika kedua rata-rata dapat dinaikkan dengan menggeser beberapa kumpulan integer hingga (katakanlah lima) dari satu set ke set lainnya. , apakah selalu mengikuti bahwa kedua rata-rata dapat dinaikkan dengan menggeser hanya satu bilangan bulat ? Dengan demikian menunjukkan bahwa tantangannya benar-benar mencakup semua kasus.
Trevor J Richards
3
@ TrvorRichards Saya pikir kasus uji falsy terakhir mencakup ini. Anda bisa bergerak a 1dan 9lebih, yang akan menaikkan rata-rata, tetapi Anda tidak bisa melakukannya dengan memindahkan satu saja.
Martin Ender
@ TrvorRichards Secara umum, jika set A & B memiliki rata-rata a & b dengan a <b maka kedua rata-rata dapat dinaikkan jika ada himpunan bagian C dari B yang memiliki rata-rata c sedemikian sehingga a <c <b. Di sisi lain, jika Anda mengharuskan semua elemen dipindahkan dari B ke A untuk memiliki nilai <b maka hipotesis Anda akan benar.
Alchymist

Jawaban:

11

Pyth, 29 28 26 24 byte

Terima kasih kepada @Jakube karena telah menyelamatkan saya 3 byte dengan .pdan L.

Sangat sederhana, periksa apakah ada elemen dalam daftar 2 yang lebih besar dari rata-rata daftar 1 dan kurang dari rata-rata daftar 2, lalu ulangi dengan daftar 1 dan daftar 2 diaktifkan.

Lcsblbff&>YyhT<YyeTeT.pQ

Mencetak daftar yang tidak kosong untuk kebenaran, dan []untuk 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

Cobalah online di sini .

Test Suite.

Maltysen
sumber
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)

Mengambil dua daftar sebagai masukan. Cek apakah daftar pertama memiliki elemen yang lebih besar dari rata-rata tetapi lebih kecil dari yang lain. Kemudian, lakukan hal yang sama untuk dua input yang ditukar. Memiliki pemahaman daftar dua lapis lebih pendek daripada mendefinisikan fungsi terpisah untuk mencoba dua perintah (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)
Tidak
sumber
7

Haskell, 58 57

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

kita dapat memeriksa apakah kita memperbesar atau menurunkan rata-rata dengan memeriksa apakah elemen yang akan dihapus atau dimasukkan lebih besar atau lebih kecil dari rata-rata.

kita dapat memeriksa dengan memeriksa apakah rata-rata lebih kecil atau lebih besar dari suatu elemen dengan menghapus elemen itu dari array, dan memeriksa apakah rata-rata array baru negatif atau positif, yang pada gilirannya sama dengan memeriksa apakah jumlahnya positif atau negatif .

memeriksa yang dimasukkan sangat sederhana sum.map(-n+).

haskeller bangga
sumber
6

Mathematica, 49 47 byte

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

Mengevaluasi fungsi murni yang mengharapkan input dalam formulir {list1, list2}.

jcai
sumber
4

APL, 45 40 byte

Disimpan 5 byte berkat Moris Zucca!

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

Ini menciptakan fungsi dyadic tanpa nama yang menerima array di kiri dan kanan dan mengembalikan 1 atau 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
}

Anda dapat mencobanya secara online .

Alex A.
sumber
1
Anda dapat menulis artinya sebagai: (+ / ÷ ≢)
Moris Zucca
@MorisZucca Terima kasih! Diedit untuk menggunakan saran Anda.
Alex A.
3

R, 66 52 Bytes

Sebagai fungsi yang tidak disebutkan namanya, yang menerima 2 vektor. Singkirkan beberapa yang palsu.

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

Tes

> 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
> 
MickyT
sumber
3

SAS / IML, 67

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

Ini menggunakan operator pengurangan subskrip untuk mendapatkan jawabannya, mengembalikan 0 jika tidak ada elemen yang cocok dengan persyaratan atau 1 jika ada yang ditemukan.

Non-golf, di sini saya mengembalikan nilai aktual itu sendiri menggunakan perkalian matriks:

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;

Tes:

%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;

(Ringkas untuk keterbacaan)

z1 1

z2 1

z3 1

z4 1

z5 1

z6 0

z7 0

z8 0

z9 0

z10 0

Joe
sumber
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]])

Mengambil input sebagai array dari 2 input dan mengembalikan boolean.
Logikanya adalah - temukan rata-rata dari 2 daftar, kemudian temukan elemen sedemikian rupa sehingga kurang dari rata-rata daftar sendiri dan tetapi lebih besar dari rata-rata daftar lainnya.

Mengujinya untuk input yang diberikan demo di sini

Kamehameha
sumber
2
Anda dapat melakukan *1.alih - alih *1.0menyimpan byte. Atau, jika Anda melakukan ini di Python 3, divisi akan mengembalikan float secara default, sehingga Anda tidak akan memerlukan perkalian sama sekali. (Saya tidak berpikir Anda harus mengubah kode Anda sama sekali untuk menggunakan Python 3.)
mathmandan
@mathmandan Menyelamatkan saya satu byte. Terima kasih :)
Kamehameha
Anda dapat menjadikannya fungsi anonim dengan menghapus f=dan mengubah in[0,1]forke in 0,1for. Karena Anda sebenarnya pada 101 byte, ini membawa Anda ke 98.
Kade
@ Vioz- Terima kasih, tidak tahu saya bisa melakukan itu :)
Kamehameha
2

CJam, 28 byte

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

Ini adalah fungsi anonim yang muncul array dua dimensi dari tumpukan dan meninggalkan array elemen bergerak sebagai gantinya.

Di browser yang didukung, Anda dapat memverifikasi semua kasus uji sekaligus dalam juru bahasa CJam .

Uji kasus

Kode

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

Memasukkan

[[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]]

Keluaran

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

Bagaimana itu bekerja

Jika A dan B adalah array dan rata - rata (A) ≤ rata-rata (B), kami cukup memeriksa apakah B ∩ {⌊avg (A) ⌋ + 1,…, ⌈avg (B) ⌉-1} tidak kosong. Elemen apa pun di persimpangan ini dapat dipindahkan dari B ke A untuk meningkatkan kedua rata-rata.

{          }%              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.

Ini mendorong array semua elemen array dengan rata-rata yang lebih tinggi yang dapat dipindahkan untuk meningkatkan kedua rata-rata. Array ini kosong / salah jika dan hanya jika tidak ada elemen yang dapat dipindahkan untuk mencapai hasil ini.

Dennis
sumber
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]}}

Dibawa sebagai input array yang mengandung dua array.

Mencoba menemukan sub item rata-rata dari grup dengan rata-rata lebih tinggi yang lebih besar daripada rata-rata grup lainnya.

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

Cristian Lupascu
sumber
Mulai mengerjakan ini tanpa memperhatikan sudah ada solusi Ruby, berakhir dengan sesuatu yang sangat mirip tetapi itu menjaring dua karakter lebih sedikit dengan memiliki fungsi menganggap daftar pertama adalah 'lebih baik', kemudian menyebut dirinya sebaliknya. 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]}
histokrat
@ histokrat Pendekatan yang bagus! Saya mendapatkan NameError mengenai variabel b. Saya pikir panggilan rekursif harus seperti f[a.rotate,p].
Cristian Lupascu
1
Ups, jadi begitulah cara saya mendapat skor yang lebih baik, dengan menipu.
histokrat
1

Matlab, 54

Menggunakan fungsi anonim:

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

Contoh:

>> 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
Luis Mendo
sumber
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);}

Panggilan Contoh:

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})
Stephan Schinkel
sumber
0

C ++ 14, 157 byte

Sebagai lambda yang tidak disebutkan namanya, kembali dengan parameter terakhir r. Diasumsikan A, Bmenjadi wadah seperti vector<int>atau 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);}

Tidak Disatukan:

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);
}
;

Pemakaian:

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;
}
Karl Napf
sumber