Chia một danh sách thành các phần có kích thước, nhưng không tính các mục không thành ngữ


17

Động lực : Đôi khi một số mục nhất định trong danh sách không được tính vào tổng số của bạn. Ví dụ, đếm hành khách trên máy bay theo hàng, nơi em bé ngồi trên vòng của cha mẹ.

Thách thức : viết chương trình chia danh sách các mục thành các phần. Mỗi khối (ngoại trừ có thể là cuối cùng) có cùng kích thước , trong đó kích thước được xác định là số lượng vật phẩm đi qua một hàm vị ngữ.

Quy tắc :

  1. Chương trình của bạn phải mất
    • một danh sách các mặt hàng
    • một kích thước số nguyên dương
    • một hàm vị ngữ (lấy một mục và trả về đúng hoặc sai)
  2. Bạn phải trả lại danh sách đầu vào được chia thành các phần
  3. Mỗi đoạn là một danh sách các mục
  4. Nhìn chung, các mặt hàng phải được giữ theo cùng một thứ tự, không có gì bị coi thường
  5. Số lượng vật phẩm đi qua vị ngữ trong mỗi khối (ngoại trừ có thể là cuối cùng) phải khớp với kích thước khối đầu vào.
  6. các mục không có vị ngữ không được tính vào kích thước này
  7. Các mục không thành ngữ là
    1. vẫn được bao gồm trong khối đầu ra
    2. được phân bổ cho đoạn đầu tiên, trong trường hợp một đoạn "đầy" nhưng các mục tiếp theo là các mục không thành công
      • do đó, đoạn cuối cùng có thể không chỉ bao gồm các mục bị lỗi vị ngữ
  8. Đoạn cuối có thể có kích thước nhỏ hơn kích thước khối vì tất cả các mục đã được tính.

Ví dụ không đầy đủ:

Ví dụ đơn giản nhất là xem xét 1s và 0s, trong đó hàm vị ngữ là x ==> x > 0. Trong trường hợp này, summỗi khối phải phù hợp với kích thước khối.

  • mục : [], kích thước : 2, vị ngữ: x > 0-> []hoặc[[]]
  • mục : [0, 0, 0, 0, 0, 0], kích thước : 2, vị ngữ: x > 0->[[0, 0, 0, 0, 0, 0]]
  • mục : [0, 1, 1, 0], kích thước : 2, vị ngữ: x > 0->[[0, 1, 1, 0]]
  • mục : [0, 1, 1, 0, 1, 0, 0], kích thước : 2, vị ngữ: x > 0->[[0, 1, 1, 0], [1, 0, 0]]
  • mục : [0, 1, 0, 0, 1, 0, 1, 1, 0], kích thước : 2, vị ngữ: x > 0->[[0, 1, 0, 0, 1, 0], [1, 1, 0]]

Và hãy kết thúc với hành khách trên máy bay nơi em bé ngồi trên ví dụ của cha mẹ . AĐối với người lớn, bđối với em bé, hàng máy bay 3rộng chỗ ngồi, người lớn luôn được liệt kê trước em bé của họ:

  • mục : [A, b, A, b, A, A, A, b, A, b, A, A, b], kích thước : 3, vị ngữ: x => x == A->[[A, b, A, b, A], [A, A, b, A, b], [A, A, b]]

6
Đây có vẻ là một câu hỏi hay, nhưng hiện tại nó thiếu một tiêu chí chiến thắng. Tôi đề nghị sử dụng mã golf .
Laikoni

3
Chúng ta có thể giả sử các mục danh sách là các ký tự đơn không? Hoặc, nói, số?
xnor

chunking nghe có vẻ thú vị, mặc dù có thể được thay thế bằng phân vùng set .
Jonathan Frech

@Laikoni được gắn thẻ mã-golf
Tom Viner

