リストをサイズのチャンクに分割しますが、述語に失敗したアイテムはカウントしません


17

動機:リスト内の特定のアイテムが合計にカウントされない場合があります。例えば、赤ちゃんが親の膝の上に座っている飛行機の乗客を列に数えます。

課題:アイテムのリストをチャンクに分割するプログラムを作成します。各チャンク(最後のチャンクを除く)は同じサイズです。サイズは、述語関数を渡すアイテムの数として定義されます。

ルール

  1. あなたのプログラムは
    • アイテムのリスト
    • 正の整数チャンクサイズ
    • 述語関数(項目を取り、trueまたはfalseを返します)
  2. 入力リストをチャンクに分割して返す必要があります
  3. 各チャンクはアイテムのリストです
  4. 全体的に、アイテムは同じ順序のままで、何も変装していない必要があります
  5. 各チャンク(おそらく最後を除く)で述語を渡すアイテムの数は、入力チャンクサイズと一致する必要があります。
  6. 述語に失敗したアイテムは、このサイズにカウントされません
  7. 述語に失敗した項目は
    1. 出力チャンクにまだ含まれています
    2. チャンクが「満杯」であるが、次の項目が述語に失敗したものである場合、最も早いチャンクに割り当てられます
      • したがって、最終チャンクは、述語に失敗した項目のみで構成されない場合があります
  8. すべてのアイテムが考慮されているため、最終チャンクのサイズはチャンクサイズよりも小さい場合があります

非網羅的な例:

最も簡単な例は、述語関数がである1sと0s を考慮することですx ==> x > 0。この場合、sum各チャンクのがチャンクサイズと一致する必要があります。

  • items:[]、size:2、predicate:x > 0-> []または[[]]
  • アイテム:[0, 0, 0, 0, 0, 0]、サイズ:2、述語:x > 0->[[0, 0, 0, 0, 0, 0]]
  • アイテム:[0, 1, 1, 0]、サイズ:2、述語:x > 0->[[0, 1, 1, 0]]
  • アイテム:[0, 1, 1, 0, 1, 0, 0]、サイズ:2、述語:x > 0->[[0, 1, 1, 0], [1, 0, 0]]
  • アイテム:[0, 1, 0, 0, 1, 0, 1, 1, 0]、サイズ:2、述語:x > 0->[[0, 1, 0, 0, 1, 0], [1, 1, 0]]

そして、赤ちゃんが親の膝の上に座る飛行機の乗客で終わりましょう。A大人の場合b、赤ちゃんの場合、飛行機の列は3座席幅で、大人は常に赤ちゃんの前に記載されています

  • アイテム:[A, b, A, b, A, A, A, b, A, b, A, A, b]、サイズ:3、述語:x => x == A->[[A, b, A, b, A], [A, A, b, A, b], [A, A, b]]

6
これは良い質問のように見えますが、現在のところ、勝つ基準はありません。code-golfを使用することをお勧めします
ライコニ

3
リスト項目が単一文字であると想定できますか?または、たとえば、数字?
xnor

チャンクは面白いように聞こえますが、set-partitionsに置き換えることもできます。
ジョナサンフレッチ

@Laikoniがcode-golfに
Tom Viner

1
@Ourous「すべてのアイテムが考慮されているため」を追加しました。つまり、最後のチャンクは「フル」になる機会を得られません。これは入力アイテムの終わりに過ぎないからです。
トム・ヴァイナー

回答:


2

ゼリー、10 バイト

vⱮTm⁵ḊœṖŒṘ

モナドブラックボックス関数を最初のオプション引数として、リストを2番目のオプション引数として、チャンクサイズを3番目のオプション引数として使用する完全なプログラムは、リストの結果リストのPython表現を出力します(Jellyの暗黙的なスマッシングを避けるため)文字を含むリスト)。

オンラインでお試しください!(文字のリストは、Python引用符付き文字列としてフォーマットすることにより、Jellyプログラムに渡されることに注意してください)

どうやって?

vⱮTm⁵ḊœṖŒṘ - Main Link: B, L, S
 Ɱ         - map across second argument with (i.e. for X in L):
