리버스 엔지니어 폴링 통계


22

소개

여론 조사에서 일정 비율의 선택 항목이 주어지면 해당 통계를 생성하기 위해 여론 조사에 참여해야하는 최소 유권자 수를 계산하십시오.

예 : 가장 좋아하는 애완 동물은 무엇입니까?

  • 개: 44.4%
  • 고양이: 44.4%
  • 쥐: 11.1%

결과 : 9(최소한 유권자 수)

명세서

프로그램 / 기능에 대한 요구 사항은 다음과 같습니다.

  • 입력으로 백분율 값의 배열이 제공됩니다 (stdin, 함수 인수 등).
  • 각 백분율 값은 소수점 이하 한 자리로 반올림 된 숫자입니다 (예 :) 44.4 44.4 11.1.
  • 여론 조사에서 소수점 이하 한 자리 (stdout 또는 함수 반환 값)로 반올림했을 때 정확한 백분율을 산출 할 수있는 투표자의 최소 유권자 수를 계산합니다.
  • 보너스 : "사소한"방법으로 해결할 수있는 경우 -15 자 (즉, 첫 번째 유권자를 찾을 때까지 가능한 모든 유권자 수를 반복하지 않음)

>./pollreverse 44.4 44.4 11.1
9
>./pollreverse 26.7 53.3 20.0
15
>./pollreverse 48.4 13.7 21.6 6.5 9.8
153
>./pollreverse 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 99.6
2000
>./pollreverse 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 98.7
667
>./pollreverse 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 98.7
2000
>./pollreverse 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 97.8
401

채점

이것은 코드 골프이므로 가능한 가장 짧은 문자가 이깁니다. 모든 보너스는 총 캐릭터 수에서 차감됩니다.


2
테스트가 더 어색한 경우와 관련이 있다고 생각합니다. 26.7 53.3 20.0(4 8 3 of 15), 48.4 13.7 21.6 6.5 9.8(74 21 33 10 15 of 153) 등
Gareth

@Gareth : 좋은 생각입니다. 테스트 사례로 업데이트되었습니다.
mellamokb

모든 투표의 합이 100 %가 아니어야합니까? 지난 4 개의 테스트 케이스에는 없습니다
Ali1S232

@Gajet : 아니요 100 %는 아닙니다. 반올림이있을 때마다 0.5%총계에서 잃고 반올림 할 때마다 총계까지 0.5%합산됩니다. 마지막 4 개의 테스트 사례는이 현상을 최적으로 활용하기 위해 의도적으로 구성되었습니다. 결과로 표시되는 첫 번째 테스트 사례 2000에서 처음 9 개 항목 각각은 1투표를 나타내고 (모두 반올림 됨 0.5%), 마지막 항목은 투표를 나타냅니다 1991(내림 ~ 0.5%) 이 백분율을 수동으로 계산하고 소수점 이하 1 자리로 반올림하면 모두 올바른지 알 수 있습니다.
mellamokb

VBA에서 사소한 대답으로 어려움을 겪고 있지만 (지금까지 시도한 결과 아무것도 없었습니다) 노력하고 있습니다!
Gaffi

답변:


2

APL (Dyalog Classic) , 48 43 바이트

Adám으로 -5 바이트

+/0(⊢+{(⌈/⍷⊢)⍺-⍵÷+/⍵})⍣{z≡⍎3⍕⍺÷+/⍺}⍨z←.01×⎕

stdin에서 입력을받는 전체 프로그램.

온라인으로 사용해보십시오! 링크는 dfn 버전입니다.

언 골프

normalize   ÷ +/
find_max  {⍵⍷⍨⌈/⍵}
round  {⍎3⍕⍵}
increase  {find_max  - normalize ⍵}
vote_totals  {z←⍺   (⊢+increase)⍣{z  round normalize ⍺} ⍵}
h  {+/ (.01×⍵) vote_totals 0}

온라인으로 사용해보십시오!

  • normalize÷올바른 인수 ( ) 의 모든 요소를 합계 ( +/)로 나눕니다 ( ).
  • round(y)y의 각 요소를 형식화 ( ) 한 다음 평가 ( ) 하여 y를 소수점 이하 3 자리로 올림 합니다.
  • find_max(y) max (y)가 1이면 다른 곳에서는 0으로 배열을 반환합니다.
  • increase(x,y) x (목표 백분율) 및 y (현재 투표 합계의 배열)를 취하고 백분율을 x에 더 가깝게하기 위해 y에 1을 더할 위치를 계산합니다.
  • vote_totals(x,y) x (목표 백분율)와 y (시작 투표 총계)를 취하고 f를 반복적으로 실행하여 백분율이 x로 반올림 될 때까지 투표를 추가합니다.
    • 구문 은 true가 될 때까지 반복해서 f ⍣ g실행하는 것을 의미 합니다. 이 경우 우리는 무시 합니다.fg(y,f(y))f(y)
  • h(x) y를 0으로 설정하고 (벡터화로 인해 0의 배열과 같음) g를 실행하고 최종 투표 총계를 합합니다.

