윌 로저스 현상


35

소위 Will Rogers 현상 은 하나의 요소가 두 세트 사이를 이동할 때 두 개의 (다중) 세트에서 평균을 높여 통계를 조정하는 방법을 설명합니다. 간단한 예로 두 세트를 고려하십시오.

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

산술 평균은 각각 25입니다. 우리는 이동하는 경우 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) 매개 변수를 통해 결과를 출력하는 프로그램 또는 함수를 작성할 수 있습니다.

편리한 문자열 또는 목록 형식으로 입력 할 수 있습니다.

각 목록의 요소가 고유하거나 정렬되어 있다고 가정해서는 안됩니다. 두 목록에 하나 이상의 요소가 있다고 가정 할 수 있습니다.

단일 정수를 이동하고 그렇지 않으면 거짓으로 두 평균을 모두 올릴 수 있으면 결과 가 진실 해야합니다 .

이것은 코드 골프이므로 가장 짧은 대답 (바이트)이 이깁니다.

테스트 사례

진실한 :

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

리더 보드

다음은 일반 리더 보드와 언어 별 수상자 개요를 생성하는 스택 스 니펫입니다.

답변이 표시되도록하려면 다음 마크 다운 템플릿을 사용하여 헤드 라인으로 답변을 시작하십시오.

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


수학자이면서 코더가 아니라는 사실에 도전 할 수는 없지만 다음 질문에 관심이 있습니다. 유한 한 정수 컬렉션 (예 : 5)을 한 세트에서 다른 세트로 이동하여 두 평균을 모두 올릴 수 있다면 항상 하나의 정수만 이동하여 두 평균을 모두 올릴 수 있습니까? 따라서 도전이 실제로 모든 경우를 다룬다는 것을 보여줍니다.
Trevor J Richards

3
@TrevorRichards 마지막 허위 테스트 사례가 이것에 해당한다고 생각합니다. 당신은을 움직일 수 19이상, 모두 평균을 올릴 것이다,하지만 당신은 하나 하나를 이동하여 그렇게 할 수 없습니다.
마틴 엔더

@TrevorRichards 일반적으로, 세트 A & B의 평균 a & b가 a <b 인 경우, 평균 c를 갖는 B의 서브 세트 C가 a <c <b와 같은 경우 두 평균을 모두 올릴 수 있습니다. 반면에 모든 요소가 B에서 A로 이동하여 값 <b를 갖도록 요구하면 가설은 참이됩니다.
Alchymist

답변:


11

Pyth, 29 28 26 24 바이트

저에게 3 바이트를 저장하는 @Jakube에게 감사 .p하고 L.

목록 2의 요소가 목록 1의 평균보다 크고 목록 2의 평균보다 작은 지 확인한 다음 목록 1과 목록 2가 전환 된 상태에서 반복합니다.

Lcsblbff&>YyhT<YyeTeT.pQ

진실과 거짓에 대한 비어 있지 않은 목록을 인쇄합니다 [].

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)

두 개의 목록을 입력으로 사용합니다. 첫 번째 목록에 평균보다 크지 만 다른 것보다 작은 요소가 있는지 확인합니다. 그런 다음 교체 된 두 입력에 대해 동일하게 수행합니다. 2 계층 목록 이해력을 갖는 것은 두 가지 명령을 시도하는 별도의 함수를 정의하는 것보다 짧았습니다 (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

Mathematica, 49 47 바이트

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

형식의 입력을 기대하는 순수한 함수로 평가합니다 {list1, list2}.


4

APL, 45 40 바이트

Moris Zucca 덕분에 5 바이트를 절약했습니다!

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

왼쪽과 오른쪽의 배열을 받아들이고 1 또는 0을 반환하는 명명되지 않은 2 차원 함수를 만듭니다.

{
  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
평균을 다음과 같이 쓸 수 있습니다 : (+ / ÷ ≢)
Moris Zucca

@MorisZucca 감사합니다! 제안을 사용하도록 수정되었습니다.
Alex A.

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

z0 0

z10 0


2

파이썬 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 입력의 배열로 가져 와서 부울을 리턴합니다.
논리는 두 목록의 평균을 찾은 다음 자체 목록의 평균보다 작지만 다른 목록의 평균보다 큰 요소를 찾습니다.

주어진 입력에 대한 테스트는 여기에서 시연됩니다.


2
바이트를 저장하는 *1.대신 수행 할 수 있습니다 *1.0. 또는 Python 3 에서이 작업을 수행하면 나누기가 기본적으로 float을 반환하므로 곱셈이 전혀 필요하지 않습니다. (파이썬 3을 사용하기 위해 코드를 전혀
바꾸지 않아도된다고

@mathmandan 바이트를 저장했습니다. 감사합니다 :)
Kamehameha

를 제거 f=하고로 변경 in[0,1]for하여 익명 기능으로 만들 수 있습니다 in 0,1for. 실제로 101 바이트이므로 98로 줄어 듭니다.
Kade

@ Vioz- 고마워요, 내가 할 수있을 줄 몰랐어요 :)
Kamehameha

2

CJam, 28 바이트

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

이것은 스택에서 2 차원 배열을 팝하고 그 대신에 이동 가능한 요소 배열을 남기는 익명 함수입니다.

지원되는 브라우저에서는 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


이미 루비 솔루션이 있다는 것을 알지 못하고이 작업을 시작했으며 매우 비슷한 것으로 끝났지 만 함수가 첫 번째 목록이 '더 나은'것이라고 가정하여 문자가 두 개 적었습니다. 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 멋진 접근 방식! b그래도 변수에 관한 NameError가 발생합니다 . 재귀 호출은 다음과 같아야한다고 생각합니다 f[a.rotate,p].
Cristian Lupascu

1
죄송합니다. 부정 행위를 통해 더 나은 점수를 얻었습니다.
histocrat

1

MATLAB, 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;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.