Binning ในเวลา


12

ภารกิจในการท้าทายนี้คือการใส่องค์ประกอบของอาร์เรย์ลงในถังขยะเวลา อินพุตจะเป็นอาร์เรย์จำนวนเต็มบวกที่ไม่ลดลงซึ่งแสดงเวลาของเหตุการณ์และจำนวนเต็มซึ่งแทนขนาดของแต่ละ bin ให้เราเริ่มด้วยตัวอย่าง เราเรียกอาร์เรย์อินพุทและเอาท์พุทอาร์เรย์AO

`A = [1,1,1,2,7,10]` and `bin_size = 2`.

`O = [4,0,0,1,1]`.

ทำไม ? ด้วยbin_size = 2เราจะมีช่วงเวลาต่อไปนี้: (0,2], (2,4], (4,6], (6,8], (8,10]ที่สี่รายการ(1,1,1,2)อยู่ในช่วงแรก(0,2]ไม่มีใครในช่วงที่สองและสามซึ่งเป็นหนึ่ง7ในช่วงเวลา(6,8]และเป็นหนึ่งในช่วงเวลา10(8,10]

รหัสของคุณควรพิจารณาทุกช่วงเวลาที่มีความยาวbin_sizeเริ่มต้น0และนับจำนวนที่Aมีในแต่ละตัว คุณควรมีปลายด้านขวามือของช่วงเวลาในถังเพื่อให้ในตัวอย่างข้างต้นจะถูกรวมอยู่ในจำนวนของ2 4รหัสของคุณควรทำงานในเวลาเชิงเส้นในผลรวมของความยาวของอินพุตและเอาต์พุต

ตัวอย่างเพิ่มเติม:

`A = [1,2,7,12,15]`  and `bin_size = 5`.

`O = [2, 1, 2]`.

`A = [1,2,7,12,15]`  and `bin_size = 3`.

`O = [2,0,1,1,1]`.

คุณสามารถสันนิษฐานได้ว่าอินพุตและเอาต์พุตสามารถให้ในรูปแบบที่คุณสะดวก คุณสามารถใช้ภาษาและห้องสมุดที่คุณต้องการ


0อนุญาตให้ใช้เอาต์พุตที่มีการต่อท้ายหรือไม่ ดังนั้นการกลับมา[2,0,1,1,1,0]แทน[2,0,1,1,1]?
Kevin Cruijssen

โปรดไม่มีเลขศูนย์ต่อท้าย

2
สิ่งที่เกี่ยวกับสถานการณ์ที่ค่าอาเรย์สูงสุดไม่ได้เป็นหลายตัวbin_sizeเราควรจัดการกับสิ่งเหล่านี้หรือไม่? ดูเหมือนว่าคำตอบส่วนใหญ่จะทำ แต่ถ้าเป็นเช่นนั้นจะเป็นการดีถ้าเพิ่มกรณีทดสอบสำหรับสถานการณ์นี้เพื่อป้องกันความสับสน
Kirill L.

@KirillL ใช่พวกเขาควรได้รับการจัดการเช่นกัน

1
@GPS 0 ไม่ใช่จำนวนเต็มบวก นี่ไม่ใช่อุบัติเหตุ :)

คำตอบ:


9

R , 48 ไบต์

function(n,s)table(cut(n,0:ceiling(max(n)/s)*s))

ลองออนไลน์!

อีกครั้งtableและcutการfactorทำเคล็ดลับสำหรับการ binning เอาท์พุทที่มีชื่อvectorที่มีช่วงเวลาในการบันทึกช่วงเวลาตัวอย่างเช่นnames(0,5]

แก้ไข: เปลี่ยนกลับไปใช้รุ่นก่อนหน้านี้ว่าผลงานเมื่อไม่ได้แบ่งsn


ฉันไม่ได้ R จริงๆ แต่ใน TIO นี้ดูเหมือนจะส่งออกformat you [most likely do not] find convenientโดยไม่ต้องมีtableส่วน
สรรพนามของฉันคือ monicareinstate

