Феномен Вілла Роджерса


35

Так званий феномен Вілла Роджерса описує спосіб налаштування статистики шляхом підняття середнього значення у двох (декількох) множинах, коли один елемент переміщується між двома множинами. Як простий приклад розглянемо два набори

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

Їх арифметичні засоби є 2і 5, відповідно. Якщо ми перейдемо 4до A:

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

Тепер середні показники є 2.5і 5.5, відповідно, обидва середні показники були підвищені шляхом простого перегрупування.

В якості іншого прикладу розглянемо

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

З іншого боку, не можна підняти обидва середні значення для наборів

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

Змагання

Давши два списки невід’ємних цілих чисел, визначте, чи можна підняти обидва середні, переміщуючи одне ціле число з одного списку в інший.

Середнє значення порожнього списку не визначено, тому якщо один із списків містить лише один елемент, цей елемент неможливо перемістити.

Ви можете написати програму або функцію, взявши введення через STDIN (або найближчу альтернативу), аргумент командного рядка або аргумент функції та вивівши результат через STDOUT (або найближчу альтернативу), значення повернення функції або параметр функції (out).

Введення даних може здійснюватися у будь-якому зручному форматі рядка чи списку

Ви не повинні вважати, що елементи в кожному списку є унікальними, ні що вони сортуються. Можна припустити, що обидва списки містять принаймні один елемент.

Вихід повинен бути правдивим, якщо обидва середні показники можна підвищити, перемістивши одне ціле число, а фальш - помилково .

Це кодовий гольф, тому найкоротша відповідь (у байтах) виграє.

Випробування

Truthy:

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

Табло лідерів

Ось фрагмент стека для створення як звичайного табло, так і огляду переможців за мовою.

Щоб переконатися, що ваша відповідь відображається, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown:

# Language Name, N bytes

де Nрозмір вашого подання. Якщо ви покращите свій рахунок, ви можете зберегти старі бали у заголовку, прокресливши їх. Наприклад:

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


Як математик, а не кодер, я не можу реально вирішити проблему, але мене цікавить наступне питання: Якщо обидва середні показники можна підняти, перемістивши деяку кінцеву колекцію цілих чисел (скажімо, п'ять) з одного набору на інший Чи завжди випливає, що обидва середні значення можна збільшити, змістивши лише одне ціле число ? Таким чином показуючи, що виклик дійсно охоплює всі випадки.
Тревор Дж Річардс

3
@TrevorRichards Я думаю, що останній тестовий випадок хибності стосується цього. Ви можете рухатись вгору 1і 9знову, що піднімає обидва середні показники, але ви не можете цього зробити, перемістивши один.
Мартін Ендер

@TrevorRichards Загалом, якщо множини A & B мають середні значення a & b з <b, то обидва середні значення можуть бути підвищені, якщо є підмножина C B, яка має середню c таку, що a <c <b. З іншого боку, якщо вам потрібні всі елементи, переміщені з B до A, щоб мати значення <b, то ваша гіпотеза була б істинною.
Алхімік

Відповіді:


11

Pyth, 29 28 26 24 байт

Дякую @Jakube, що врятував мені 3 байти з .pта L.

Дуже просто, перевіряє, чи будь-які елементи у списку 2 перевищують середнє значення у списку 1 та менше середнього середнього списку 2, а потім повторюється із переключеним списком 1 та списком 2.

Lcsblbff&>YyhT<YyeTeT.pQ

Друкує не порожній список для truthy та []for 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

Спробуйте його онлайн тут .

Тестовий сюїт.


7

Пітон 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)

В якості вхідних даних бере два списки. Перевіряє, чи є в першому списку елемент, який більший за середній, але менший, ніж у другого. Потім робить те ж саме для двох входів, що поміняються. Розуміння двошарового списку було коротше, ніж визначення окремої функції для спробу двох порядків (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

Хаскелл, 58 57

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

ми можемо перевірити, збільшуємо чи знижуємо середнє, перевіряючи, чи елемент, який потрібно видалити чи включити, більший чи менший за середній

ми можемо перевірити це, перевіривши, чи є середнє значення меншим чи більшим, ніж елемент, вилучивши цей елемент із масиву, і перевіривши, чи є середнє значення нового масиву негативним чи позитивним, що, в свою чергу, так само перевіряє, чи є сума позитивною чи негативною .

перевірка того, що ставиться дуже просто як sum.map(-n+).


6

Математика, 49 47 байт

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

Оцінюється до чистої функції, яка очікує введення у форму {list1, list2}.


4

APL, 45 40 байт

Збережено 5 байт завдяки Морісу Зукці!

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

Це створює безіменну діадичну функцію, яка приймає масиви зліва та справа і повертає 1 або 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
}

