Bir Sayının Sıralı Sözcüksel Bölümü


17

Zorluk gerçekten basit: bir sayı verildiğinde, elde edilen sayılar azalmayacak şekilde basamaklarını daha küçük sayılara ayırırsınız. Yakalama, dizi uzunluğu maksimum olacak şekilde bölmeniz gerektiğidir.

Şaşkın?

  • STDIN (veya en yakın alternatif), komut satırı bağımsız değişkeni veya işlev bağımsız değişkeni ile uygun, açık olmayan herhangi bir girdi biçiminde pozitif bir tam sayı verilir.
  • Sayının ondalık basamaklarını bitişik, ayrık gruplara ayırmanız gerekir.
  • Bu rakam grupları tarafından temsil edilen sayılar dizisi, gruplar yeniden düzenlenmeden sıralanır (normalde, azalmayan sırada) .
  • Bu tür birden fazla bölümün mevcut olduğu durumlarda, girdiyi mümkün olduğunca çok sayıda bölüme ayırmanız gerekir. Bağlar durumunda, böyle bir sonuç döndürün.
  • Diziyi STDOUT (veya en yakın alternatif) olarak veya işlev dönüş değeri olarak çıktılayabilirsiniz. STDOUT (veya en yakın alternatif) durumunda, dizi herhangi bir uygun, açık liste formatında yazdırılmalıdır.
  • Bölünmüş sayıların başında sıfır olmamalıdır. Yani örneğin 1002003ya [1, 002, 003]da olarak yazdırılamaz [1, 2, 3]ve bunun tek geçerli cevabıdır [100, 2003].

Test senaryoları:

123456 -> [1, 2, 3, 4, 5, 6]
345823 -> [3, 4, 5, 8, 23]
12345678901234567890 -> [1, 2, 3, 4, 5, 6, 7, 8, 90, 123, 456, 7890]
102 -> [102]
302 -> [302]
324142 -> [3, 24, 142] OR [32, 41, 42]
324142434445 -> [32, 41, 42, 43, 44, 45]
1356531 -> [1, 3, 5, 6, 531]
11121111111 -> [1, 1, 1, 2, 11, 11, 111]
100202003 -> [100, 202003]

puanlama

Bu kod golf yani bayt en kısa kod kazanır.

Yanıtlar:


10

Pyth, 34

FNyUz#aYmv:zhdedC,+0N+NlzB)efqSTTY

Buradan çevrimiçi deneyin . Dikkat edin, bu O (n) 'nin zaman (ve uzay) karmaşıklığına sahiptir. Bu nedenle test durumu 12345678901234567890çevrimiçi derleyicide çok uzun sürüyor. Bunun yerine çevrimdışı olanı kullanın (dizüstü bilgisayarımda 1 dakika).

Bu sadece ilk denemem. İyileştirmeler için biraz yer olabilir.

Öncelikle algoritmamın nasıl çalıştığı hakkında bazı fikirler.

  • Girişi sayı olarak değil dize olarak yorumluyorum.
  • Sonra tüm olası alt kümelerini [0, 1, 2, ..., len(n-1)]
  • Bu alt kümelerin her biri için (hadi alalım [1, 4, 5]), bu sayıları kullanarak giriş dizesini parçalara ayırdım.[input[0:1], input[1, 4], input[4,5], input[5,len(input)]].
  • Daha sonra bu sayıları dizgeye dönüştürmeye çalışıyorum. İki sorun olabilir. Pyth (veya Python), boş bir dize ve ile başlayan bir sayı dizesi için bir istisna atar 0. Bu nedenle bir try - catchblok kullanıyorum (aslında bir mola ile sonsuzluk döngüsü). Dönüştürme işlemi başarılı olduysa, sonucu listeye eklerim Y.
  • Tüm altkümeleri işledikten sonra, listeyi Yzaten sıralanmış olan ve sonuncuyu (sonuncusu en çok grubu olan) yazdıran sonuçlar için filtrelerim .

Şimdi ayrıntılı açıklama:

                            Implicit: z = input() (z is a String!)
                                      Y = empty list
FNyUz                       for each subset N of [0, 1, 2, ..., len(z)-1]:

     #                         start try-catch block (actually an infinite loop, 
                               but the Python implementation uses a try catch. 

      aY                          append to Y:
                C,+0N+Nlz            zip([0] + N, N + [len(z)])
        m                            map each element d to
          :zhded                     z[d[0]:d[-1]]
         v                           evaluated
                         B        if this didn't throw an exception already, end the infinite loop
                          ) end for loop   

 f    Y      filter Y for elements T, for which
  qSTT           sorted(T) == T
