Bir listeyi boyutlandırılmış parçalara ayırın, ancak yüklemesi başarısız olan öğeleri saymayın


17

Motivasyon : Bazen listedeki bazı öğeler toplamlarınıza dahil edilmez. Örneğin, bebeklerin bir ebeveynin kucaklarında oturduğu sıradaki uçak yolcularını saymak.

Zorluk : bir öğe listesini parçalar halinde bölmek için bir program yazın. (Muhtemelen son hariç) her bir yığın, aynı olan boyutu , boyut öncül fonksiyonu geçen madde sayısı olarak tanımlanır.

Kurallar :

  1. Programınız
    • bir öğe listesi
    • pozitif tamsayı yığın boyutu
    • yüklem işlevi (bir öğe alır ve doğru veya yanlış döndürür)
  2. Giriş listesini parçalara ayrılmış olarak döndürmelisiniz
  3. Her yığın bir öğe listesidir
  4. Genel olarak, ürünler aynı sırada kalmalı, hiçbiri göz ardı edilmemelidir
  5. Her bir öbekte yüklemi geçen öğe sayısı (muhtemelen sonuncusu hariç) girdi öbeği boyutuyla eşleşmelidir.
  6. yüklemi geçmeyen öğeler bu boyuta dahil edilmemelidir
  7. Yüklemi başarısız olan öğeler
    1. hala çıktı yığınlarına dahil
    2. bir parçanın "dolu" olması durumunda, ancak sonraki öğeler yüklemi başarısız olan öğelerdir.
      • bu nedenle son yığın sadece yüklemi başarısız olan maddelerden oluşmayabilir
  8. Tüm parçalar muhasebeleştirildiği için, son yığın yığın boyutundan daha küçük olabilir .

Kapsamlı olmayan örnekler:

En basit örnek, yüklem işlevinin bulunduğu 1s ve 0s'yi dikkate almaktır x ==> x > 0. Bu durumda, sumher bir yığının yığın boyutuyla eşleşmesi gerekir.

  • öğeler:, []boyut:, 2yüklem: x > 0-> ya []veya[[]]
  • ürün:, [0, 0, 0, 0, 0, 0]boyut:, 2yüklem: x > 0->[[0, 0, 0, 0, 0, 0]]
  • ürün:, [0, 1, 1, 0]boyut:, 2yüklem: x > 0->[[0, 1, 1, 0]]
  • ürün:, [0, 1, 1, 0, 1, 0, 0]boyut:, 2yüklem: x > 0->[[0, 1, 1, 0], [1, 0, 0]]
  • ürün:, [0, 1, 0, 0, 1, 0, 1, 1, 0]boyut:, 2yüklem: x > 0->[[0, 1, 0, 0, 1, 0], [1, 1, 0]]

Ve bebeklerin bir ebeveynin kucak örneğinde oturduğu uçak yolcuları ile bitirelim . Ayetişkin için, bbebek için, uçak sırası 3geniş koltuklar, yetişkin her zaman bebeklerinden önce listelenir:

  • ürün:, [A, b, A, b, A, A, A, b, A, b, A, A, b]boyut:, 3yüklem: x => x == A->[[A, b, A, b, A], [A, A, b, A, b], [A, A, b]]

6
Bu iyi bir soru gibi görünüyor, ancak şu anda kazanan bir kriter yok. Kod-golf kullanmanızı öneririm .
Laikoni

3
Liste öğelerinin tek karakter olduğunu varsayabilir miyiz? Veya sayılar mı?
xnor

parçalama ilginç geliyor, ancak belki set bölümleri ile değiştirilebilir .
Jonathan Frech


1
@Ourous ekledim "çünkü tüm öğeler muhasebeleştirildi", yani son yığın "dolmak" için bir şansa sahip değil, çünkü bu sadece giriş öğelerinin sonu.
Tom Viner

Yanıtlar:


2

Jöle , 10 bayt

vⱮTm⁵ḊœṖŒṘ

Monadik kara kutu işlevini ilk isteğe bağlı argüman, ikinci isteğe bağlı argüman olarak liste ve üçüncü isteğe bağlı argüman olarak sonuç listelerinin bir Python temsilini basan tam bir program karakter içeren listeler).

Çevrimiçi deneyin! (karakter listesinin bir Python tarafından alıntılanan dize olarak biçimlendirilerek bir Jelly programına aktarıldığını unutmayın)

Nasıl?

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 bayt

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

Çevrimiçi deneyin!

Sorunun yeniden ifade edilmesinin başarılı bir şekilde sona erdiğini ve doğru çıktı ürettiğini bulmak beni çok şaşırttı.

Yüklemin bu kodun altında yüklem 2 olarak var olduğunu varsayar. Liste listesi ("parçalar") veya falseboş bir girdi için çıktı verir.

Açıklama:

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

Adám'a beni 1 bayt kurtardığı için teşekkürler.

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

Çevrimiçi deneyin! açıklama amacıyla 17 baytlık bir çözüm bırakacağım.

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