7

파이썬, 154

def p(x):
 n=[1]*len(x);d=2;r=lambda z:round(1000.*z/d)/10
 while 1:
    if(map(r,n),sum(n))==(x,d):return d
    d+=1
    for i in range(len(x)):n[i]+=r(n[i])<x[i]

이제 마지막 예제에서 작동합니다.

예제 실행 :

>>> p([44.4, 44.4, 11.1])
9
>>> p([26.7, 53.3, 20.0])
15
>>> p([48.4, 13.7, 21.6, 6.5, 9.8])
153
>>> p([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 99.6])
2000
>>> p([0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 98.7])
667
>>> p([0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 98.7])
2000
>>> p([0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 97.8])
401

나는 당신의 마지막 예에서 무언가 잘못되었을 것입니다. 아마 당신 99.1은 마지막 값으로 의미
Cristian Lupascu

2
나는 그것이 옳다고 생각하지만 꽤 혼란 스럽습니다. 1/2000 = 0.05%( 0.1%반올림) 및 1991/2000 = 99.55%( 99.6%반올림). 따라서 여론 조사에 10 개의 옵션이 있고 그 중 9 개가 한 번만 투표되고 마지막은 1991 년에 투표하면 그 비율이 표시됩니다.
grc

네가 옳아. 훌륭한 솔루션, BTW.
Cristian Lupascu


고마워, w0lf. 탭을 포함하도록 지금 업데이트했습니다. 누군가 궁금한 경우 탭은 4 개의 공백으로 표시됩니다.
grc

4

J, 57 자

