เปอร์เซ็นต์จำนวนเต็ม


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สามารถแมปทั้งหมดให้เป็นค่าเดียวกันได้ วิธีนี้ช่วยลดอัลกอริธึมที่ง่ายเกินไปที่ใช้กับกรณีทดสอบก่อนหน้านี้ทั้งหมดเนื่องจากการปัดเศษไม่ได้เลวร้ายเกินไป
Sophia Lechner

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
ถ้าแฟร์มาต์เพียงคนเดียวอาจเรียนกอล์ฟจากคุณ
TessellatingHeckler

1
@TessellatingHeckler ฉันเห็นสิ่งที่คุณทำที่นั่น บางทีเขาอาจจะมีที่ว่างเพียงพอในระยะขอบสำหรับการพิสูจน์ของเขา :)
mbomb007

14

TI-BASIC, 26 23 16 ไบต์

สำหรับเครื่องคิดเลขชุด TI-83 + / 84 +

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

ขอบคุณ @Dennis สำหรับอัลกอริทึมที่สวยงาม! เรานำผลรวมสะสมของรายการหลังจากแปลงเป็นเปอร์เซนต์จากนั้นตามด้วยชั้นต่อท้าย tack 0 ลงบนด้านหน้าและรับความแตกต่าง เป็นหนึ่งไบต์สั้นกว่าᴇ2100

ที่จำนวนไบต์เดียวกันคือ:

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

ความจริงแล้วสนุก: %เป็นโทเค็นสองไบต์ที่คูณด้วย 0.01 แต่ไม่มีวิธีที่จะพิมพ์ลงในเครื่องคิดเลข! คุณต้องแก้ไขแหล่งภายนอกหรือใช้แอสเซมบลีโปรแกรม

รหัสเก่า:

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

บรรทัดแรกจะคำนวณเปอร์เซ็นต์การปูพื้นทั้งหมดจากนั้นบรรทัดที่สองจะเพิ่ม 1 ให้กับNองค์ประกอบแรกโดยที่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
นาที

