時間内にビニング


12

この課題のタスクは、配列の要素を時間ビンに入れることです。入力は、イベントの時間を表す正の整数の非減少配列と、各ビンのサイズを表す整数になります。例から始めましょう。入力配列Aと出力配列を呼び出しますO

`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]、4つの項目は、(1,1,1,2)最初の区間内にあるが(0,2]、第二と第三の間隔、1でどれ7間隔で(6,8]、1 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]`.

入力および出力は、便利な任意の形式で指定できると想定できます。好きな言語とライブラリを使用できます。


末尾が0sの出力は許可されますか?では、[2,0,1,1,1,0]代わりに[2,0,1,1,1]
ケビンクルーッセン

末尾にゼロを付けないでください。

2
最大配列値がの倍数ではない状況についてはどうbin_sizeですか?ほとんどの回答がそうであるように見えますが、そうであれば、混乱を防ぐために、このシナリオのテストケースを追加するとよいでしょう。
キリルL.

@KirillL はい、それらも処理する必要があります。

1
@GPS 0は正の整数ではありません。これは偶然ではありません:)

回答:


9

R、48バイト

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

オンラインでお試しください!

もう一度、tablecutティンへのfactorビニングのためにトリックを行います。が間隔vectorである名前付きを出力namesします(0,5]。たとえば、間隔表記で。

編集:s分割しないときに動作する以前のバージョンに戻しnます。


私は本当にRをしませんが、TIOではこれformat you [most likely do not] find convenienttable部分なしで出力するようです。
私の代名詞は、18年

@someoneそれがまさにそこにある理由です。cutベクトルを間隔で指定されたレベルの因子に分割tableし、入力内の各一意の値の出現をカウントします。
ジュゼッペ

1
@someone ah、なるほど、あなたのコメントを誤解しました。いいえ、各ビンのカウントが必要なので、それは有効ではないと思います。
ジュゼッペ

1
完全にテストされ、私はあなたがreaplacingバイトのカップルを救うことができると思いません0:ceiling(max(n)/s)*sseq(0,max(n)+s-1,s)。少なくとも問題の2つのサンプルで機能します。
グレゴール-モニカを

1
@Gregorうーん、それが機能する場合1:max(n/s+1)*s-sは、2つが同等であるため、別の改善になります
ジュゼッペ



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ます。
ケビンクルーッセン

@KevinCruijssenお知らせありがとうございます!
デッドポッサム

3

05AB1E、18バイト

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

オンラインでお試しください!


05AB1Eはよくわかりませんが、これはA.count max(A)を呼び出すようですので、実行時間はlen(A)+ len(O)で線形ではありません。それは正しいですか、何か間違っていますか?
デニス

@DennisのカウントはO(max(A)*max(A))...なので、Aの最大値で2 次になります... OPは、...の点で線形でなければならないと指定しました。
魔法のタコ

2
@MagicOctopusUrn コードは、最新のリビジョンに従って、入力と出力の長さの合計で線形時間で実行する必要があります
デニス

2
@Dennisはかなりrather意的です。
魔法のタコ

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

@DeadPossumのPython 2アンサーのポートです。彼のアンサーに必ず投票してください

説明:

オンラインでお試しください。

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)+ max(a)/ n)

@Neilのおかげで5バイト節約

カリー化構文の入力を受け取ります(a)(n)

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)2番目のソリューションから最初の出力をより少ないバイト数で取得します。
ニール

@Neilどうしてこんなに複雑なものにしたのかわかりません。:-/
アーナウルド


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

ルビー53 50バイト

編集:iamnotmaynardによる-3バイト。

->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])。私は同じアプローチを試みました。
モニカの復職-notmaynard

(というより[4, 0, 1, 1]
モニカを復活させる-notmaynard

まあ、これは浮動小数点の最大範囲値に切り替えることで修正できますが、タスクの説明でこれを明確にするようにOPに依頼します。
キリルL.


いいね、もっといい、ありがとう。
キリルL.

1

このパズルは本質的にはカウントソートです。最初に入力を経由せずに出力の長さを知ることはできません。

C(clang)、53バ​​イト

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

オンラインでお試しください!

この溶液は、以下のパラメータを取る:
A入力配列
lの長
bbin_sizeの
O出力のためのストレージを。十分な長さでなければならず
、出力をOで返します。

このソリューションにはハンディキャップがあります。出力配列Oの長さを返さないため、呼び出し側は印刷する量がわかりません。

次のバージョンはそのハンディキャップを克服します。

C(clang)、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;}

オンラインでお試しください!

12バイトを削減してくれたKevin Cruijssenと、さらに4バイトのceilingcatに感謝します!


1
forループを使用し、を削除してintに変更==1することにより、90バイト>0
ケビンクルーッセン

どういたしまして。ちなみに、ただのメモですが、現在無効です(今削除したJavaの答えがそうだったように)。で実行するために必要なのO(n)は、任意のは、forループ入れ子にすることはできませんので..時間(あなたのC ++の答え罰金だ、しかしだから私のしました+ 1-ED 1その:)。。)
ケビンCruijssen

まだO(n)です。内側のループは常に値を出力し、合計(最大値+ 1)/ binsizeの値のみを出力します。
G. Sliepen

うーん、しかし、既にO(n)入力項目をループすることによる外側のループではありません。内側のループが2回だけループする場合でも、すでに上にありO(n)ます。それとも私が何かを誤解しています..私は認めなければならないO回分は本当に私の専門知識...ではありません
ケビンCruijssen

1
しかし、内側のループはすべての入力要素を反復処理するのではなく、最新の入力要素に対応する位置に「追いつく」ために印刷する必要がある出力値を反復処理するだけです。入力ベクトルが、ビンサイズよりも小さい多数の重複または値で構成されている場合、内部ループは反復をまったく実行しません。一方、入力ベクトルが非常にまばらな場合、内側のループはさらに反復を実行し、0を出力します。正確に言うと、コードはO((入力要素の数)+(最後の要素/ビンのサイズ))時間で実行されます。これはまだ線形です。
G.スリーペン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.