e            and print the last one (the subsets generated with yUz are sorted 
             by length, so the last one has the most groups)

Bunun aYyerine kullanabilirsiniz~Y]
FryAmTheEggman 18:15

@FryAmTheEggman Her zaman unuturum a. Neden bilmiyorum.
Jakube

@ Jakube Belki de dokümanlarda olmadığı için?
Sp3000

Ben ~ 45 karakter için bir çözüm vardı. Ben int("01")Pyth (bu Python gerçekleşmez) bir hata olmanın farkında değildi.
orlp

3
@Jakube haha, mantıklı gibi görünse de, genellikle ngirdinin uzunluğudur.
Doktor

6

Mathematica, 134 127 bayt

Geçerli olanlardan çok daha fazla bölüm oluşturduğundan bu oldukça verimsizdir . 324142434445Test durumu birkaç saniye içinde çalışır, ama denemek olmaz 12345678901234567890.

f/@Last@Select[Needs@"Combinatorica`";f=FromDigits;SetPartitions[d=IntegerDigits@#],0<=##&@@f/@#&&Join@@#==d&&#~FreeQ~{0,__}&]&

Bu, bir tamsayı alan ve bir tamsayı listesi döndüren adsız bir işlevi tanımlar.

açıklama

Bu kodun okuma sırası her yerde biraz, bu yüzden okunması amaçlanan sırayla yıkacağım (ve çoğunlukla değerlendirildi):

  • d=IntegerDigits@#girişin ondalık basamağını alın ve bu listeyi atayın d.
  • SetPartitions(ki gerektirir Needs@"Combinatorica`";) bana tüm bu bölümleri verir. Ancak, girdiyi küme olarak değerlendirdiğinden, aslında istediğimden çok daha fazla döndürür . Bu onu verimsiz yapan şey, ama bunu kullanıyorum çünkü tüm liste bölümlerini almanın en kısa yolu çok daha uzun. Örnek olarak, eğer liste işlevse {1, 2, 3}, geri dönecektir:

    {{{1, 2, 3}}, {{1}, {2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2}, {3}}}
    

    A) ardışık bölümlerin hepsinin doğru sırada olduğunu ve b) bölümlerin en kabadan en iyiye doğru sıralandığını unutmayın.

  • Select[...,...&] daha sonra bu listeyi ikinci argüman olarak iletilen anonim işleve göre filtreler.
    • Join @@ # == d genel set bölümü yerine bir liste bölümümüzün olup olmadığını kontrol eder.
    • #~FreeQ~{0, __} hiçbir bölümün başında sıfır ile başlayıp başlamadığını kontrol eder.
    • 0 <= ## & @@ f /@ #biraz daha belirsiz. İlk olarak FromDigits, rakamlarla temsil edilen sayıları kurtarmak için bölümdeki her listeyi eşleriz. Sonra tüm sayıları ifade eden 0 <= ##bu sayılara uygulanır ##. Bölüm o {1, 23, 45}zaman bu genişler 0 <= 1 <= 23 <= 45, bu nedenle dizinin sıralandığını kontrol eder.
  • Last@sonra filtrelemeden sonra kalan son bölümü verir - bu SetPartitions, bölümleri zaten sıraladığı için çalışır , böylece en iyi bölümler sonunda olur.
  • Son olarak, f/@sayı listelerinden sayıları kurtarır.

5

Python 3, 134 bayt

def f(s,n=0,L=[],R=[],i=0):
 while s[i:]:i+=1;m=int(s[:i]);R=max([f(s[i:],m,L+[m]),R][m<n or"1">s[i:]>"":],key=len)
 return[L,R][s>""]

Biraz dağınık, ama oh iyi. Program tüm geçerli bölümleri özyinelemeli olarak oluşturur. İlginç olan, önde gelen sıfırlara izin vermemek için gerekli olan tek şeyor "1">s[i:]>"" durumdu.

Gibi girişi alır f("12345678901234567890")ve bir ints listesi döndürür.


4

Pyth, 62 61 60

