Sắp xếp phân vùng từ điển của một số


17

Thử thách thực sự rất đơn giản: được cung cấp một số, bạn chia các chữ số của nó thành một mảng gồm các số nhỏ hơn sao cho các số kết quả không giảm. Điều hấp dẫn là bạn phải chia nó sao cho độ dài mảng là tối đa.

Bối rối?

  • Bạn được cung cấp một số nguyên dương thông qua STDIN (hoặc thay thế gần nhất), đối số dòng lệnh hoặc đối số hàm trong bất kỳ định dạng đầu vào thuận tiện, rõ ràng nào.
  • Bạn phải phân vùng các chữ số thập phân của số thành các nhóm liền kề nhau, rời rạc.
  • Mảng số được biểu thị bởi các nhóm chữ số này phải được sắp xếp (theo thứ tự thông thường, không giảm) mà không sắp xếp lại các nhóm .
  • Trong trường hợp có nhiều phân vùng như vậy tồn tại, bạn phải phân vùng đầu vào thành càng nhiều số càng tốt. Trong trường hợp quan hệ, trả lại một kết quả như vậy.
  • Bạn có thể xuất mảng thành STDOUT (hoặc thay thế gần nhất) hoặc dưới dạng giá trị trả về của hàm. Trong trường hợp STDOUT (hoặc thay thế gần nhất), mảng phải được in ở bất kỳ định dạng danh sách thuận tiện, rõ ràng nào.
  • Các số chia không nên có số 0 đứng đầu. Vì vậy, ví dụ 1002003không thể được in dưới dạng [1, 002, 003]hoặc [1, 2, 3]và câu trả lời hợp lệ duy nhất cho nó là [100, 2003].

Các trường hợp thử nghiệm:

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]

Chấm điểm

Đây là mã golf để mã ngắn nhất tính theo byte thắng.

Câu trả lời:


10

Bình thường, 34

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

Hãy thử trực tuyến tại đây . Lưu ý, điều này có độ phức tạp thời gian (và không gian) của O (n). Do đó, trường hợp thử nghiệm 12345678901234567890mất quá nhiều thời gian trong trình biên dịch trực tuyến. Sử dụng ngoại tuyến thay thế (1 phút trên máy tính xách tay của tôi).

Đây chỉ là nỗ lực đầu tiên của tôi. Có thể có một số chỗ để cải thiện.

Đầu tiên một số ý tưởng làm thế nào thuật toán của tôi hoạt động.

  • Tôi giải thích đầu vào là chuỗi và không phải là một số.
  • Sau đó, tôi tạo tất cả các tập hợp con có thể của [0, 1, 2, ..., len(n-1)]
  • Đối với mỗi tập hợp con này (cho phép [1, 4, 5]), tôi chia chuỗi đầu vào thành một phần bằng các số này. [input[0:1], input[1, 4], input[4,5], input[5,len(input)]].
  • Sau đó tôi cố gắng chuyển đổi những số này thành chuỗi. Có thể có hai vấn đề. Pyth (hoặc Python) đưa ra một ngoại lệ cho một chuỗi rỗng và cho một chuỗi số bắt đầu bằng 0. Vì vậy, tôi sử dụng một try - catchkhối (thực sự là vòng lặp vô cực với một phá vỡ ngay lập tức). Nếu chuyển đổi thành công, tôi thêm kết quả vào danh sách Y.
  • Sau khi tôi xử lý tất cả các tập hợp con, tôi lọc danh sách Ycho các kết quả, đã được sắp xếp và in cái cuối cùng (cái cuối cùng có nhiều nhóm nhất).

Bây giờ giải thích chi tiết:

                            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)

Bạn có thể sử dụng aYthay vì~Y]
FryAmTheEggman

@FryAmTheEggman Tôi luôn quên mất a. Không biết tại sao.
Jakube

@Jakube Có lẽ vì nó không có trong tài liệu?
Sp3000

Tôi đã có một giải pháp cho ~ 45 ký tự. Tôi đã không nhận thức được thực tế int("01")là lỗi trong Pyth (điều này không xảy ra với Python).
orlp 18/03/2015

3
@Jakube haha, mặc dù có vẻ hợp lý, nhưng nói chung nlà độ dài của đầu vào.
Tối ưu hóa

6

Toán học, 134 127 byte

Điều này khá kém hiệu quả vì nó tạo ra nhiều phân vùng hơn các phân vùng hợp lệ. Các 324142434445trường hợp thử nghiệm chạy trong vòng vài giây, nhưng tôi sẽ không cố gắng 12345678901234567890.

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

Điều này xác định một hàm không tên, lấy một số nguyên và trả về một danh sách các số nguyên.

Giải trình