Ви можете спробувати в Інтернеті .


1
можна записати середнє значення як: (+ / ÷ ≢)
Моріс Цука

@MorisZucca Дякую! Відредаговано для використання вашої пропозиції.
Олексій А.

3

R, 66 52 байт

Як неназвана функція, яка приймає 2 вектори. Позбувся деяких хибних, які.

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

Тести

> 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

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

Для отримання відповіді використовуються оператори скорочення підписки, повертаючи 0, якщо не знайдено жодного елемента, що відповідає вимогам, або 1, якщо такий знайдено.

Без гольфу, тут я повертаю власне значення за допомогою матричного множення:

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;

Тести:

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

(Стиснення для читабельності)

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

Приймає вхід як масив двох входів і повертає булевий.
Логіка полягає в тому, щоб знайти середній рівень двох списків, а потім знайти такий елемент, що він менший за середній рівень його власного списку та більший за середній показник для іншого списку.

Тут продемонстровано тестування його для заданих входів


2
Ви можете зробити *1.замість того, *1.0щоб зберегти байт. Крім того, якщо ви зробите це в Python 3, ділення поверне плавець за замовчуванням, тож вам не потрібно цього множення взагалі. (Я не думаю, що вам взагалі доведеться змінювати код, щоб використовувати Python 3.)
mathmandan,

@mathmandan врятував мені байт. Дякую :)
Kamehameha

Ви можете зробити це анонімною функцією, видаливши f=та змінивши in[0,1]forна in 0,1for. Оскільки ви насправді на 101 байт, це зводить вас до 98.
Кейд,

@ Vioz- Спасибі, не знав, що я можу це зробити :)
Kamehameha

2

CJam, 28 байт

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

Це анонімна функція, яка спливає двовимірний масив із стека та залишає масив рухомих елементів натомість.

У підтримуваних браузерах ви можете перевірити всі тестові випадки одразу в інтерпретаторі CJam .

Тестові справи

Код

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

Вхідні дані

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

Вихідні дані

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

Як це працює

Якщо A і B - масиви, а avg (A) ≤ avg (B), ми просто перевіряємо, чи B ∩ {⌊avg (A) ⌋ + 1,…, ⌈avg (B) ⌉-1} не порожній. Будь-який елемент цього перетину може бути переміщений з B до A для збільшення обох середніх.

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

Це підштовхує масив усіх елементів масиву з більш високим середнім рівнем, який можна перемістити для збільшення обох середніх. Цей масив порожній / хибний тоді і лише тоді, коли для досягнення цього результату не можна перемістити жодні елементи.


1

Рубі, 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]}}

За вхід приймає масив, що містить два масиви.

Намагається знайти підгрупу середнього елемента з групи з вищим середнім, що перевищує середнє значення для іншої групи.

Тест: http://ideone.com/444W4U


Почав працювати над цим, не помічаючи, що вже було рішення Ruby, в кінцевому підсумку вийшло щось дуже схоже, але воно містить два менших символи, функція припускає, що перший список "кращий", а потім називайте себе навпаки. 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 Приємний підхід! bОднак я отримую NameError щодо змінної . Я думаю, що рекурсивний дзвінок повинен бути чимось подібним f[a.rotate,p].
Крістіан Лупаску

1
На жаль, так я отримав кращу оцінку шляхом обману.
гістократ

1

Матлаб, 54

Використання анонімної функції:

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 = 
    @(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);}

Приклад дзвінків:

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 байт

Як неназвана лямбда, повертається за останнім параметром r. Припускає A, Bщо це контейнери типу vector<int>або 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);}

Безголівки:

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

Використання:

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.