พาร์ติชันคำศัพท์ที่เรียงของตัวเลข


17

ความท้าทายนั้นง่ายมาก: เมื่อได้ตัวเลขคุณจะแบ่งตัวเลขออกเป็นอาเรย์ของตัวเลขที่เล็กลงซึ่งตัวเลขที่ได้จะไม่ลดลง การจับคือคุณต้องแยกมันให้ยาวที่สุด

สับสน?

  • คุณจะได้รับจำนวนเต็มบวกผ่าน STDIN (หรือทางเลือกที่ใกล้เคียงที่สุด) อาร์กิวเมนต์บรรทัดคำสั่งหรืออาร์กิวเมนต์ฟังก์ชันในรูปแบบอินพุตที่สะดวกและชัดเจน
  • คุณต้องแบ่งตัวเลขทศนิยมให้เป็นกลุ่มที่ต่อเนื่องกัน
  • อาร์เรย์ของตัวเลขที่แสดงโดยกลุ่มหลักเหล่านี้ควรเรียงลำดับ (ตามลำดับปกติไม่ลด) โดยไม่ต้องจัดเรียงกลุ่มใหม่
  • ในกรณีที่มีพาร์ติชั่นดังกล่าวมากกว่าหนึ่งตัวคุณต้องแบ่งพาร์ติชันอินพุตให้เป็นตัวเลขให้ได้มากที่สุด ในกรณีของความสัมพันธ์ให้ส่งคืนผลลัพธ์หนึ่งรายการ
  • คุณสามารถส่งออกอาร์เรย์เพื่อ STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด) หรือเป็นค่าตอบแทนการทำงาน ในกรณีของ STDOUT (หรือทางเลือกที่ใกล้เคียงที่สุด) อาร์เรย์ควรพิมพ์ในรูปแบบรายการที่สะดวกและไม่คลุมเครือ
  • ตัวเลขที่แยกไม่ควรมีเลขศูนย์นำหน้า ดังนั้นสำหรับตัวอย่างเช่น1002003ไม่สามารถพิมพ์ออกมาเป็นอย่างใดอย่างหนึ่ง[1, 002, 003]หรือและคำตอบที่ถูกต้องเพียงเพราะมันเป็น[1, 2, 3][100, 2003]

กรณีทดสอบ:

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]

เกณฑ์การให้คะแนน

นี่คือโค้ดกอล์ฟที่สั้นที่สุดในหน่วยไบต์

คำตอบ:


10

Pyth, 34

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

ลองมันออนไลน์ได้ที่นี่ โปรดสังเกตว่าสิ่งนี้มีความซับซ้อนของเวลา (และที่ว่าง) เป็น O (n) ดังนั้นกรณีทดสอบ12345678901234567890ใช้เวลานานในคอมไพเลอร์ออนไลน์ ใช้ออฟไลน์แทน (1 นาทีบนแล็ปท็อปของฉัน)

นี่เป็นเพียงความพยายามครั้งแรกของฉัน อาจมีห้องสำหรับการปรับปรุง

ก่อนอื่นให้คิดบางอย่างว่าขั้นตอนวิธีของฉันทำงาน

  • ฉันตีความอินพุตเป็นสตริงไม่ใช่ตัวเลข
  • จากนั้นฉันสร้างส่วนย่อยที่เป็นไปได้ทั้งหมดของ [0, 1, 2, ..., len(n-1)]
  • สำหรับแต่ละชุดย่อยเหล่านี้ (ลองดู[1, 4, 5]) ฉันแบ่งสตริงอินพุตออกเป็นส่วนหนึ่งโดยใช้ตัวเลขเหล่านี้ [input[0:1], input[1, 4], input[4,5], input[5,len(input)]].
  • หลังจากนั้นฉันพยายามแปลงตัวเลขเหล่านี้เป็นสตริง อาจมีสองปัญหา Pyth (หรืองูใหญ่) 0พ่นข้อยกเว้นสำหรับสตริงที่ว่างเปล่าและสำหรับสตริงของตัวเลขที่เริ่มต้นด้วย ดังนั้นฉันจึงใช้try - catchบล็อก (อันที่จริงวงอินฟินิตี้ที่มีตัวแบ่งทันที) Yถ้าแปลงเป็นเรียบร้อยแล้วฉันจะเพิ่มผลไปยังรายการ
  • หลังจากที่ฉันจัดการชุดย่อยทั้งหมดฉันกรองรายการYผลลัพธ์ที่เรียงแล้วและพิมพ์ชุดสุดท้าย (ชุดสุดท้ายมีกลุ่มมากที่สุด)