JlzKkef&qJsml`dTqTSTolNmmibTcjKsC,z+m>Ndt>+*J]0jk2_JKNU^2-J1

açıklama

Algoritma , girişin uzunluğu olan 0(dahil) ve 2^(n-1)(hariç) arasındaki tüm ikili sayıları üreterek çalışır n.

Her birinin ikili rakamları daha sonra N1 için bir ayırıcıya ( ) eşlenir ve 0 için hiçbir şey eşlenmez .

Bu karakterler daha sonra her bir giriş karakteri arasına eklenir ve sonuç, Nbir liste vererek bölünür .

Daha sonra listelerdeki değerler tamsayılara ayrıştırılır ve listeler uzunluğa göre sıralanır. Sonra kalan tek şey, sıralanmamış olanları ve baştaki sıfırlara bölünmüş olanları filtrelemektir, bundan sonra en uzun liste seçilir.

Jlz                                                   set J to len(input)
Kk                                                    set K to ""
e                                                     take the last of:
 f&                                                    only take lists where:
   qJsml`dT                                             sum of string lengths of items
                                                        is equal to length of input and
           qTST                                         list is in order
               olN                                       sort by length
                  m                                       map k over...
                   mibT                                    convert items to int (base-10)
                       c                        N           split by N
                        jK                                   join by ""
                          s                                   sum to combine tuples
                           C,z                                 zip input with
                              +                K                append [""] for equal lengths
                               m>Nd                              replace 1 with N, 0 with ""
                                   t                              take all but first
                                    >        _J                    take len(input) last values
                                     +                              pad front of binary with
                                      *J]0                           [0] times input's length
                                          jk2                        current k in binary
                                                 U^2-J1  range 0..2^(len(input)-1)-1

1

(YARIŞMAYAN) Pyth, 25 bayt

ef&&Fmnhd\0T.A<V=NsMTtN./

Çevrimiçi deneyin!

Nasıl çalışır:

ef&&Fmnhd\0T.A<V=NsMTtN./  Q = eval(input())
                         ./  all partitions of Q
 f                       ./  filter all partitions of Q where:
  &                            both:
   &Fmnhd\0T                     neither substring starts with "0"
                               and:
            .A<V=NsMTtN          all entries are less than their proceeding ones
e                            returns the last amongst the filtered partitions

0

J, 109 bayt

Çok uzun ama en azından O (n * (2n)!) Belleği ve O (n * log (n) * (2n)!) Süresini kapsıyor, burada n girişin uzunluğu. (Bu yüzden 5 basamaktan fazla çalıştırmayı denemeyin.)

f=.3 :0
>({~(i.>./)@:(((-:/:~)@(#$])*#)@>))<@".(' 0';' _1')rplc"1~(#~y-:"1' '-."#:~])(i.!2*#y)A.y,' '#~#y
)

İşlev, girdiyi dize olarak alır.

Örnekler:

   f every '5423';'103';'1023'
  5 423
103   0
 10  23

Yöntem:

  • Girdiye uzunluğu ile aynı sayıda boşluk ekleyin.
  • Olası her şekilde izin verin.
  • Boşluksuz dizenin girişle aynı olup olmadığını kontrol edin (yani, bunun bir bölümüdür).
  • Baştaki sıfır çözümleri geçersiz kılmak için '0'ları' _1'leri değiştirin.
  • Her dizeyi değerlendirin.
  • Ayrıca sıralanmış en uzun listeyi bulun. Bu, dönüş değeridir.

0

Haskell, 161 bayt

(#)=map
f[x]=[[[x]]]
f(h:t)=([h]:)#f t++(\(a:b)->(h:a):b)#f t
g l=snd$maximum[(length x,x::[Int])|x<-[read#y|y<-f l,all((/='0').head)y],and$zipWith(>=)=<<tail$x]

Test sürüşü:

*Main> mapM_ (print . g) ["123456","345823","12345678901234567890","102","302","324142","324142434445","1356531","11121111111","100202003"]
[1,2,3,4,5,6]
[3,4,5,8,23]
[1,2,3,4,5,6,7,8,90,123,456,7890]
[102]
[302]
[32,41,42]
[32,41,42,43,44,45]
[1,3,5,6,531]
[1,1,1,2,11,11,111]
[100,202003]

Nasıl çalışır: yardımcı işlev f, giriş listesini olası her alt liste listesine böler. gönce bir alt listeye sahip 0olanları ve sonra uygun sıraya sahip olmayanları atar . Kalan her listeyi uzunluğu ile eşleştirin, maksimumu alın ve uzunluk kısmını tekrar atın.

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.