정수 백분율


21

양의 정수 목록을 가져와 같은 위치에있는 해당 정수에 대한 총 백분율을 근사하는 정수 목록을 리턴하는 함수를 작성하십시오.

리턴 목록의 모든 정수는 정확히 100을 더해야합니다. 전달 된 정수의 합이 0보다 크다고 가정 할 수 있습니다. 소수를 반올림하거나 자르는 방법은 단일 결과 정수가 백분율로 리턴되는 한 사용자에게 달려 있습니다. 어느 방향으로도 1만큼만 꺼져 있습니다.

p([1,0,2])      ->  [33,0,67] or [34,0,66]
p([1000,1000])  ->  [50,50]
p([1,1,2,4])    ->  [12,12,25,51] or [13,12,25,50] or [12,13,25,50] or [12,12,26,50]
p([0,0,0,5,0])  ->  [0,0,0,100,0]

이것은 이므로 바이트 단위의 가장 짧은 코드가 이깁니다!


알고리즘이 결정적이어야합니까? 제한된 시간 내에 항상 종료해야합니까?
lirtosiast

우리는 이미 유사하지만 좀 더 일반적인 몇 가지 반올림 문제가 있었다
edc65

1
다른 테스트 사례를 추가하는 것이 좋습니다 p([2,2,2,2,2,3]).. 많은 법적 답변이 있지만 모든 2값을 동일한 값으로 매핑 할 수있는 것은 아닙니다 . 이것은 반올림이 나쁘지 않기 때문에 이전의 모든 테스트 사례에서 작동하는 지나치게 간단한 알고리즘을 제거합니다.
소피아 레크 너

4
할 수 있습니까 p([1000,1000]) -> [49,51]?
l4m2

1
이 사양은 다음과 있도록 @ l4m2, 더 이상 그것은 잘못된 것 같다,하지만 모두 결과는 1 꺼져 있고
edc65

답변:


20

Dyalog APL, 21 19 16 바이트

+\⍣¯1∘⌊100×+\÷+/

위의 열차는

{+\⍣¯1⌊100×+\⍵÷+/⍵}

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

작동 원리

                 ⍝ Sample input: 1 1 2 4
           +\    ⍝ Cumulative sum of input. (1 2 4 8)
              +/ ⍝ Sum of input. (8)
             ÷   ⍝ Divide the first result by the second. (0.125 0.25 0.5 1)
       100×      ⍝ Multiply each quotient by 100. (12.5 25 50 100)
      ⌊          ⍝ Round the products down to the nearest integer... (12 25 50 100)
     ∘           ⍝ and ...
  ⍣¯1            ⍝ apply the inverse of...
+\               ⍝ the cumulative sum. (12 13 25 50)

9
Fermat만이 당신에게서 골프 레슨을받을 수 있다면.
TessellatingHeckler

1
@TessellatingHeckler 나는 당신이 무엇을했는지 봅니다. 어쩌면 그는 증거를 위해 여백에 충분한 공간이 있었을 것입니다. :)
mbomb007

14

TI-BASIC, 26 23 16 바이트

TI-83 + / 84 + 시리즈 계산기 용.