ตอนนี้คำอธิบายรายละเอียด:

                            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)

คุณสามารถใช้aYแทน~Y]
FryAmTheEggman

@FryAmTheEggman aฉันมักจะลืมเกี่ยวกับ ไม่รู้ทำไม
Jakube

@Jakube อาจเป็นเพราะมันไม่ได้อยู่ในเอกสารเหรอ?
Sp3000

ฉันมีทางออกสำหรับ ~ 45 ตัวอักษร ฉันไม่ทราบว่าint("01")เป็นข้อผิดพลาดใน Pyth (สิ่งนี้ไม่ได้เกิดขึ้นใน Python)
orlp

3
@Jakube ฮ่าฮ่าแม้ว่าจะดูสมเหตุสมผล แต่โดยทั่วไปแล้วnก็คือความยาวของอินพุต
เครื่องมือเพิ่มประสิทธิภาพ

6

Mathematica, 134 127 bytes

นี้จะไม่มีประสิทธิภาพสวยเพราะมันสร้างจำนวนมากพาร์ทิชันมากขึ้นกว่าคนที่ถูกต้อง 324142434445กรณีทดสอบวิ่งภายในไม่กี่วินาที 12345678901234567890แต่ผมจะไม่พยายาม

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

ฟังก์ชันนี้กำหนดฟังก์ชันที่ไม่มีชื่อซึ่งใช้จำนวนเต็มและส่งกลับรายการจำนวนเต็ม

คำอธิบาย

ลำดับการอ่านของรหัสนี้ค่อนข้างทั่วสถานที่ดังนั้นฉันจะแยกตามลำดับที่ตั้งใจจะอ่าน (และประเมินผลเป็นส่วนใหญ่):

  • d=IntegerDigits@#dรับตัวเลขทศนิยมของการป้อนข้อมูลและกำหนดรายการนี้เพื่อ
  • SetPartitions(ซึ่งต้องการNeeds@"Combinatorica`";) ให้พาร์ติชันทั้งหมดของฉันนี้ แต่มันกลับมากขึ้นกว่าที่จริงผมต้องการเพราะมันถือว่าการป้อนข้อมูลที่เป็นชุด นี่คือสิ่งที่ทำให้มันไม่มีประสิทธิภาพ แต่ฉันใช้สิ่งนี้เพราะวิธีที่สั้นที่สุดที่ฉันรู้เพื่อให้พาร์ทิชันรายการทั้งหมดนั้นยาวขึ้น ตัวอย่างเช่นถ้ารายการเป็น{1, 2, 3}ฟังก์ชันจะส่งคืน:

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

    โปรดทราบว่า a) พาร์ติชั่นต่อเนื่องทั้งหมดถูกต้องและ b) พาร์ติชั่นนั้นเรียงลำดับจากหยาบไปสุด

  • Select[...,...&] จากนั้นกรองรายการนี้โดยฟังก์ชั่นที่ไม่ระบุชื่อที่ส่งผ่านเป็นอาร์กิวเมนต์ที่สอง
    • Join @@ # == d ตรวจสอบว่าเรามีพาร์ทิชันรายการจริงแทนที่จะเป็นพาร์ติชันชุดทั่วไป
    • #~FreeQ~{0, __} ตรวจสอบว่าไม่มีพาร์ติชันเริ่มต้นด้วยศูนย์นำหน้า
    • 0 <= ## & @@ f /@ #ค่อนข้างคลุมเครือมากขึ้น ก่อนอื่นเราแผนที่FromDigitsลงในแต่ละรายการในพาร์ติชั่นเพื่อกู้คืนตัวเลขที่แสดงด้วยหลัก จากนั้นเรานำ0 <= ##ไปใช้กับตัวเลขเหล่านั้นโดยที่##อ้างถึงตัวเลขทั้งหมด ถ้าพาร์ติชันอยู่{1, 23, 45}นี่จะขยายเป็น0 <= 1 <= 23 <= 45ดังนั้นจะตรวจสอบว่ามีการเรียงลำดับอาร์เรย์หรือไม่
  • Last@จากนั้นให้พาร์ทิชันสุดท้ายที่ฉันเหลือหลังจากการกรอง - งานนี้เพราะSetPartitionsเรียงพาร์ติชันแล้วเช่นที่ดีที่สุดอยู่ในตอนท้าย
  • ในที่สุดการf/@กู้คืนตัวเลขจากรายการหลัก

