Zaman içinde binning


12

Bu meydan okumadaki görev, bir dizinin elemanlarını zaman bölmelerine koymaktır. Girdi, olayların zamanını temsil eden azalmayan pozitif bir tamsayı dizisi ve her bir bölmenin boyutunu temsil eden bir tamsayı olacaktır. Bir örnekle başlayalım. Girdi dizisini Ave çıktı dizisini çağırıyoruz O.

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

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

Neden ? A ile bin_size = 2aşağıdaki aralıklara sahip olacağız: (0,2], (2,4], (4,6], (6,8], (8,10]burada dört öğe (1,1,1,2)ilk aralıkta (0,2], hiçbiri ikinci ve üçüncü aralıklarda, biri 7aralıkta (6,8]ve biri 10aralıkta (8,10].

Kodunuz uzunluğu her aralığını dikkate almalıdır bin_sizegelen başlangıç 0ve kaç numara saymak Aher vardır. Yukarıdaki örnekte 2sayıya dahil edilmesi için her zaman bir bölmenin sağ ucunu bir kutuya eklemeniz gerekir 4. Kodunuz, girdi ve çıktı uzunluklarının toplamı olarak doğrusal sürede çalışmalıdır.

Daha fazla örnek:

`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]`.

Giriş ve çıktının uygun bulduğunuz herhangi bir biçimde verilebileceğini varsayabilirsiniz. İstediğiniz dilleri ve kütüphaneleri kullanabilirsiniz.


Sonunda 0s olan çıktılara izin veriliyor mu? Bunun [2,0,1,1,1,0]yerine geri [2,0,1,1,1]mi dönüyorsun ?
Kevin Cruijssen

Sondaki sıfırlar yok lütfen.

2
Maksimum dizi değerinin katları olmadığı durumlarda bin_size, bunları gerçekten ele almalıyız? Çoğu yanıtın öyle olduğu anlaşılıyor, ancak öyleyse, karışıklığı önlemek için bu senaryo için bir test örneği eklemek güzel olurdu.
Kirill L.

@KirillL. Evet onlar da ele alınmalıdır.

1
@GPS 0 pozitif bir tam sayı değil. Bu bir kaza değil :)

Yanıtlar:


9

R , 48 bayt

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

Çevrimiçi deneyin!

Bir kez daha tableve cutbining için factorhile yapmak. Aralık gösterimindeki aralıkların vectorolduğu bir adlandırılmış çıktı verir .names(0,5]

DÜZENLEME: eserler olduğunu önceki sürümüne Geri Al geri sbölmek yok n.


Gerçekten R değilim, ama TIO bu parçası format you [most likely do not] find convenientolmadan bir çıktı gibi görünüyor table.
benim zamirim monicareinstate

@someone tam da bu yüzden orada. cutvektörü aralıklarla verilen düzeylerle faktörlere böler tableve girdisindeki her bir benzersiz değerin oluşumunu sayar.
Giuseppe

1
@someone ah, anlıyorum, yorumunuzu yanlış anladım. Hayır, bence her bir kutuya ihtiyacımız var.
Giuseppe

1
Tamamen test edilmedi, ancak yeniden baypas 0:ceiling(max(n)/s)*sile birkaç bayt kaydedebileceğinizi düşünüyorum seq(0,max(n)+s-1,s). En azından sorudaki iki örnek için çalışır.
Gregor Thomas

1
@Gregor Hmm eğer 1:max(n/s+1)*s-sikisi eşdeğer olduğu için bu işe yararsa başka bir gelişmedir
Giuseppe



3

Python 2 , 62 bayt

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

Çevrimiçi deneyin!


1
Her şeyden önce: güzel cevap, zaten + 1-ed (ve Java'da bir bağlantı noktası oluşturdum, çünkü sahip olduğumdan biraz daha kısa). Sondaki sıfır ancak (sadece sorulan OP) izin verilmez, bu yüzden I[-1]/s+1olmalı ~-I[-1]/s+1yerine.
Kevin Cruijssen

@KevinCruijssen Bildirim için teşekkürler!
Dead Possum

3

05AB1E , 18 bayt

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

Çevrimiçi deneyin!


05AB1E'yi çok iyi bilmiyorum, ama bu A.count max (A) olarak adlandırılıyor gibi görünüyor , bu yüzden çalışma süresi len (A) + len (O) ' da doğrusal değil . Doğru mu yoksa yanlış bir şey mi aldım?
Dennis

@Dennis sayısı olurdu O(max(A)*max(A))... bu yüzden maksimum A ... OP üzerinde ikinci dereceden ikinci dereceden olduğunu söyledi ... tam olarak ne?
Sihirli Ahtapot Urn

2
@MagicOctopusUrn En son revizyona göre, kodunuz giriş ve çıkış uzunluklarının toplamı olarak doğrusal sürede çalıştırılmalıdır .
Dennis

2
@ Oldukça keyfi görünüyor.
Sihirli Ahtapot Urn

2
@MagicOctopusUrn Sanırım bu soru için doğrusal zaman için tek mantıklı tanım.

2

APL + WIN, 23 bayt

Kutuların ekran girişi ve ardından tamsayıların vektörünün girilmesini ister:

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

Açıklama:

⎕ 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 bayt

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

Port of @ DeadPossum'un Python 2 cevabı , bu yüzden cevabını yükselttiğinizden emin olun!

Açıklama:

Çevrimiçi deneyin.

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 bayt / O (len (a) + maks (a) / n)

@Neil sayesinde 5 bayt kaydedildi

Körili sözdiziminde girdi alır (a)(n).

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

Çevrimiçi deneyin!

Veya boş elemanlara izin verilirse sadece 43 bayt / O (len (a)) .


[...o].map(n=>n|0)ikinci çözümden ilk çıktıyı daha az bayt olarak alır.
Neil

@Neil Neden bu kadar kıvrımlı bir şey için gittiğime emin değilim. : - /
Arnauld

2

Haskell , 63 75 70 bayt

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

Hata! Bu daha kısa olan doğrusal değil, ikinci dereceden;

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

Çevrimiçi deneyin!


1

Pyth, 23 22 bayt

Jm/tdeQhQK*]ZheJhXRK1J