@someone นั่นเป็นสาเหตุที่แน่ชัด cutแยกเวกเตอร์เป็นปัจจัยที่มีระดับตามช่วงเวลาและtableนับการเกิดขึ้นของค่าเฉพาะแต่ละค่าในอินพุตของมัน
Giuseppe

1
@someone อ่าฉันเข้าใจแล้วฉันเข้าใจความคิดเห็นของคุณผิด ไม่ฉันคิดว่ามันจะไม่ถูกต้องเพราะเราต้องการจำนวนของถังขยะแต่ละถัง
จูเซปเป้

1
ไม่ได้ทดสอบอย่างเต็มที่ แต่ฉันคิดว่าคุณสามารถบันทึกไบต์คู่ reaplacing กับ0:ceiling(max(n)/s)*s seq(0,max(n)+s-1,s)มันทำงานอย่างน้อยสองตัวอย่างในคำถาม
Gregor Thomas

1
@ Gregor อืมถ้ามันทำงาน1:max(n/s+1)*s-sได้ดีขึ้นอีกเพราะทั้งสองสิ่งนี้มีค่าเท่ากัน
Giuseppe



3

Python 2 , 62 ไบต์

I,s=input()
B=[0]*(~-I[-1]/s+1)
for i in I:B[~-i/s]+=1
print B

ลองออนไลน์!


1
ก่อนอื่น: คำตอบที่ดีฉันได้ +1 มันแล้ว (และสร้างพอร์ตใน Java เพราะมันค่อนข้างสั้นกว่าที่ฉันมี) ศูนย์ต่อท้ายไม่ได้รับอนุญาต (เพิ่งถาม OP) ดังนั้นI[-1]/s+1ควรจะ~-I[-1]/s+1แทน
Kevin Cruijssen

@KevinCruijssen ขอบคุณสำหรับการแจ้งเตือน!
Dead Possum

3

05AB1E , 18 ไบต์

θs/Å0¹vDyI/î<©è>®ǝ

ลองออนไลน์!


ผมไม่ทราบว่า 05AB1E ที่ดี แต่นี้ดูเหมือนว่าจะเรียกA.count สูงสุด (A) , ทำงานดังนั้นเวลาไม่เป็นเชิงเส้นในlen (A) + len (O) ถูกต้องหรือว่าฉันทำอะไรผิดไป?
Dennis

@ จำนวนเดนนิสจะเป็นO(max(A)*max(A))... ดังนั้นมันเป็นกำลังสองในค่าสูงสุด A ... OP ระบุว่ามันต้องเป็นเชิงเส้นในแง่ของ ... อะไรกันแน่
Magic Octopus Urn

2
@MagicOctopusUrn รหัสของคุณควรทำงานในเวลาเชิงเส้นในผลรวมของความยาวของอินพุตและเอาต์พุตตามการแก้ไขล่าสุด
Dennis

2
@D เดนนิสที่ดูเหมือนว่าค่อนข้างจะเป็นไป
Magic Octopus Urn

2
@ MagicOctopusUrn มันเป็นคำจำกัดความที่สมเหตุสมผลสำหรับเวลาเชิงเส้นสำหรับคำถามนี้ฉันคิดว่า

2

APL + WIN, 23 ไบต์

แจ้งให้ใส่หน้าจอของถังขยะแล้วเวกเตอร์ของจำนวนเต็ม:

+⌿<\v∘.≤b×⍳⌈⌈/(v←⎕)÷b←⎕    

คำอธิบาย:

⎕ Prompt for input

⌈⌈/(v←⎕)÷b←⎕ divide the integers by bin size, take maximum and round up for number of bins

b×⍳ take number of bins from previous step and create a vector of bin upper boundaries

v∘.≤ apply outer product to generate boolean matrix where elements of vector ≤ boundaries

<\ switch off all 1's after first 1 in each row to filter multiple bin allocations