⍺⍺¨⍵aplies bir Boole vektör dönen listesine yüklem
+\çalışan toplam oluşturur
1⌈gelen yerine geçer 0s ile 1s
⌈⍺÷⍨bölme yukarı yığın büyüklüğü ve mermi tarafından her bir eleman
⍵⊆⍨, bu göre bölme orijinal vektör


2
Bu etkileyici! Ve çıktı ekranını seviyorum, sorun için uygun görsel.
sundar - Monica'yı yeniden

Program (tradfn gövdesine) dönüştürerek bir byte kaydedin:w⊆⍨⌈⎕÷⍨1⌈+\⎕¨w←⎕
Adam

5

Temiz , 96 92 bayt

Adlandırılmış bir işlev kullanır f :: a -> BoolMeta konsensusa göre izin verilen .

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

Çevrimiçi deneyin!

Genişletilmiş (yorumların görünmesi için varsayılan vurgulama ile):

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

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 kesinlikle bu meydan okuma için doğru dil değil (veya tabii ki herhangi bir codegolf meydan okuması ..)

@OOBalance sayesinde -21 bayt

Çevrimiçi deneyin.

Açıklama:

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

Kara kutu giriş formatı:

Bu meta cevaba göreboolean f(Object i) izin verilen adlandırılmış bir fonksiyonun var olduğunu varsayar .

Yukarıdaki lambda yanı sıra Testvarsayılan işlevi içeren soyut bir sınıf var 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;}
  ;
}

Test durumları için bu işlevin üzerine yazıyorum f. Örneğin, son test senaryosu şöyle adlandırılır:

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 bilmiyorum, en azından birkaç durumda Temiz cevaplarımı yendin. Her neyse, ben her zaman cevaplarını dört gözle bekliyorum.
18

2
@ Οurous Java'nın herhangi bir şekilde codegolf için uygun olmadığı, Jelly, 05AB1E, vb. Java olsa (ve siz de Temiz sanırım). Ve bir (uzun) kez, Java Python'u yenebilir . ;) Ve bir zamanlar bash onu mahvetene kadar Java ile başa çıkmış bir cevaptım (ve R daha da golf oynadı). xD
Kevin Cruijssen

1
Dizilerin bir listesini döndürürseniz 186 bayt: bit.ly/2mSjCIc
OOBalance

@OOBalance Teşekkürler! Akıllı kullanımı Arrays.copyOfRange!
Kevin Cruijssen

@OOBalance, girişi List olarak alarak ve kullanarak biraz daha golf yapabildi .sublist. Bunun dışında işlevselliğiniz aynı kalır, ancak çok fazla bayt tasarrufu sağlar ve içe aktarmayı kaldırır. (Ve şimdi tamsayı yerine karakterlerle test
senaryosu


3

C (gcc) , 70 66 bayt

C bu tür şeyleri bilmediği için bir alt listenin başlangıcını not etmek için bir yapı kullanıyorum.

Öneriler için ceilingcat'e teşekkürler.

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

Çevrimiçi deneyin!


3

Haskell, 72 bayt

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

Çevrimiçi deneyin!

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 bayt

HyX$Ysi/Xk1y>+!w7XQ

Dayanarak jslip mükemmel APL cevap .

MATL gerçekten kullanıcı tanımlı işlevlere sahip değildir, ancak üzerinde çalıştığı çevreyi (MATLAB / Octave) çağırmanın bir yolu vardır, bu nedenle bu, yüklem işlevi için bunu kullanır. Kullanımı gibi bir şey olurdu bu , ama bu işlevselliği işte bir kodlanmış kullanan bir versiyonu, güvenlik nedenleriyle çevrimiçi devre dışıdır isoddyerine yüklem işlevi: Matl Online Deneyin .

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 bayt

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

Çevrimiçi deneyin!

Giriş dizisi a, yığın boyutu nve yüklemi kabul eden anonim lambda g. cYüklemle eşleşen öğelerin bir sayacını tutar ve öğeleri zaten kullanılmış olan parça sayısına göre gruplandırır. Ne yazık ki, başlangıç ​​değeri -1 / n 0'a yuvarlanmaz, bu yüzden düzeltmek için birkaç bayt harcamalıyız.


2

R , 100 bayt

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],"
")

Çevrimiçi deneyin!

digEmAll tarafından handgalled


Çıkış olarak adlandırılmış listeler tamam olup olmadığını bilmiyorum (ve bazı kenar durumlarda kaçırdıysanız ...): 65 bayt
digEmAll

Hmm, bunu ayrı bir cevap olarak gönderirim!
Giuseppe



1

Mathematica, 82 bayt

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

Ungolfed:

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

lgirdi listesidir; syığın boyutu; p, adsız / anonim / saf / lambda işlevidir ve liste öğelerinde doğru / yanlış işlemi döndürür.

Last@Reap[...]Sowiçinde -n olan her öğenin bir listesini döndürür .... İkinci argümanı e~Sow~tsteno için olan alt listelere ayrılırlar Sow[e, t].

Ben 1 bir yığın boyutu işlemek için -1 için sayaçları başlatmak zorunda kaldı, aksi takdirde Mod[i, s]( i~Mod~s) asla olmayacak 1'e eşit ( ) kontrol etmek gerekir .

Kodun geri kalanı ungolfed blokta açıklanmıştır.

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.