@DavidArenburg นี่เป็นเพียงรูปแบบที่มนุษย์อ่านได้ ราชสกุลทุกชนิด ( int(, sum(, Ansฯลฯ ) ครอบครองเพียงหนึ่งไบต์
Dennis

4
+1 นี่คือหนึ่งในสนามกอล์ฟ TI-BASIC ที่น่าประทับใจที่สุดที่ฉันเคยเห็นในเว็บไซต์นี้
PhiNotPi

โทมัสคำตอบนี้น่าทึ่ง!
DaveAlger

คุณแน่ใจหรือไม่ว่าไม่สามารถใส่%สัญลักษณ์ได้ ฉันคิดว่ามันสามารถพบได้ในแคตตาล็อกสัญลักษณ์ ... นอกจากนี้ฉันควรออก TI-84 + เงินของฉันด้วย ฉันไม่ได้ใช้งานมาระยะหนึ่งแล้ว Block Dude ยอดเยี่ยมมาก
mbomb007

7

CJam, 25 23 22 ไบต์

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

ขอบคุณ @ Sp3000 สำหรับ 25 → 24

ลองออนไลน์

มันทำงานอย่างไร

_                   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

Mathematica, 41 ไบต์

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

เดี๋ยวก่อนเกิดอะไรขึ้นที่นี่
seequ

@Seeq อัลกอริทึมก็เหมือนรหัสเก่าในคำตอบ TI-BASIC มันคำนวณเปอร์เซ็นต์ของการปูพื้นทั้งหมดแล้วเพิ่ม 1 ลงในNองค์ประกอบแรกโดยที่Nเปอร์เซ็นต์ที่เหลืออยู่
alephalpha

5

J (8.04 เบต้า) , 59 ไบต์ (30 ไบต์ที่ถูกขโมย)

ตัวอักษร J-port ขนาด 30 ไบต์ของคำตอบ APL ของ Dennis :

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

    f 1 1 2 4
12 13 25 50

59 bytes ตอบที่ดีที่สุดที่ฉันสามารถทำได้เอง:

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

(ขึ้นอยู่กับส่วนที่เหลือจะต้องไปที่ค่าสูงสุดไม่เกิน +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)ค่าเหล่านั้นคือ 100x: 33.33.. 0 0.66...เพื่อให้ได้เปอร์เซ็นต์
    • <. (100*y%+/y) เป็นตัวดำเนินการพื้นที่ใช้กับเปอร์เซ็นต์: 33 0 66
  • r=. ตัวแปร 'r' สร้างจาก:
    • +/p คือผลรวมของเปอร์เซ็นต์ที่ปูพื้น: 99
    • 100 - (+/p) คือ 100 - ผลรวมหรือคะแนนเปอร์เซ็นต์ที่เหลือจำเป็นต้องใช้เพื่อทำให้ผลรวมเป็น 100
  • ผลไม่ได้เก็บไว้:
    • r $ 1 คือรายการ 1s ตราบใดที่จำนวนรายการที่เราต้องการเพิ่ม: 1 [1 1 ..]
    • #p คือความยาวของรายการเปอร์เซ็นต์
    • (#p - r) คือจำนวนของรายการที่จะไม่เพิ่มขึ้น
    • (#p-r) $ 0 คือรายการ 0s ตราบใดที่นับ: 0 0 [0 ..]
    • ((r$1) , (#p-r)$0) คือรายการ 1s ตามด้วยรายการ 0s: 1 0 0
    • \: pเป็นรายการของดัชนีที่จะนำมาจากpเพื่อวางไว้ในลำดับถัดลงมา
    • /: (\:p)เป็นรายการของดัชนีที่จะนำมาจาก\:pการเรียงลำดับจากน้อยไปมาก
    • ((r$1),(#p-r)$0)/:\:pคือการองค์ประกอบจาก 1 1 0 0 .. .. หน้ากากและการเรียงลำดับรายการจึงมี 1s ในตำแหน่งของเปอร์เซ็นต์ที่ใหญ่ที่สุดหนึ่งสำหรับจำนวนที่เราต้องการที่จะเพิ่มขึ้นในแต่ละครั้งและ 0s สำหรับตัวเลขอื่น ๆ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

และ

  • ) จุดสิ้นสุดของคำจำกัดความ

ฉันไม่ค่อยมีประสบการณ์กับเจมาก ฉันจะไม่ต้องแปลกใจเกินไปถ้ามีรายการ "กลายเป็นเปอร์เซ็นต์ของทั้งหมด" การดำเนินการในตัวและเป็นวิธีทำความสะอาดเพื่อ "เพิ่มnค่าที่ใหญ่ที่สุด" เกินไป (นี่คือ 11 ไบต์น้อยกว่าความพยายามครั้งแรกของฉัน)


1
เด็ดมาก ฉันมีวิธีการแก้ปัญหาหลาม แต่มันยาวกว่านี้มาก เยี่ยมมาก!
DaveAlger

1
หากคุณไม่ได้สังเกตเห็นว่ากฎมีการเปลี่ยนแปลงดังนั้นคุณควรจะสามารถย่อให้สั้นลงได้มาก
lirtosiast

@DaveAlger ขอบคุณ! @ThomasKwa ฉันสังเกตุเห็นว่าฉันไม่แน่ใจว่ามันช่วยฉันได้มาก - ตอนแรกฉันจะได้ตัวละคร -2 ตัว ฉันจะต้องเปลี่ยนlist[0:100-n] + list[:-100-n]วิธีการ - และฉันไม่ได้คิดวิธีอื่นที่จะเข้าใกล้มัน
TessellatingHeckler

4

JavaScript (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 จากตัวเองและเพิ่มไปยังหมายเลขปัจจุบัน ปัญหาก็คือจุดลอยตัวซึ่งหมายถึงบางสิ่งเช่น [1,1,1] ออกจากส่วนที่เหลือเป็น. 99999999999999998 ดังนั้นฉันจึงเปลี่ยนเช็คให้มากกว่า 0.999 และตัดสินใจที่จะโทรหาที่แม่นยำพอ


4

Haskell, 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

ลองออนไลน์!

ทำควบคู่ไปกับcaird coinheringaahingและuser202729ในการแชทการแชท

มันทำงานอย่างไร

0; + \ ÷ S ×ȷ2ḞI - โปรแกรมแบบเต็ม

0; - เติม 0
  + \ - ผลรวมสะสม
    ÷ S - หารด้วยผลรวมของอินพุต
      ×ȷ2 - คูณ 100 แทนที่ด้วย׳ในลิงค์ลิงค์รุ่น monadic
         Ḟฉัน - แต่ละชั้นคำนวณส่วนที่เพิ่มขึ้น (เดลต้าความแตกต่าง)


3

Perl, 42 ไบต์

ขึ้นอยู่กับอัลกอริทึมของเดนนิส

รวม +1 สำหรับ -p

เรียกใช้ด้วยรายการตัวเลขใน STDIN เช่น

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

percent.pl:

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


2

Python 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

JavaScript (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

อันสุดท้ายควรจะมากที่สุดโดย 98 แต่มันเป็น 100
l4m2

@ l4m2 เอ่อถูกต้องขอบคุณเวลาคิดใหม่อีกครั้ง
edc65

@ 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

JavaScript ขนาด 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

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%
Sophia Lechner

@SophiaLechner คำตอบใดที่ถูกต้อง?
ติตัส

ส่วนใหญ่ทำจริง คำตอบที่ถูกต้องดูเหมือนจะถูกสร้างขึ้นรอบหนึ่งในสองอัลกอริทึม; รอบแรกปิดเปอร์เซ็นต์ของผลรวมสะสมและรับผลต่าง ส่วนที่สองจะคำนวณชั้นของเปอร์เซ็นต์และเพิ่มเปอร์เซ็นต์ที่แตกต่างกันมากพอที่จะนำมารวมเป็น 100
Sophia Lechner

@SophiaLechner ฉันไม่ได้หมายความว่าฉันจะไม่มองมัน แต่ฉันจะทำในภายหลัง ขอบคุณที่สังเกต
ติตัส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.