+⌿ sum columns for the result


2

Java 8, 75 ไบต์

a->b->{var r=new int[~-a[a.length-1]/b+1];for(int i:a)r[~-i/b]++;return r;}

คำตอบ Python 2ของ Port of @ DeadPossum ดังนั้นอย่าลืมโหวตคำตอบของเขา!

คำอธิบาย:

ลองออนไลน์

a->b->{          // Method with integer-array and integer parameters and no return-type
  var r=new int[~-a[a.length-1]/b+1];
                 //  Result integer-array of size `((last_item-1)/bin_length)+1`
  for(int i:a)   //  Loop over the input-array
    r[~-i/b]++;  //   Increase the value at index `(i+1)/bin_length` by 1
  return r;}     //  Return the result-array


2

JavaScript (ES6), 60 ไบต์ / O (len (a) + สูงสุด (a) / n)

บันทึก 5 ไบต์ด้วย @Neil

(a)(n)จะเข้าในไวยากรณ์ currying

a=>n=>[...a.map(x=>o[x=~-x/n|0]=-~o[x],o=[])&&o].map(n=>~~n)

ลองออนไลน์!

หรือเพียง43 ไบต์ / O (len (a))หากองค์ประกอบที่ว่างเปล่าได้รับอนุญาต


[...o].map(n=>n|0)รับเอาต์พุตแรกจากโซลูชันที่สองด้วยจำนวนไบต์ที่น้อยลง
Neil

@ Neil ไม่แน่ใจว่าทำไมฉันไปเพื่ออะไรที่ซับซ้อน : - /
Arnauld

2

Haskell , 63 75 70 ไบต์

l!n=l#[n,2*n..]
[]#_=[]
l#(b:i)|h<-length$takeWhile(<=b)l=h:drop h l#i

อ๊ะอันที่สั้นกว่านี้ไม่เชิงเส้น แต่เป็นกำลังสอง

l!n=l#[n,2*n..]
[]#_=[]
l#(b:i)=sum[1|a<-l,a<=b]:[a|a<-l,a>b]#i

ลองออนไลน์!


1

Pyth, 23 22 ไบต์

Jm/tdeQhQK*]ZheJhXRK1J

ลองที่นี่

Jm/tdeQhQK*]ZheJhXRK1J
Jm/tdeQhQ                 Find the bin for each time and save them as J.
         K*]ZheJ          Create empty bins.
                 XRK1J    Increment the bins for each time within them.
                h         Take the first (because mapping returned copies).

1

Ruby , 53 50 ไบต์

แก้ไข: -3 ไบต์โดย iamnotmaynard

->a,b{(0..~-a.max/b).map{|i|a.count{|x|~-x/b==i}}}

ลองออนไลน์!


สิ่งนี้ไม่ทำงานเมื่อa.maxไม่ได้เป็นหลายตัวb(เช่นf[[1,1,1,2,7,10],3]=> [4, 0, 1]แต่ควรให้[4, 0, 2]) ฉันลองวิธีเดียวกัน
Reinstate Monica - notmaynard

(หรือมากกว่า[4, 0, 1, 1])
Reinstate Monica - notmaynard

นี่เป็นสิ่งที่แก้ไขได้โดยการเปลี่ยนเป็นค่าช่วงลอยตัวสูงสุด แต่ฉันจะขอให้ OP ชี้แจงสิ่งนี้ในคำอธิบายงาน
คิริลล์แอล


ดีมากยิ่งขึ้นขอบคุณ
คิริลล์แอล

1

ปริศนานี้เป็นหลักนับเรียง เราไม่ทราบความยาวของเอาต์พุตโดยไม่ผ่านอินพุตก่อน

C (เสียงดังกราว) , 53 ไบต์

i,j;f(*A,l,b,*O){for(j=0;j<l;O[(A[j++]+b-1)/b-1]++);}

ลองออนไลน์!