Thứ tự đọc của mã này là một chút ở khắp mọi nơi, vì vậy tôi sẽ chia nhỏ theo thứ tự mà nó dự định sẽ được đọc (và được đánh giá cho hầu hết các phần):

  • d=IntegerDigits@#lấy các chữ số thập phân của đầu vào và gán danh sách này cho d.
  • SetPartitions(yêu cầu Needs@"Combinatorica`";) cung cấp cho tôi tất cả các phân vùng này. Tuy nhiên, nó trả về nhiều hơn tôi thực sự muốn vì nó coi đầu vào là một bộ . Đây là những gì làm cho nó không hiệu quả, nhưng tôi đang sử dụng điều này bởi vì cách ngắn nhất tôi biết để có được tất cả các phân vùng danh sách dài hơn nhiều. Ví dụ, nếu danh sách là {1, 2, 3}hàm sẽ trả về:

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

    Lưu ý rằng a) các phân vùng liên tiếp đều theo đúng thứ tự và b) các phân vùng được sắp xếp từ thô nhất đến tốt nhất.

  • Select[...,...&] sau đó lọc danh sách này bằng hàm ẩn danh được truyền vào làm đối số thứ hai.
    • Join @@ # == d kiểm tra xem chúng tôi thực sự có phân vùng danh sách thay vì phân vùng chung.
    • #~FreeQ~{0, __} kiểm tra xem không có phân vùng nào bắt đầu bằng số 0 đứng đầu.
    • 0 <= ## & @@ f /@ #là một chút tối nghĩa. Đầu tiên chúng tôi ánh xạ FromDigitsvào từng danh sách trong phân vùng để phục hồi các số được biểu thị bằng các chữ số. Sau đó, chúng tôi áp dụng 0 <= ##cho những số đó, trong đó ##đề cập đến tất cả các số. Nếu phân vùng là {1, 23, 45}cái này mở rộng ra 0 <= 1 <= 23 <= 45, vì vậy nó kiểm tra xem mảng đã được sắp xếp chưa.
  • Last@ sau đó đưa cho tôi phân vùng cuối cùng còn lại sau khi lọc - điều này hoạt động vì SetPartitions đã sắp xếp các phân vùng, sao cho những phân vùng tốt nhất ở cuối.
  • Cuối cùng, f/@phục hồi các số từ danh sách chữ số.

5

Python 3, 134 byte

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

Nó hơi lộn xộn, nhưng tốt. Chương trình chỉ tạo ra tất cả các phân vùng hợp lệ đệ quy. Phần thú vị là không cho phép các số 0 đứng đầu, tất cả những gì cần thiết là một or "1">s[i:]>""điều kiện bổ sung .

Lấy đầu vào thích f("12345678901234567890")và trả về một danh sách các số nguyên.


4

Bình thường 62 61 60

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

Giải trình

Thuật toán hoạt động bằng cách tạo ra tất cả các số nhị phân giữa 0(bao gồm) và 2^(n-1)(độc quyền), trong đó nđộ dài của đầu vào.

Các chữ số nhị phân của mỗi sau đó được ánh xạ tới một dấu phân cách ( N) cho 1 và không có gì cho 0.

Các ký tự này sau đó được chèn vào giữa mỗi ký tự đầu vào và kết quả được chia cho N , thu được một danh sách.

Các giá trị trong danh sách sau đó được phân tích cú pháp thành số nguyên và danh sách được sắp xếp theo độ dài. Sau đó, tất cả những gì còn lại là để lọc ra những cái không được sắp xếp và những cái đã được phân chia tại các số 0 đứng đầu, sau đó danh sách dài nhất được chọn.

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

(KHÔNG CẠNH TRANH) Pyth, 25 byte

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

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

Làm thế nào nó hoạt động:

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 byte

Rất dài nhưng ít nhất chiếm hết bộ nhớ O (n * (2n)!) Và thời gian O (n * log (n) * (2n)!) Trong đó n là độ dài của đầu vào. (Vì vậy, đừng cố chạy nó với hơn 5 chữ số.)

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

Hàm lấy đầu vào là một chuỗi.

Ví dụ:

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

Phương pháp:

  • Thêm cùng số lượng khoảng trắng vào đầu vào theo chiều dài của nó.
  • Cho phép nó theo mọi cách có thể.
  • Kiểm tra xem chuỗi không gian có giống với đầu vào không (nghĩa là phân vùng của chuỗi đó).
  • Thay thế '0' thành '_1' để vô hiệu hóa các giải pháp zero hàng đầu.
  • Đánh giá từng chuỗi.
  • Tìm danh sách dài nhất cũng được sắp xếp. Đây là giá trị trả về.

0

Haskell, 161 byte

(#)=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]

Chạy thử nghiệm:

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

Cách thức hoạt động: chức năng của trình trợ giúp fchia danh sách đầu vào thành mọi danh sách có thể có của danh sách phụ. gđầu tiên loại bỏ những người có một danh sách con bắt đầu bằng 0và sau đó những người không có thứ tự thích hợp. Ghép nối mọi danh sách còn lại với độ dài của nó, lấy tối đa và loại bỏ phần chiều dài một lần nữa.

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.