t=:".>'1'8!:0|:100*%/~i.1001
{.I.*/"1(t{~i.#t)e."1~1!:1[1

사소한 방법을 사용했습니다. 키보드에서 입력을받습니다. t조회 테이블을 작성하고 두 번째 행은 테이블 내에서 입력을 찾습니다. 관심이 있다면 코드에 대한 자세한 설명을 제공 할 수 있습니다.

나는 백분율을 사용하여 분수를 만든 다음 가장 낮은 형태의 분수를 구하여 숫자를 알아 내려고 시도했지만 결과의 반올림으로 작동시키는 방법을 알 수 없었습니다.


흠, 이것은 새로운 테스트 사례에서는 실패합니다. 수정을 찾아야합니다.
Gareth

4

파이썬, 154

def r(l):
 v=0
 while 1:
  v+=1;o=[round(y*v/100)for y in l];s=sum(o)
  if s: 
    if all(a==b for a,b in zip(l,[round(y*1000/s)/10for y in o])):return s

+1 좋아 보인다! ideone.com/k2Mgb . 나는 병리학 적 사례를 찾으려고 노력했지만 실패했습니다.
mellamokb

시간 제한을 초과하여 IDE에서 생성 할 수 없지만 어떤 결과를 얻 [0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,99.6]습니까?
mellamokb

흠 ... 30 분 동안 프로그램이 여전히 실행 중입니다. 아마 그것이 브레이커라고 말하는 것이 안전하다고 생각합니다. 그러나 100 %가 아니라 총 100.5 %이기 때문에 어떻게 이것이 올바른 답변이 될 수 있는지 모르겠습니다.
Blazer

2
1/2000 = 0.05%( 0.1%반올림) 및 1991/2000 = 99.55%( 99.6%반올림). 실제로는 총 100 %이지만 반올림으로 인해 실제로 혼란스러워집니다.
grc

3

VBA-541

이것은 눈부신 오류가 있었지만, 사소한 / 반복이 될 때까지 올바른 숫자의 해결책을 찾으려는 시도였습니다. 나는 그것을 완전히 골프화하지는 않았지만, 그 점에서 추가 할 것이 많지 않다고 생각합니다. 그러나 나는 이것에 너무 많은 시간을 보냈고 지금은 내 머리를 아프게합니다. 말할 것도없이, 규칙은 아마도 매우 깨졌으며 이러한 예에만 적용됩니다.

이것은 내가 실행 한 많은 간단한 테스트 (예 : 총 2 ~ 3 개의 입력)에 대해 매우 잘 수행되지만 도전에 의해 제시 된 일부 테스트에서는 실패합니다. 그러나 입력의 십진 정밀도를 높이면 (도전 범위를 벗어난) 정확도가 향상됩니다.

대부분의 작업은 제공된 일련의 숫자에 대한 gcd를 찾는 것과 관련 Function g()이 있습니다.

입력은 공백으로 구분 된 값 문자열입니다.

Const q=10^10
Sub a(s)
e=Split(s)
m=1
f=UBound(e)
For i=0 To f
t=1/(e(i)/100)
m=m*t
n=IIf(n>t Or i=0,t,n)
x=IIf(x<t Or i=0,t,x)
Next
h=g(n,x)
i=(n*x)/(h)
If Int(i)=Round(Int(i*q)/q) Then
r=i
ElseIf (n+x)=(n*x) Then
r=(1/(n*x))/h/m
ElseIf x=Int(x) Then
r=x*(f+1)
Else
z=((n+x)+(n*x)+m)*h
y=m/(((m*h)/(f+1))+n)
r=IIf(y>z,z,y)
End If
Debug.Print Round(r)
End Sub
Function g(a,b)
x=Round(Int(a*q)/q,3)
y=Round(Int(b*q)/q,3)
If a Then
If b Then
If x>y Then
g=g(a-b,b)
ElseIf y>x Then
g=g(a,b-a)
Else
g=a
End If
End If
Else
g=b
End If
End Function

테스트 사례 (입력 ==> 예상 / 반환) :

Passed:  

"95 5" ==> 20/20
"90 10" ==> 10/10
"46.7 53.3" ==> 15/15
"4.7 30.9 40.4 23.8" ==> 42/42
"44.4 44.4 11.1" ==> 9/9
"26.7 53.3 20.0" ==> 15/15
"48.4 13.7 21.6 6.5 9.8" ==> 153/153
"0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 0.05 99.55" ==> 2000/2000
"0.15 0.15 0.15 0.15 0.15 0.15 0.15 0.15 0.15 98.65" ==> 2000/2000
"0.149925 0.149925 0.149925 0.149925 0.149925 0.149925 0.149925 0.149925 0.149925 98.65067" ==> 667/667


Failed:  

"0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 99.6" ==> 2000/1000
"0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 98.7" ==> 2000/5000
"0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 98.7" ==> 667/1000
"0.14 0.14 0.14 0.14 0.14 0.14 0.14 0.14 0.14 98.65" ==> 667/10000
"0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 0.2 97.8" ==> 401/500
"0.24 0.24 0.24 0.24 0.24 0.24 0.24 0.24 0.24 97.75" ==> 401/235
"0.249377 0.249377 0.249377 0.249377 0.249377 0.249377 0.249377 0.249377 0.249377 97.75561" ==> 401/14010

다음으로 변환 Debug.Print 하면 6 바이트를 잃을 수 있습니다.Debug.?
Taylor Scott

2

C # (. NET 코어) , 286 바이트

double M(string[]a){var p=a.Select(double.Parse).ToList();var n=p.Select(x=>1d).ToList();var c=2;for(;;){Func<double,double>f=x=>Math.Round(x*1000/c,(MidpointRounding)1)/10;if(n.Select(f).Zip(p,(x,y)=>x==y).All(z=>z)&&c==n.Sum())return c;c++;n=n.Zip(p,(x,y)=>x+(f(x)<y?1:0)).ToList();}}

온라인으로 사용해보십시오!

Peter Taylor무지의 구현 덕분에 많은 바이트를 절약했습니다.


ideone.com에서 테스트하기 위해 어떻게 이것을 수정할 수 있습니까?
Gareth

나는 당신이 }마지막에 빠진 것 같아요 .
grc

@Gareth ideone.com에서 실행하려고 시도했지만 Linq Zip메서드를 인식하지 못하기 때문에 4.0 이전의 .NET 프레임 워크 버전을 사용하고 있다고 생각합니다 .
Cristian Lupascu

@grc 지적 해 주셔서 감사합니다. 업데이트되었습니다.
Cristian Lupascu

1
@Gaffi : 아니요, C #에는 엄격한 타이핑 (예 : Java)이 있으므로 부울이어야합니다. 1>0보다 짧기 때문에 true바람직하다.
mellamokb

0

파이썬 (3) , 140 (139) 137 바이트

f=lambda l,m=1,i=0,c=0,x=0:round(x*100,1)-l[i]and(x<1and f(l,m,i,c,x+1/m)or f(l,m+1))or l[i+1:]and f(l,m,i+1,c+x)or c+x-1and f(l,m+1)or m

온라인으로 사용해보십시오!

처음 두 테스트 사례에 대한 정답을 제공하고 다른 테스트 사례에 대한 Python의 재귀 한계에 도달합니다. 모든 검사가 새로운 재귀 수준에서 이루어 지기 때문에 이것은 놀라운 일이 아닙니다 . 짧지 만 ...

(사용 된 변수에 대한 설명은 TIO 링크에서 찾을 수 있습니다)

f=lambda l,m=1,i=0,c=0,x=1:round(x*100,1)-l[i]and(x and f(l,m,i,c,x-1/m)or f(l,m+1))or l[i+1:]and f(l,m,i+1,c+x)or c+x-1and f(l,m+1)or m

136 바이트에서 작동 하지만 부동 소수점 정밀도로 인한 것은 아닙니다.

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