v          -   evaluate as a monad with input (i.e. B(X))
  T        - truthy indices (e.g. [0,0,1,0,1,1,1,0,0,0,1,0,0]T -> [3,5,6,7,10])
    ⁵      - 3rd optional argument = S
   m       - modulo slice   (e.g. [3,4,7,9,12,15,16,18,19,20]m3 -> [[3,4,7],[9,12,15],[16,18,19],[20]]
     Ḋ     - dequeue        (e.g. [[3,4,7],[9,12,15],[16,18,19],[20]]Ḋ -> [[9,12,15],[16,18,19],[20]]
      œṖ   - partition right (L) at the indices in that
        ŒṘ - print Python representaion

8

Brachylog、37バイト

hW&t~c.k{↰₂ˢl}ᵐ;WxĖ∧.bhᵐ↰₂ᵐ∧.t↰₂ˢl≤W∧

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

これ-質問のかなりの修正-が正常に終了し、正しい出力を生成することを発見して、私は嬉しく驚きました。

このコードの下に述語2として述語が存在すると仮定します。リストのリスト(「チャンク」)を出力するかfalse、空の入力用に出力します。

説明:

hW&               % First input is W, the expected "weight" of each chunk
                  %  (i.e. the number of items passing predicate in each chunk)

t                 % Take the second input, the list of items
 ~c.              % Output is a partition of this list
    k{    }ᵐ      % For each partition (chunk) except the last, 
      ↰₂ˢ         %   Select the items in the chunk that pass the predicate
         l        %   Get the length of that
                  % (So now we have the list of the "weights" of each chunk)
            ;Wx   % Remove the input expected weight from this list, and 
               Ė  %  the result of this should be empty.
                  %  This verifies that the list of weights is either 
                  %  composed of all W-values, or is empty (when input is [0 0 0] for eg.)

    ∧.bhᵐ↰₂ᵐ      % And, the first element of each chunk (except the first) should
                  %  pass the predicate. This is another way of saying:
                  %  "Items failing the predicate are allocated to the earliest chunk"

    ∧.t↰₂ˢl≤W     % And, the final chunk (which we haven't constrained so far)
                  %  should have weight ≤ the input expected weight
                  %  This disallows putting everything in the final chunk and calling it a day!

    ∧             % (no further constraints on output)

7

Apl(Dyalog Unicode) 17 16バイト(SBCS)

1バイト節約してくれたAdámに感謝します。

w⊆⍨⌈⎕÷⍨1⌈+\⎕¨w←⎕

オンラインでお試しください! 説明のために、17バイトのソリューションは残しておきます。

{⍵⊆⍨⌈⍺÷⍨1⌈+\⍺⍺¨⍵}

⍺⍺¨⍵ブールベクトルを返すリストに述語を適用し、現在の
+\合計を生成し、
1⌈先頭0のsを1sに置き換え
⌈⍺÷⍨、各要素をチャンクサイズで除算し
⍵⊆⍨、これにより元のベクトルのパーティションを切り上げます


2
それが印象的です!そして、問題に適した視覚的な出力表示が好きです。
スンダ

プログラム(tradfn body)に変換してバイトを保存します。w⊆⍨⌈⎕÷⍨1⌈+\⎕¨w←⎕
Adám18年

5

クリーン96 92バイト

f :: a -> Boolメタコンセンサスに従って許可された名前付き関数を使用します。

import StdEnv,StdLib
$l n|l>[]=last[[i: $t n]\\i<-inits l&t<-tails l|n>=sum[1\\e<-i|f e]]=[]

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

拡張(コメントを表示するためのデフォルトの強調表示を使用):

$ l n // define function $ on `l` and `n`
 | l > [] // if `l` is not the empty list
  = last [ // the last element of ...
                   \\ i <- inits l // prefixes of `l`
                    & t <- tails l // matching suffixes of `l`
                    | n >= // where n is greater than or equal to
                           sum [1 \\ e <- i | f e] // the number of matching elements in the prefix
          [i: $t n] // prepend that prefix to the application of $ to the rest of the list
         ]
 = [] // if `l` is empty, return empty

4

ジャワ10、207の 186 159 148バイト

a->n->{var r=new java.util.Stack();int l=a.size(),i=0,c=0,j=0;for(;i<=l;i++)if(i==l||f(a.get(i))&&++c>n&i>0){r.add(a.subList(j,j=i));c=1;}return r;}

Javaは、間違いなくこの課題に適した言語ではありません(もちろん、もちろんあらゆるゴルフコースの挑戦..)

@OOBalanceのおかげで-21バイト

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

説明:

a->n->{                    // Method with List & int parameters & List of Lists return-type
  var r=new java.util.Stack();
                           //  Result-list, starting empty
  int l=a.size(),          //  Size of the input-List
      c=0,                 //  Count-integer, starting at 0
      j=0,                 //  Range-integer, starting at 0
  i=0;for(;i<=l;i++){      //  Loop `i` in the range [0, `l`]
    if(i==l||              //   If this is the last iteration
       f(a.get(i))         //   Or if the black-box function is true for the current item
       &&++c               //    Increase the counter by 1
        >n&                //    If the counter is now larger than the size
        &i>0){             //    and it's not the first item of the List
      a.subList(j,j=i);    //     Add a sub-List to the result from range [`j`, `i`)
                           //     And set `j` to `i` at the same time
      c=1;}                //     And reset `c` to 1
  return r;}               //  Return the List of Lists as result

ブラックボックス入力形式:

名前付き関数boolean f(Object i)が存在すると仮定しますこれ、このメタ回答に従って許可されます

上記のラムダと同様にTest、デフォルト関数を含む抽象クラスがありますf(i)

abstract class Test{
  boolean f(Object i){
    return true;
  }

  public java.util.function.Function<java.util.List, java.util.function.Function<Integer, java.util.List<java.util.List>>> c =
    a->n->{var r=new java.util.Stack();int l=a.size(),i=0,c=0,j=0;for(;i<=l;i++)if(i==l||f(a.get(i))&&++c>n&i>0){r.add(a.subList(j,j=i));c=1;}return r;}
  ;
}

テストケースでは、この関数を上書きしますf。たとえば、最後のテストケースは次のように呼び出されます。

System.out.println(new Test(){
  @Override
  boolean f(Object i){
    return (char)i == 'A';
  }
}.c.apply(new java.util.ArrayList(java.util.Arrays.asList('A', 'b', 'A', 'b', 'A', 'A', 'A', 'b', 'A', 'b', 'A', 'A', 'b'))).apply(3));

1
" (or any codegolf-challenge of course..)"ええ、少なくともいくつかのケースであなたは私のクリーンな答えを打ち負かしました。とにかく、私はいつもあなたの答えを楽しみにしています。
18

2
@ΟurousJavaがコードゴルフに適していないというのはミームです。Jelly、05AB1Eなどの実際のゴルフ言語と比較すると、JavaがCleanにも当てはまると思います。ただし、Javaでも(そしてCleanでも同様です)。そして、長い間、JavaはPythonを打ち負かすことができます。;)そして、bash がJavaを台無しにする(そしてRがさらにゴルフをする)まで私はかつてJavaの主要な回答でした。xD
ケビンクルーッセン

1
あなたは配列のリストを返す場合は186バイトを:bit.ly/2mSjCIc
OOBalance

@OOBalanceありがとう!のスマートな使用Arrays.copyOfRange
ケビンクルーイッセン

@OOBalanceは、入力をリストとして使用し、を使用することで、もう少しゴルフをすることができました.sublist。それ以外は機能は同じですが、多くのバイトを節約し、インポートを削除します。(そして今では、整数の代わりに文字を使用したテストケースでも動作します。)
ケビンCruijssen



3

Haskell、72バイト

p#s|let l@(h:t)!a|sum[1|e<-h:a,p e]>s=a:l![]|n<-a++[h]=t!n;_!a=[a]=(![])

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

p#s     = (![])         -- main function that takes a predicate function 'p',
                        -- a size 's' and a input list without a name that is
                        -- directly passed as the first argument to function '!'
  let  l@(h:t)!a        -- function '!' is a local function (so that 'p' and 's'
                        -- are in scope). Takes a list 'l' of at least one element
                        -- 'h' (and 't' being the rest of the list) and an
                        -- accumulator 'a'
   |sum[1|e<-h:a,p e]>s -- if 'p' holds for more than 's' elements in 'h' and 'a'
     =a:l![]            --   put 'a' in front of a recursive call with the same list
                        --   'l' and an empty accumulator
   |n<-a++[h]           -- else bind 'n' to 'h' appended to 'a' and
     =t!n               --   call '!' again with 't' and 'n'
  _!a=[a]               -- base case for '!'. If the input list is empty, return
                        --   a singleton list with 'a' 

3

MATL、19バイト

HyX$Ysi/Xk1y>+!w7XQ

jslipの優れたAPL回答に基づいています

MATLには実際にはユーザー定義関数はありませんが、実行中の環境(MATLAB / Octave)を呼び出す方法があるため、これを述語関数に使用します。使用法は次のようなものになるだろうこれが、その機能はので、ここではハードコード使用するバージョンですが、セキュリティ上の理由から、オンラインで無効になっているisodd代わりに、述語関数:MATLオンライン上でそれを試してみてくださいが

H    % Push the function name to be called, assumed to be 
     %  stored in the H clipboard
y    % Take the first input, push copies of it both below and above the 
     %  function name
X$   % Call the function (say 'isupper') with the input as argument
     %  returns a boolean vector
Ys   % Cumulative sum
i/   % Take the chunk size and divide each element by it
Xk   % ceil
1y>+ % Turn the (initial) 0s to 1s
!    % Transpose. Now we have a column vector specifying which chunk 
     %  each input element should go into
w    % Bring the other copy of the input on top 
7    % Code for this function: '@(x){x.'}'
     %  i.e. place each chunk in a row vector and enclose it in a cell
XQ   % 'accumarray' - split the input into chunks based on
     %   the given column vector, apply the given function to each chunk
     %   (which here just wraps it up as a cell), and accumulate the results
     %   in an array.
     % implicit output


2

ルビー、57バイト

->a,n,g{c=-1;a.group_by{|x|[0,c+=g[x]?1:0].max/n}.values}

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

入力配列a、チャンクサイズn、および述語を受け入れる匿名ラムダgc述語に一致するアイテムのカウンターを維持し、すでに使用されているチャンクの数でアイテムをグループ化します。残念ながら、初期値-1 / nは0に切り上げられないため、修正するには数バイトを費やす必要があります。





1

Mathematica、82バイト

f[l_,s_,p_]:=Last@Reap[i=t=-1;Do[If[p@e,If[++i~Mod~s==0&&i>0,t++]];e~Sow~t,{e,l}]]

ゴルフをしていない:

f[l_,s_,p_] :=                (* define a function that takes three    *)
                              (* arguments                             *)

  Last@Reap[                  (* collect and return results which were *)
                              (* gathered by the procedural loop below *)

    i=t=-1;                   (* initialize two counters               *)

    Do[                       (* start iterating over the list         *)

      If[p@e,                 (* if element passes predicate           *)
        If[                   (* then if preincremented i is 0 modulo  *)
          ++i~Mod~s==0&&i>0,  (* chunk size and i > 0                  *)
          t++                 (* increment t                           *)
        ]
      ];e~Sow~t,              (* finally sow the element tagged with   *)
                              (* the current value of t                *)

    {e,l}]                    (* e references current element of list  *)
                              (* l is the list itself                  *)
  ]

l入力リストです。sチャンクサイズです。pリストの要素を操作するtrue / falseを返す無名/匿名/純粋/ラムダ関数です。

Last@Reap[...]Sow内の-n であったすべての要素のリストのリストを返します...。それらはサブリストにグループ化され、その2番目の引数e~Sow~tはの短縮形ですSow[e, t]

1のチャンクサイズを処理するには、カウンターを-1に初期化する必要がありました。そうしないと、1に等しいMod[i, s]i~Mod~s)をチェックする必要があり、これは決して発生しませんでした。

コードの残りの部分は、ungolfedブロックで説明されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.