술어에 실패한 항목을 계산하지 않고 크기가 지정된 청크로 목록을 분할하십시오.


17

자극 : 때로는 목록의 특정 항목이 총계에 포함되지 않습니다. 예를 들어, 아기가 부모의 무릎에 앉는 비행기 승객을 줄로 세는 것입니다.

도전 과제 : 항목 목록을 덩어리로 나누는 프로그램을 작성하십시오. 각 청크 (마지막은 제외)는 같은 크기입니다 . 여기서 size 술어 함수를 전달하는 항목의 개수로 정의된다.

규칙 :

  1. 당신의 프로그램은
    • 아이템 목록
    • 양의 정수 청크 크기
    • 술어 함수 (항목을 가져오고 true 또는 false를 리턴 함)
  2. 입력 목록을 청크로 분할하여 리턴해야합니다.
  3. 각 청크는 항목 목록입니다
  4. 전체적으로 품목은 동일한 순서로 유지되어야하며 무시하지 않아야합니다.
  5. 각 청크에 술어를 전달하는 항목 수 (마지막을 제외하고)는 입력 청크 크기와 일치해야합니다.
  6. 술어가 실패한 항목은이 크기에 포함되지 않아야합니다.
  7. 술어가 실패한 항목은
    1. 여전히 출력 청크에 포함
    2. 청크가 "full"이지만 다음 항목이 술어에 실패한 경우 가장 빠른 청크에 할당됩니다.
      • 따라서 최종 청크는 술어가 실패한 항목으로 만 구성되지 않을 수 있습니다.
  8. 모든 항목이 설명 되었기 때문에 최종 청크의 크기 는 청크 크기보다 작을 수 있습니다 .

철저하지 않은 예 :

가장 간단한 예는 술어 함수가 인 1s 및 0s 를 고려 하는 것입니다 x ==> x > 0. 이 경우 sum각 청크의 청크 크기와 일치해야합니다.

  • 항목 : [], 크기 : 2, 조건 자 : 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 사용하는 것이 좋습니다 .
Laikoni

3
목록 항목이 단일 문자라고 가정 할 수 있습니까? 아니면 숫자?
xnor

청크 청크는 재미있는 것으로 들리지만, 파티션 설정 으로 대체 될 수 있습니다 .
Jonathan Frech

@Laikoni 태그 코드 골프
톰 Viner

1
@Ourous "나는 모든 항목이 설명되어 있기 때문에"추가했습니다. 즉, 마지막 청크는 입력 항목의 끝이기 때문에 "풀업"할 기회가 없습니다.
Tom Viner

답변:


2

젤리 , 10 바이트

vⱮTm⁵ḊœṖŒṘ

모나 딕 블랙 박스 함수를 첫 번째 선택적 인수로, 전체 목록은 두 번째 선택적 인수로, 청크 크기를 세 번째 선택적 인수로 사용하여 결과 목록 목록의 Python 표현을 인쇄하여 젤리의 암시 적 스매싱을 방지합니다. 문자가 포함 된 목록).

온라인으로 사용해보십시오! (문자 목록은 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⌈+\⍺⍺¨⍵}

⍺⍺¨⍵aplies 부울 벡터를 반환 목록에 술어는
+\실행중인 총 발생
1⌈선도을 대체를 0의와 1
⌈⍺÷⍨분할 최대 청크 크기와 라운드로 각 요소
⍵⊆⍨이이 파티션을 원래 벡터


2
인상적입니다! 그리고 나는 출력 디스플레이, 문제에 대한 적절한 시각을 좋아합니다.
sundar-복원 모니카

프로그램 (tradfn body)으로 변환하여 바이트를 저장하십시오.w⊆⍨⌈⎕÷⍨1⌈+\⎕¨w←⎕
Adám

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..)"어이 던전, 당신은 적어도 몇 가지 경우에 내 깨끗한 답변을 이겼습니다. 어쨌든, 나는 항상 당신의 답변을 기대합니다.
OUurous

2
@ Οurous Java가 어떤 식 으로든 코드 골프에 적합하지 않다는 사실에 더 가깝습니다 .Jelly, 05AB1E 등과 같은 실제 골프 언어와 비교하면 Clean에도 적용됩니다. Java에서 (그리고 Clean에서도 가정합니다). 그리고 (긴) 한 번에 Java는 Python을 이길 수 있습니다. ;) 그리고 한 번 자바가 bash가 그것을 망칠 때까지 (그리고 R은 더 골프를 쳤다) 최고의 답변 이었습니다. xD
Kevin Cruijssen

1
배열 목록을 반환하면 186 바이트 : bit.ly/2mSjCIc
OOBalance

@OOBalance 감사합니다! 똑똑한 사용Arrays.copyOfRange !
Kevin Cruijssen

@OOBalance는 입력을 List로 사용하고을 사용하여 조금 더 골프를 칠 수있었습니다 .sublist. 귀하의 기능은 그와 동일하게 유지되지만 많은 바이트를 절약하고 가져 오기를 제거합니다. (이제 정수 대신 문자가있는 테스트 케이스에서도 작동합니다.)
Kevin Cruijssen


3

C (gcc) , 70 66 바이트

C는 그러한 것들에 대해 알지 못하기 때문에 하위 목록의 시작을 기록하는 구조를 사용합니다.

제안에 대한 ceilingcat에게 감사합니다.

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

온라인으로 사용해보십시오!


3

하스켈, 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및 조건 자를 허용하는 익명 람다 g. c술어와 일치하는 항목 카운터 를 유지하고 이미 사용한 청크 수로 항목을 그룹화합니다. 불행히도 초기 값 -1 / n은 0으로 올림되지 않으므로이를 수정하기 위해 몇 바이트를 사용해야합니다.





1

수학, 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명명되지 않은 / 익명 / 순수 / lambda 함수는 목록의 요소에 대해 true / false 작동을 리턴합니다.

Last@Reap[...]Sow-n 안의 모든 요소의 목록을 반환합니다 .... 두 번째 인수 e~Sow~t가 속기 때문에 하위 목록으로 그룹화됩니다 Sow[e, t].

청크 크기 1을 처리하기 위해 카운터를 -1로 초기화해야했습니다. 그렇지 않으면 확인해야합니다 Mod[i, s](i~Mod~s 1과 같은 ) .

나머지 코드는 ungolfed 블록에 설명되어 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.