Burada deneyin

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

Yakut , 53 50 bayt

Düzenleme: iamnotmaynard tarafından -3 bayt.

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

Çevrimiçi deneyin!


Bu, a.maxkatları birden fazla olmadığında çalışmaz b(örn. f[[1,1,1,2,7,10],3]=> [4, 0, 1]Ancak vermelidir [4, 0, 2]). Aynı yaklaşımı denemiştim.
Monica'yı eski durumuna döndürme - notmaynard

(veya daha doğrusu [4, 0, 1, 1])
Monica'yı eski durumuna döndürme - notmaynard

Peki, bu bir float max aralık değerine geçerek düzeltilebilir, ancak OP'den bunu görev açıklamasında netleştirmesini isteyeceğim.
Kirill L.


Güzel, daha da iyisi, teşekkürler.
Kirill L.

1

Bu bulmaca aslında bir Count-sort. İlk olarak girdiden geçmeden çıktının uzunluğunu bilmiyoruz.

C (clang) , 53 bayt

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

Çevrimiçi deneyin!

Bu çözüm aşağıdaki parametreleri alır:
A Çıktı için
lbir
bbin_size
Odepolama alanı girdi dizisi uzunluğu . Yeterli uzunlukta olmalı
ve çıktıyı O olarak döndürmelidir.

Bu çözümün bir handikabı vardır: O çıkış dizisinin uzunluğunu döndürmez ve bu nedenle arayan ne kadar yazdırılacağını bilmez.

Aşağıdaki sürüm bu handikapın üstesinden gelir:

C (clang) , 79 bayt

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;}

Çevrimiçi deneyin!

Ek bir parametre alır mve içindeki uzunluğu döndürür O. Bana 26 byte mal oldu.


1

C (gcc) , 102 90 89 86 bayt

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

Çevrimiçi deneyin!

12 bayt ayırdığı için Kevin Cruijssen'e ve 4 bayt için tavan kedisine teşekkürler!


1
90 bayt için, döngüler ile uzaklaştırarak intve değişen ==1için >0.
Kevin Cruijssen

Rica ederim. Btw, sadece bir not, şu anda geçersiz (tıpkı şimdi silinen Java yanıtım gibi). Çalıştırmak için gerekli olan minimum O(n)herhangi for-döngüler .. iç içe olamaz bu yüzden (Sizin C ++ cevap cezası görünüyor olsa da, Ben ettik + 1-ed biri olduğunu :)..), Zaman
Kevin Cruijssen

Hala O (n). İç döngü her zaman bir değer yazdırır ve toplamda yalnızca (maksimum değer + 1) / binsize değer yazdırırız.
G. Sliepen

Hmm, ancak O(n)giriş öğeleri üzerinde döngü yaparak dış döngü zaten değil . İç döngü zaten 2 kat daha döngü yapsa bile O(n). Yoksa bir şeyleri yanlış mı anlıyorum .. İtiraf etmeliyim ki - Ozamanlar benim uzmanlığım değil ..
Kevin Cruijssen

1
Ancak iç döngü tüm giriş öğeleri üzerinde yineleme yapmaz, yalnızca en son giriş öğesine karşılık gelen konuma "yakalamak" için yazdırması gereken birçok çıkış değerini yinelemektedir. Giriş vektörü, çok sayıda kopyadan veya kutu boyutundan daha az farklı değerlerden oluşuyorsa, iç döngü hiç yineleme yapmaz. Öte yandan, eğer giriş vektörü çok seyrek ise, iç döngü daha fazla iterasyon gerçekleştirir, 0'ları basar. Doğru olmak gerekirse, kod O ((giriş elemanı sayısı) + (son eleman / kutu boyutu)) zamanında çalışır. Bu hala doğrusal.
G.Slipepen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.