1
@Ourous tôi đã thêm "vì tất cả các mục đã được tính", tức là đoạn cuối cùng không có cơ hội nhận được "đầy đủ", vì đó chỉ là phần cuối của các mục đầu vào.
Tom Viner

Câu trả lời:


2

Thạch , 10 byte

vⱮTm⁵ḊœṖŒṘ

Một chương trình đầy đủ lấy chức năng hộp đen đơn âm làm đối số tùy chọn đầu tiên, danh sách làm đối số tùy chọn thứ hai và kích thước khối làm đối số tùy chọn thứ ba in đại diện danh sách Python của danh sách kết quả (để tránh việc đập vỡ ngầm của Jelly danh sách chứa các ký tự).

Hãy thử trực tuyến! (lưu ý rằng một danh sách các ký tự được chuyển đến chương trình Jelly bằng cách định dạng nó dưới dạng chuỗi trích dẫn Python)

Làm sao?

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 byte

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

Hãy thử trực tuyến!

Tôi đã rất ngạc nhiên khi thấy rằng điều này - gần như là một sự phục hồi của câu hỏi - chấm dứt thành công và tạo ra đầu ra chính xác.

Giả sử vị từ có mặt như vị ngữ 2 bên dưới mã này. Xuất ra một danh sách các danh sách ("khối") hoặc falsecho một đầu vào trống.

Giải trình:

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 byte (SBCS)

Cảm ơn Adám đã tiết kiệm cho tôi 1 byte.

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

Hãy thử trực tuyến! với mục đích giải thích tôi sẽ để lại giải pháp 17 byte.

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

⍺⍺¨⍵áp dụng vị ngữ vào danh sách trả về một vectơ boolean
+\tạo ra tổng chạy
1⌈thay thế 0các s hàng đầu bằng 1s
⌈⍺÷⍨chia mỗi phần tử theo kích thước khối và làm tròn các
⍵⊆⍨phân vùng vectơ ban đầu bằng cách này


2
Ấn tượng đấy! Và tôi thích màn hình đầu ra, hình ảnh phù hợp cho vấn đề.
- Phục hồi Monica

Lưu một byte bằng cách chuyển đổi sang chương trình (cơ thể tradfn): w⊆⍨⌈⎕÷⍨1⌈+\⎕¨w←⎕
Adám

5

Sạch , 96 92 byte

Sử dụng một chức năng được đặt tên f :: a -> Boolđược cho phép theo sự đồng thuận meta.

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

Hãy thử trực tuyến!

Mở rộng (với đánh dấu mặc định để hiển thị bình luận):

$ 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

Java 10, 207 186 159 148 byte

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 chắc chắn không phải là ngôn ngữ phù hợp cho thử thách này (hoặc bất kỳ thách thức về tiền mã hóa nào ..)

-21 byte nhờ @OOBalance

Hãy thử trực tuyến.

Giải trình:

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

Định dạng đầu vào hộp đen:

Giả sử có một hàm boolean f(Object i)được đặt tên , được cho phép theo câu trả lời meta này .

Tôi có một lớp trừu tượng Testchứa hàm mặc định f(i), cũng như lambda ở trên:

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

Đối với các trường hợp thử nghiệm, tôi ghi đè chức năng này f. Ví dụ, trường hợp thử nghiệm cuối cùng được gọi như thế này:

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..)" ehh tôi không biết, bạn đã đánh bại câu trả lời sạch của tôi trong ít nhất một vài trường hợp. Dù sao, tôi luôn mong chờ câu trả lời của bạn.
Οurous

2
@ Οurous Thêm một điều đáng nhớ là Java không phù hợp với codegolf theo bất kỳ cách nào, mà tôi đoán cũng áp dụng cho Clean nếu chúng ta so sánh nó với các ngôn ngữ golf thực tế như Jelly, 05AB1E, v.v. Tôi vẫn thích giải quyết tất cả các thử thách về codegolf này trong Java mặc dù (và bạn cũng trong Clean cũng vậy). Và một lần trong một thời gian dài, Java có thể đánh bại Python . ;) Và tôi đã từng là một câu trả lời hàng đầu với Java , cho đến khi bash phá hỏng nó (và R đánh gôn hơn nữa). xD
Kevin Cruijssen