ΔList(augment({0},int(cumSum(ᴇ2Ans/sum(Ans

아름다운 알고리즘을위한 @Dennis에 감사합니다! 우리는 퍼센트로 변환 한 후 목록의 누적 합계를 취한 다음 바닥에 0을 앞에 붙인 다음 차이를 취합니다. ᴇ2보다 1 바이트 짧습니다 100.

동일한 바이트 수는 다음과 같습니다.

ΔList(augment({0},int(cumSum(Ans/sum(Ans%

재미있는 사실은 : %A는 2 바이트 토큰 에 의해 곱셈 숫자 .01 -하지만 계산기에 입력 할 수있는 방법이 없습니다! 외부에서 소스를 편집하거나 어셈블리 프로그램을 사용해야합니다.

오래된 코드 :

int(ᴇ2Ans/sum(Ans
Ans+(ᴇ2-sum(Ans)≥cumSum(1 or Ans

첫 번째 줄은 모든 바닥 백분율을 계산 한 다음 두 번째 줄은 첫 번째 N요소에 1을 더합니다 N. cumSum("누적 합계"를 나타냅니다.

{1,1,2,4}:

          sum(Ans                  ; 8
int(ᴇ2Ans/                         ; {12,12,25,50}

                        1 or Ans   ; {1,1,1,1}
                 cumSum(           ; {1,2,3,4}
     ᴇ2-sum(Ans)                   ; 1
                ≥                  ; {1,0,0,0}
Ans+                               ; {13,12,25,50}

우리는 필요가 없습니다 N>dim([list]더 비율이 바닥재에 1 개 이상 감소하지 않기 때문에.


확실하지가 카운트 여기 바이트 방법, 그것은 나에게 무섭게 이상 23 이상의 보인다
데이비드 Arenburg

@DavidArenburg 이것은 사람이 읽을 수있는 형태 일뿐입니다. 모든 토큰 ( int(, sum(, Ans, 등)은 하나의 바이트를 차지합니다.
Dennis

4
+1이 사이트에서 본 가장 인상적인 TI-BASIC 골프 중 하나입니다.
PhiNotPi

토마스이 대답은 놀랍습니다!
DaveAlger

%기호 를 입력 할 방법이 없습니까? 심볼 카탈로그에서 찾을 수 있다고 생각했을 것입니다 ... 또한 TI-84 + Silver를 꺼내야합니다. 한동안 사용하지 않았습니다. Block Dude는 대단합니다.
mbomb007

7

CJam, 25 23 22 바이트

{_:e2\:+f/_:+100-Xb.+}

25 → 24의 @ Sp3000에 감사합니다.

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

작동 원리

_                   e# Push a copy of the input.
 :e2                e# Apply e2 to each integer, i.e., multiply by 100.
    \               e# Swap the result with the original.
     :+             e# Add all integers from input.
       f/           e# Divide the product by the sum. (integer division)
        _:+         e# Push the sum of copy.
           100-     e# Subtract 100. Let's call the result d.
               Xb   e# Convert to base 1, i.e., push an array of |d| 1's.
                 .+ e# Vectorized sum; increment the first |d| integers.

5

수학, 41 바이트

(s=Floor[100#/Tr@#];s[[;;100-Tr@s]]++;s)&

잠깐, 여기서 어떻게됩니까?
seequ

@Seeq 알고리즘은 TI-BASIC 답변의 이전 코드와 같습니다. 모든 바닥재 백분율을 계산 한 다음 첫 번째 N요소에 1을 더합니다 N.
alephalpha

5

J (8.04 베타) , 59 바이트 (도난당한 30 바이트)

Dennis APL 응답의 30 바이트 리터럴 J- 포트 :

    f=.3 :'+/\^:_1<.100*(+/\%+/)y'

    f 1 1 2 4
12 13 25 50

59 바이트 대답, 내가 할 수있는 최선의 방법 :

f=.3 :0
p=.<.100*y%+/y
r=.100-+/p
p+((r$1),(#p-r)$0)/:\:p
)

(나머지가 1보다 크지 않은 나머지 값을 기준으로 나머지는 1보다 크거나 나머지 값이 1보다 큰 경우 또는 여러 값으로 분할됩니다).

예 :

   f 1 0 2
33 0 67

   f 1000 1000
50 50

   f 1 1 2 4
12 12 25 51

   f 0 0 0 5 0
0 0 0 100 0

   f 16 16 16 16 16 16
17 17 17 17 16 16

   f 0 100 5 0 7 1
0 89 4 0 7 0

설명

  • f=.3 : 0 - 'f'는 변수이며, 동사 유형 (3)이며 아래에 정의되어 있습니다 (: 0) :
  • p=. 변수 'p', 내장 :
    • y 숫자의 목록입니다 1 0 2
    • +/y 각 값 '/'사이의 '+', 목록의 합계 3
    • y % (+/y) 원래 y 값을 합계로 나눈 값입니다. 0.333333 0 0.666667
    • 100 * (y%+/y)33.33.. 0 0.66...백분율을 얻으려면 그 값의 100 배 입니다.
    • <. (100*y%+/y) 비율에 적용된 층 연산자입니다. 33 0 66
  • r=. 변수 'r', 내장 :
    • +/p 층별 백분율의 합입니다. 99
    • 100 - (+/p) 100-합계 또는 백분율을 100으로 만드는 데 필요한 나머지 백분율 포인트
  • 저장되지 않은 결과 :
    • r $ 1 증분해야하는 항목 수가있는 한 1의 목록입니다. 1 [1 1 ..]
    • #p 백분율 목록의 길이입니다
    • (#p - r) 증분되지 않는 항목의 수
    • (#p-r) $ 0 그 수만큼 0의 목록입니다. 0 0 [0 ..]
    • ((r$1) , (#p-r)$0) 1s 목록 다음에 0s 목록이 있습니다. 1 0 0
    • \: pp내림차순으로 넣을 인덱스 목록입니다 .
    • /: (\:p) 가져올 인덱스 목록입니다 \:p오름차순으로 넣을
    • ((r$1),(#p-r)$0)/:\:p1 1 .. 0 0 .. 마스크 목록에서 요소를 가져 와서 정렬하므로 가장 큰 백분율 위치에 1이 있습니다. 증가 해야하는 각 숫자마다 하나씩, 다른 숫자는 0입니다 0 0 1.
    • p + ((r$1),(#p-r)$0)/:\:p 100 %에 해당하는 결과 목록을 작성하기위한 백분율 + 마스크입니다. 이것이 함수 리턴 값입니다.

예 :

33 0 66 sums to 99
100 - 99 = 1
1x1 , (3-1)x0 = 1, 0 0
sorted mask   = 0 0 1

33 0 66
 0 0  1
-------
33 0 67

  • ) 정의의 끝.

나는 J에 익숙하지 않다. "전체 목록의 백분율로 전환"작업이 내장되어 있고 " n 개의 가장 큰 값을 증가시키는"더 확실한 방법이 있다면 놀라지 않을 것 입니다. (이것은 내 첫 시도보다 11 바이트 적습니다).


1
매우 시원합니다. 나는 파이썬 솔루션을 가지고 있지만 이것보다 훨씬 길다. 잘 하셨어요!
DaveAlger

1
눈치 채지 못한 경우 규칙이 변경되었으므로이를 크게 줄일 수 있습니다.
lirtosiast

@DaveAlger 감사합니다! @ThomasKwa 나는 그것이 상당히 도움이 될지 확신하지 못합니다. 먼저 -2 문자를 얻을 수 있습니다. 나는 list[0:100-n] + list[:-100-n]접근 방식 을 바꿔야 할 필요가 있으며 접근하는 다른 방법을 생각하지 않았습니다.
TessellatingHeckler

4

자바 스크립트 (ES6), 81 바이트

a=>(e=0,a.map(c=>((e+=(f=c/a.reduce((c,d)=>c+d)*100)%1),f+(e>.999?(e--,1):0)|0)))

(반올림과 합산이 아니라) "100과 같아야한다"는 조건은 44에서 81로 거의 두 배가되었다. 트릭은 1에 도달하면 1을 자체에서 가져와 현재 숫자에 더하는 10 진수 값의 냄비를 추가하는 것입니다. 그런 다음 문제는 부동 소수점이었습니다. [1,1,1]과 같이 나머지는 .9999999999999858입니다. 그래서 나는 수표를 .999보다 크게 변경하고 그것을 정확하게 호출하기로 결정했습니다.


4

하스켈, 42 27 바이트

p a=[div(100*x)$sum a|x<-a]

Haskell의 사소한 방법으로 골프를 위해 몇 개의 공간이 제거되었습니다.

콘솔 (예와 일치하도록 브래킷 포함) :

*Main> p([1,0,2])
[33,0,66]
*Main> p([1000,1000])
[50,50]
*Main> p([1,1,2,4])
[12,12,25,50]
*Main> p([0,0,0,5,0])
[0,0,0,100,0]

편집 : 내 퍼팅을 연습하고 명백한 교체를했습니다.

기발한:

p xs=[div(x*100)tot|x<-xs]where tot=sum xs

1
목록의 합계는 100이어야합니다. 첫 번째 예에서는 99
Damien

4

젤리 , 7 바이트

-2 데니스 덕분에 다른 새로운 기능 ( Ä)을 사용하고 :처음에 사용했던 기능 대신 사용하도록 상기시켜줍니다 .

ŻÄ׳:SI

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

젤리 , 11 바이트

0;+\÷S×ȷ2ḞI

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

함께 완료 케어 드 coinheringaahinguser202729 에서 채팅 .

작동 원리

0; + \ ÷ S × ȷ2ḞI-전체 프로그램.

0; -앞에 0을 붙입니다.
  + \-누적 합계
    ÷ S-입력의 합으로 나눈 값입니다.
      × ȷ2-시간 100. 모나 딕 링크 버전에서 × ³으로 대체되었습니다.
         ḞI-각각 바닥, 증분 (델타, 차이)을 계산합니다.

3

하스켈, 63 56 55 바이트

p l=tail>>=zipWith(-)$[100*x`div`sum l|x<-0:scanl1(+)l]

3

펄, 42 바이트

Dennis의 알고리즘을 기반으로

에 +1 포함 -p

예를 들어 STDIN의 숫자 목록으로 실행

perl -p percent.pl <<< "1 0 2"

percent.pl:

s%\d+%-$-+($-=$a+=$&*100/eval y/ /+/r)%eg


2

파이썬 2, 89 바이트

def f(L):
 p=[int(x/0.01/sum(L))for x in L]
 for i in range(100-sum(p)):p[i]+=1
 return p

print f([16,16,16,16,16,16])
print f([1,0,2])

->

[17, 17, 17, 17, 16, 16]
[34, 0, 66]

2

Brain-Flak , 150 바이트

((([]){[{}]({}<>)<>([])}{})[()])<>([]){{}<>([{}()]({}<([()])>)<>(((((({})({})({})){}){}){}{}){}){}(<()>))<>{(({}<({}())>)){({}[()])<>}{}}{}([])}<>{}{}

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

이 코드는 끝에서 시작하여 역순으로 작업하기 때문에 각 단계에서 지금까지의 출력 숫자의 합이 반올림 한 총 백분율과 같아집니다.

(

  # Compute and push sum of numbers
  (([]){[{}]({}<>)<>([])}{})

# And push sum-1 above it (simulating a zero result from the mod function)
[()])

<>

# While elements remain
([]){{}

  # Finish computation of modulo from previous step
  <>([{}()]({}

    # Push -1 below sum (initial value of quotient in divmod)
    <([()])>

  # Add to 100*current number, and push zero below it
  )<>(((((({})({})({})){}){}){}{}){}){}(<()>))

  # Compute divmod
  <>{(({}<({}())>)){({}[()])<>}{}}{}

([])}

# Move to result stack and remove values left over from mod
<>{}{}

2

자바 스크립트 (ES6) 60 63 95

다른 도전에 대한 나의 (잘못 된) 대답 에서 적응하고 단순화
이것이 잘못되었다는 것을 발견 한 Thk @ l4m2에 대한

1 바이트 저장 (및 이름을 세지 않고 2 바이트 감소 F=)

v=>v.map(x=>(x=r+x*100,r=x%f,x/f|0),f=eval(v.join`+`),r=f/2)

EcmaScript 6 호환 브라우저에서 아래 스 니펫 실행 테스트

F=
v=>v.map(x=>(x=r+x*100,r=x%f,x/f|0),f=eval(v.join`+`),r=f/2)

console.log('[1,0,2] (exp [33,0,67] [34,0,66])-> '+F([1,0,2]))
console.log('[1000,1000] (exp [50,50])-> '+F([1000,1000]))
console.log('[1,1,2,4] (exp[12,12,25,51] [13,12,25,50] [12,13,25,50] [12,12,26,50])-> '+F([1,1,2,4]))
console.log('[0,0,0,5,0] (exp [0,0,0,100,0])-> '+F([0,0,0,5,0]))
console.log('[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,980] -> '+F([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,980]))
console.log('[2,2,2,2,2,3] -> ' + F([2,2,2,2,2,3]))
<pre id=O></pre>


실패[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,980]
l4m2

@ l4m2가 실패한 이유는 무엇입니까? 합계는 100과any single resulting integer returned as a percentage is off by no more than 1 in either direction.
edc65 8:19에

마지막 것은 98까지 최대 한 번
떨어져야

@ l4m2 어, 그래,
고마워.

@ l4m2는 이제 수정되어야합니다
edc65

1

녹, 85 바이트

내가 아는 한 여러 길이의 배열을 받아 들일 수있는 방법이 없기 때문에 배열 대신 벡터를 사용합니다.

let a=|c:Vec<_>|c.iter().map(|m|m*100/c.iter().fold(0,|a,x|a+x)).collect::<Vec<_>>();

1

자바 스크립트, 48 바이트

F=

x=>x.map(t=>s+=t,y=s=0).map(t=>-y+(y=100*t/s|0))

// Test 
console.log=x=>O.innerHTML+=x+'\n';


console.log('[1,0,2] (exp [33,0,67] [34,0,66])-> '+F([1,0,2]))
console.log('[1000,1000] (exp [50,50])-> '+F([1000,1000]))
console.log('[1,1,2,4] (exp[12,12,25,51] [13,12,25,50] [12,13,25,50] [12,12,26,50])-> '+F([1,1,2,4]))
console.log('[0,0,0,5,0] (exp [0,0,0,100,0])-> '+F([0,0,0,5,0]))
<pre id=O></pre>


0

Jq 1.5 , 46 바이트

add as$s|.[1:]|map(100*./$s|floor)|[100-add]+.

넓히는

  add as $s               # compute sum of array elements
| .[1:]                   # \ compute percentage for all elements 
| map(100*./$s|floor)     # / after the first element
| [100-add] + .           # compute first element as remaining percentage

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


0

PHP, 82 바이트

for(;++$i<$argc-1;$s+=$x)echo$x=$argv[$i]/array_sum($argv)*100+.5|0,_;echo 100-$s;

명령 줄 인수에서 입력을 받고 밑줄로 구분 된 백분율을 인쇄합니다.

온라인으로 실행 -nr하거나 사용해보십시오 .


이 출력 15_15_15_15_15_25은 입력이 지정되었을 때에 [2,2,2,2,3]오른쪽 때문에 아니다3/13 ~= 23.1%
소피아 흐너

@SophiaLechner 정답은 무엇입니까?
Titus

실제로는 대부분입니다. 지금까지 정답은 두 알고리즘 중 하나를 중심으로 구축 된 것 같습니다. 첫 번째는 누적 합계의 백분율을 반올림하고 차이를 가져옵니다. 두 번째 계산 한 후 백분율의 바닥과는 100에 총을 가지고 충분한 별개의 비율을 증가
소피아 레 흐너에게

@SophiaLechner 나는 그것을 보지 않을 것을 의미하지 않았다; 하지만 나중에 할게 알아 주셔서 감사합니다.
Titus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.