วิธีการแก้ปัญหานี้ใช้พารามิเตอร์ต่อไปนี้: ความยาวของ
Aอาร์เรย์อินพุต
lของที่เก็บA
bbin_size
Oสำหรับเอาต์พุต ต้องมีความยาวเพียงพอ
และส่งคืนเอาต์พุตใน O.

วิธีนี้มีแต้มต่อ: มันไม่ส่งคืนความยาวของอาร์เรย์เอาท์พุท O ดังนั้นผู้โทรจึงไม่รู้ว่าจะพิมพ์ได้มากแค่ไหน

รุ่นต่อไปนี้จะเอาชนะแต้มต่อที่:

C (เสียงดังกราว) , 79 ไบต์

i,j,k;f(*A,l,b,*O,*m){for(k=j=0;j<l;O[i=(A[j++]+b-1)/b-1]++,k=k>i?k:i);*m=++k;}

ลองออนไลน์!

ใช้พารามิเตอร์เพิ่มเติมmและส่งคืนความยาวของOมัน มันมีค่าใช้จ่ายฉัน 26 ไบต์


1

C (gcc) , 102 90 89 86 ไบต์

#define P!printf("%d ",k)
i,j,k;f(s){for(i=s;~scanf("%d",&j);k++)for(;j>i;i+=s)k=P;P;}

ลองออนไลน์!

ขอบคุณ Kevin Cruijssen สำหรับการลดขนาด 12 ไบต์และแมวป่าอีก 4 ไบต์!


1
90 ไบต์โดยใช้สำหรับลูป, การลบint, และการเปลี่ยนแปลงไป==1 >0
Kevin Cruijssen

ไม่เป็นไร Btw เพิ่งทราบว่าปัจจุบันไม่ถูกต้อง (เช่นเดียวกับคำตอบ Java ที่ถูกลบไปแล้วในตอนนี้) ต้องใช้O(n)เวลาดังนั้นคุณจึงไม่สามารถซ้อนซ้อนกันได้สำหรับลูป .. (คำตอบ C ++ ของคุณดูเหมือนจะดี แต่ฉันได้ +1 1-ed นั่น :))
Kevin Cruijssen

มันยังคงเป็น O (n) การวนรอบด้านในจะพิมพ์ค่าเสมอและเราพิมพ์ (ค่าสูงสุด + 1) / ค่า binsize ทั้งหมดเท่านั้น
G. Sliepen

อืม แต่ไม่ใช่ลูปด้านนอกอยู่แล้วO(n)โดยการวนซ้ำไอเท็มอินพุต แม้ว่าลูปด้านในจะวนซ้ำเพียง 2 ครั้งO(n)เท่านั้น หรือฉันเข้าใจผิดบางอย่าง .. ฉันต้องยอมรับ - บางครั้งฉันOก็ไม่ชำนาญเลย ..
Kevin Cruijssen

1
แต่ลูปด้านในไม่ได้วนซ้ำไปตามองค์ประกอบอินพุตทั้งหมด แต่จะวนซ้ำเท่านั้นอย่างไรก็ตามค่าเอาต์พุตจำนวนมากที่ต้องพิมพ์เพื่อ "ไล่ตาม" ไปยังตำแหน่งที่สอดคล้องกับองค์ประกอบอินพุตล่าสุด หากเวกเตอร์อินพุตประกอบด้วยจำนวนซ้ำหรือค่าที่แตกต่างกันน้อยกว่าขนาดถังขยะวงด้านในจะไม่ทำการวนซ้ำใด ๆ เลย ในทางกลับกันถ้าเวกเตอร์การป้อนข้อมูลเบาบางมากแล้ววงในจะทำซ้ำได้มากขึ้นโดยพิมพ์ 0 ดังนั้นเพื่อให้ถูกต้องรหัสจะทำงานในเวลา O ((จำนวนองค์ประกอบอินพุต) + (องค์ประกอบสุดท้าย / ขนาดถังขยะ)) นี่คือเส้นตรง
G. Sliepen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.