5

Python 3, 134 ไบต์

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

มันยุ่งเล็กน้อย แต่ก็ดี โปรแกรมเพิ่งสร้างพาร์ติชันที่ถูกต้องทั้งหมดแบบวนซ้ำ ส่วนที่น่าสนใจคือการไม่อนุญาตให้เป็นศูนย์นำหน้าทั้งหมดที่จำเป็นคือor "1">s[i:]>""เงื่อนไขเพิ่มเติม

รับอินพุตเหมือนf("12345678901234567890")และส่งคืนรายการของ int


4

Pyth, 62 61 60

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

คำอธิบาย

อัลกอริทึมทำงานโดยการสร้างเลขฐานสองทั้งหมดระหว่าง0(รวม) และ2^(n-1)(พิเศษ) โดยที่nความยาวของอินพุต

เลขฐานสองของแต่ละค่าจะถูกแมปกับตัวคั่น ( N) สำหรับ 1 และไม่มีอะไรสำหรับ 0

อักขระเหล่านี้จะถูกแทรกระหว่างอักขระอินพุตแต่ละตัวและผลลัพธ์ถูกแบ่งออกโดย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

(ไม่ใช่การแข่งขัน) Pyth, 25 ไบต์

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

ลองออนไลน์!

มันทำงานอย่างไร:

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 ไบต์

นานมาก แต่อย่างน้อยต้องใช้หน่วยความจำ O (n * (2n)!) และ O (n * log (n) * (2n)!) เวลาที่ n คือความยาวของอินพุต (ดังนั้นอย่าพยายามเรียกใช้ด้วยตัวเลขมากกว่า 5 หลัก)

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

ฟังก์ชันรับอินพุตเป็นสตริง

ตัวอย่าง:

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

วิธี:

  • เพิ่มช่องว่างจำนวนเดียวกันในอินพุตตามความยาว
  • ดัดในทุกทางที่เป็นไปได้
  • ตรวจสอบว่าสตริงที่ไม่มีที่ว่างเหมือนกับอินพุต (เช่นเป็นพาร์ติชันของมัน)
  • แทนที่ '0's เป็น' _1's เพื่อทำให้โซลูชั่นศูนย์นำหน้าไม่ถูกต้อง
  • ประเมินแต่ละสตริง
  • ค้นหารายการที่ยาวที่สุดซึ่งเรียงลำดับด้วย นี่คือค่าตอบแทน

0

Haskell, 161 ไบต์

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

ทดสอบการทำงาน:

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

วิธีการทำงาน: ฟังก์ชั่นfตัวช่วยแยกรายการอินพุตออกเป็นรายการย่อยทั้งหมดที่เป็นไปได้ gก่อนอื่นให้ยกเลิกรายการที่มีรายการย่อยที่ขึ้นต้นด้วย0และจากนั้นรายการที่ไม่มีลำดับที่เหมาะสม จับคู่ทุกรายการที่เหลือด้วยความยาวใช้สูงสุดและทิ้งส่วนความยาวอีกครั้ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.