1
186 byte nếu bạn quay lại một danh sách của các mảng: bit.ly/2mSjCIc
OOBalance

@OOBalance Cảm ơn! Sử dụng thông minh Arrays.copyOfRange!
Kevin Cruijssen

@OOBalance đã có thể chơi gôn thêm một chút bằng cách sử dụng đầu vào làm Danh sách và sử dụng .sublist. Chức năng của bạn vẫn giữ nguyên như vậy, nhưng nó tiết kiệm rất nhiều byte và loại bỏ việc nhập. (Và bây giờ nó cũng hoạt động cho trường hợp thử nghiệm với các ký tự thay vì số nguyên.)
Kevin Cruijssen


3

C (gcc) , 70 66 byte

Tôi sử dụng một cấu trúc để lưu ý bắt đầu một danh sách phụ, vì C không biết về những điều đó.

Cảm ơn trần nhà cho những gợi ý.

t;f(a,s,c)l*a;int(*c)();{for(;a->v;a++)(t+=c(a->v))>s?t=++a->s:0;}

Hãy thử trực tuyến!


3

Haskell, 72 byte

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

Hãy thử trực tuyến!

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 byte

HyX$Ysi/Xk1y>+!w7XQ

Dựa trên câu trả lời APL tuyệt vời của jslip .

MATL không thực sự có các hàm do người dùng định nghĩa như vậy, nhưng nó có một cách để gọi ra môi trường mà nó đang chạy (MATLAB / Octave), vì vậy, điều này sử dụng hàm đó cho hàm vị ngữ. Cách sử dụng sẽ giống như thế này , nhưng chức năng đó bị vô hiệu hóa trực tuyến vì lý do bảo mật, vì vậy đây là phiên bản sử dụng isoddchức năng vị ngữ được mã hóa cứng : Thay vào đó hãy thử trên MATL Online .

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

Ruby , 57 byte

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

Hãy thử trực tuyến!

Lambda ẩn danh chấp nhận mảng đầu vào a, kích thước khối nvà vị ngữ g. Duy trì bộ đếm ccác mục phù hợp với vị ngữ và nhóm các mục theo số lượng khối đã sử dụng hết. Thật không may, giá trị ban đầu -1 / n không làm tròn đến 0, vì vậy chúng tôi phải bỏ ra một vài byte để sửa nó.


2

R , 100 byte

function(L,K,P,s=sapply(L,P),y=cut(cumsum(s),seq(0,sum(s),K),,T))for(l in levels(y))cat(L[y==l],"
")

Hãy thử trực tuyến!

vượt trội nhờ digEmAll


Tôi không biết các danh sách được đặt tên là đầu ra có ổn không (và nếu tôi bỏ lỡ một số trường hợp cạnh ...): 65 byte
digEmAll

Hmm, tôi sẽ gửi nó như là một câu trả lời riêng biệt!
Giuseppe



1

Toán học, 82 byte

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

Ung dung:

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                  *)
  ]

llà danh sách đầu vào; slà kích thước chunk; plà một hàm không tên / ẩn danh / thuần túy / lambda trả về hoạt động đúng / sai trên các thành phần của danh sách.

Last@Reap[...]trả về một danh sách các danh sách của mọi phần tử Sownằm trong .... Chúng được nhóm thành các danh sách con theo đối số thứ hai e~Sow~tlà viết tắt cho Sow[e, t].

Tôi đã phải khởi tạo bộ đếm thành -1 để xử lý kích thước khối 1, nếu không tôi sẽ cần kiểm tra Mod[i, s]( i~Mod~s) bằng 1, điều này không bao giờ có thể xảy ra.

Phần còn lại của mã được giải thích trong khối không được phép.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.