ระบายสีเสาให้ฉัน


22

ให้บอกว่างานของคุณคือการทาสีเสาและลูกค้าขอให้คุณวาดเสาที่มี 4 ส่วนสีแดงและ 3 ส่วนสีเหลือง คุณสามารถทำได้โดยง่ายดังนี้

r y r y r y r

มีแถบสีเหลืองและสีแดง ตอนนี้ช่วยบอกลูกค้าของคุณขอให้คุณวาดเสามี 2 ส่วนสีแดง 2 ส่วนสีเหลืองและ1 ส่วนสีเขียว มีสองวิธีที่คุณสามารถทาสีเสาของคุณ

g y r y r
y g r y r
y r g y r
y r y g r
y r y r g
g r y r y
r g y r y
r y g r y
r y r g y
r y r y g
y r g r y
r y g y r

แม่นยำกว่านั่นคือ 12 วิธีในการทาสีเสา สิ่งนี้จะทำให้สีและส่วนต่าง ๆ ที่เกี่ยวข้องเพิ่มมากขึ้น

ทีนี้ถ้าลูกค้าของคุณบอกว่าพวกเขาต้องการส่วนสีแดง 3 ส่วนและส่วนสีเหลือง 1 ส่วนไม่มีวิธีการทาสีเสาแบบนั้น เพราะไม่ว่าคุณจะพยายามจัดเรียงส่วนสีแดงสองส่วนอย่างไรและเมื่อแตะสองส่วนสีแดงพวกเขาจะกลายเป็นส่วนสีแดงเดียว

และนั่นเป็นกฎข้อหนึ่งของเราในการทาสีเสา

ส่วนที่อยู่ติดกันอาจไม่เป็นสีเดียวกัน

งาน

รับรายการสีและส่วนที่ต้องการส่งออกจำนวนวิธีที่เป็นไปได้ในการทาสีเสาตามที่ร้องขอ คุณอาจเป็นตัวแทนของสีในลักษณะที่เหมาะสม (จำนวนเต็มตัวอักษรสตริง) แต่คุณจะไม่ได้รับมากกว่า 255 สีที่แตกต่างกันในแต่ละครั้ง หากคุณต้องการคุณสามารถเลือกที่จะไม่มีชื่อสีที่กำหนดและเพียงแค่ใช้รายการของส่วนที่มีการนับหากทำได้ง่ายขึ้น

กรณีทดสอบ

การคำนวณด้วยมือค่อนข้างยากโดยเฉพาะเมื่อมีขนาดใหญ่ หากใครมีกรณีทดสอบแนะนำฉันจะเพิ่ม

[4,3]    -> 1
[2,2,1]  -> 12
[3,1]    -> 0
[8,3,2]  -> 0
[2,2,1,1]-> 84

เราจะรับอินพุตเป็น "rrrryyy" สำหรับ [4,3] ได้ไหม?
Leo

@Leo แน่นอนว่ามีเหตุผลอย่างสมบูรณ์แบบ
ข้าวสาลีตัวช่วยสร้าง

ฉันจะได้รับการป้อนข้อมูลเป็น[1, 1, 1, 1, 2, 2, 2]? ผมว่าอย่างนั้น.
Erik the Outgolfer


4
ไม่สำคัญอย่างยิ่ง แต่การใช้ประโยชน์จากคำว่า Pole ทำให้ดูเหมือนว่าคุณกำลังพูดถึงบุคคลจากโปแลนด์
นิวแฮมป์เชียร์

คำตอบ:


9

Mathematica, 37 44 48 60 62 ไบต์

{1, 1, 1, 2, 2}ใช้การป้อนข้อมูลเป็นรายการของจำนวนเต็ม ลองบนวุลแฟรม Sandbox

วิธีการจับคู่รูปแบบขอบคุณ @ ไม่ต้นไม้!

Count[Split/@Permutations@#,{{_}..}]&

Splitแยกรายการเดียวออกเป็นรายการย่อยขององค์ประกอบต่อเนื่องเช่น{1, 1, 2, 3, 4, 4}เข้าไป{{1, 1}, {2}, {3}, {4, 4}}

{{_}..}คือคือ{{_}, {_}, {_}, ...}. รูปแบบที่ตรงกับรายการของรายการย่อย unary

Differences วิธีการ 48 ไบต์:

Tr@Abs@Clip[1##&@@@Differences/@Permutations@#]&

รหัสใช้Differencesเพื่อตรวจสอบว่าองค์ประกอบที่อยู่ติดกันเหมือนกัน

เป็นขั้นเป็นตอน:

  1. Permutations@# สร้างการเรียงสับเปลี่ยนทั้งหมดของรายการอินพุตให้เป็นรายการ N! * N
  2. Differences/@ คำนวณความแตกต่างระหว่างองค์ประกอบ N และให้รายการ N! * (N-1)
  3. 1##&@@@คำนวณการคูณของรายการทั้งหมด หากรายการมี0(สององค์ประกอบที่อยู่ติดกันเหมือนกัน) ผลลัพธ์จะเป็น0มิฉะนั้นไม่ใช่ศูนย์ถึง N! รายการ.
  4. Clip[]ทำหน้าที่เหมือนSign[]เปลี่ยนรายการจาก (-inf, inf) เป็น [-1, 1]
  5. Tr@Absจะเปิดทั้งหมด-1ลงไป1และตอนนี้ยังไม่มีรายชื่อมีความยาวมีเพียง0(ไม่ถูกต้อง) และ1(ที่ถูกต้อง) ดังนั้นเราจึงสรุปรายการ

4
คุณสามารถบันทึก 4 Permutations@#~Count~Except@{___,x_,x_,___}&ไบต์กับบางจับคู่รูปแบบ:
ไม่ใช่ต้นไม้

2
ฉันมีอีกอัน: Count[Split/@Permutations@#,{{_}..}]&, 37 ไบต์!
ไม่ใช่ต้นไม้

7

เยลลี่ขนาด 7 ไบต์

Œ!QIẠ€S

ลองออนไลน์!

จะเข้าเป็นเช่นสำหรับ[1,1,1,1,2,2,2] [4,3]ตู้ทดสอบ[8,3,2]ใช้เวลานานเกินไปในการทำงานกับ TIO

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

Œ!QIẠ€S - main link, input as a list
Œ!      - all permutations
  Q     - remove duplicates
   I    - take increments (returns a 0 for two adjacent identical numbers)
    Ạ€  - apply “all” atom to each: 0 for containing 0 and 1 otherwise
      S - sum

คุณใช้ช่วงเวลาผ่อนผัน ... ;)
Erik the Outgolfer

ไม่Œ!QIẠ€Sทำงานหรือไม่ ลองออนไลน์!
nmjcman101

@ nmjcman101 ดูเหมือนว่าจะทำงาน ยินดีที่ได้พบ! ฉันชอบPอะตอมที่มีค่ามากกว่าและทุกอย่างเพื่อความเรียบง่าย
fireflame241

@ fireflame241 โดยทางเทคนิคแล้วนั่นไม่ใช่อะตอมทุกตัวมันคือทุกอะตอม
Erik the Outgolfer

BTW P€แทนที่จะẠ€ยังคงใช้งานได้
Erik the Outgolfer


5

Mathematica ขนาด 50 ไบต์

Expand[1##&@@(LaguerreL[#,-1,x](-1)^#)]/._^i_:>i!&

ลองใช้ในวิชาคณิตศาสตร์หรือที่กล่องทราย Wolfram !

ใช้อินพุตเหมือนในกรณีทดสอบ - เช่น{4,3}หมายถึง "4 แถบสีแดง, 3 แถบสีเหลือง"

นี่คือการดำเนินงานที่ไร้เดียงสาของสูตรผมพบว่าที่นี่ "Naïve" หมายถึง "ฉันไม่รู้ว่าคณิตศาสตร์ทำงานอย่างไรดังนั้นโปรดอย่าขอคำอธิบาย ... "


1
เราสามารถอธิบายคำตอบของคณิตศาสตร์ได้ไหม?
TheLethalCoder

@TheLethalCoder Seconded มีใครช่วยอธิบายคณิตศาสตร์ให้ฉันหน่อยได้ไหม?
ไม่ใช่ต้นไม้


3

Ruby 2.4, 47 ไบต์

ป้อนข้อมูลคือรายการของตัวอักษร: สำหรับกรณีทดสอบ[4,3]การป้อนข้อมูลสามารถ%w[a a a a b b b], "1111222".charsหรือบางวิธีการจัดรูปแบบอาร์เรย์อื่น ๆ ที่ถูกต้องในรูบี

->x{x.permutation.uniq.count{|a|a*''!~/(.)\1/}}

ต้องการ 2.4 สำหรับEnumerator#uniq(เวอร์ชันก่อนหน้านี้มีเฉพาะในArrayคลาสเท่านั้น) ดังนั้นลิงก์ TIO จะเพิ่ม 5 ไบต์เพื่อแปลงตัวเรียงลำดับการเปลี่ยนรูปเป็นอาร์เรย์ก่อนผ่านto_aเนื่องจากไม่มีฟังก์ชันข้างต้น

ลองออนไลน์!


3

R, 72 ไบต์

pryr::f(sum(sapply(unique(combinat::permn(x)),pryr::f(!sum(!diff(x))))))

สร้างฟังก์ชั่น

function (x) 
{
    sum(sapply(unique(combinat::permn(x)), pryr::f(!sum(!diff(x)))))
}

รับอินพุตในแบบฟอร์ม[1,1,1,1,2,2,2]ตามความคิดเห็นของ Erik the Outgolfer การใช้งานcombinatของpermnฟังก์ชั่นในการสร้างรายการของพีชคณิตทั้งหมดและจากนั้นuniqueจะได้รับรายการที่แตกต่างกันทั้งหมด sapplyจากนั้นใช้ฟังก์ชันต่อไปนี้กับรายการทั้งหมด:

pryr::f(!sum(!diff(x)))

ซึ่งประเมินว่า

function (x) 
!sum(!diff(x))

โปรดทราบว่านี่xไม่ใช่สิ่งเดียวกับxในอินพุตของฟังก์ชั่นใหญ่ การใช้ตัวละครอื่นในฟังก์ชั่นนี้จะหลอกpryr::fให้เชื่อว่าฟังก์ชั่นใหญ่นั้นต้องการอาร์กิวเมนต์อีกตัว

2 1 3 4 2 1 -> -1 2 1 -2 -1ยังไงก็ตามเมื่อได้รับการเปลี่ยนแปลงที่ฟังก์ชั่นนี้จะใช้เวลาแตกต่างระหว่างเวกเตอร์: !แปลงภัณฑ์เข้าไปFALSEและศูนย์ลงไปดังนั้นเวกเตอร์จะกลายเป็นTRUE FALSE FALSE FALSE FALSE FALSEรวมว่าเพื่อตรวจสอบว่ามีใด ๆTRUE( TRUEจะหมายถึงdiff=0-> สองหมายเลขติดต่อกัน) เราสามารถกลับด้านนี้อีกครั้ง!เพื่อรับบูลีนว่ามีค่าติดต่อกันในการเปลี่ยนแปลงหรือไม่

ข้อสรุปเกี่ยวกับบูลีนเหล่านี้ทำให้เรามีจำนวนทั้งหมดของการเปลี่ยนลำดับที่นี่ไม่ใช่กรณี

ใช้งานไม่ได้กับ[8,3,2]testcase เพราะต้องใช้เวกเตอร์ขนาด 46GB ในการจัดเก็บการเรียงสับเปลี่ยน




2

Husk , 8 ไบต์

#ȯ¬ṁtguP

ลองออนไลน์! จะเข้าในรูปแบบสำหรับ"aaabb" [3,2]หมดเวลากับกรณีทดสอบที่ยาวที่สุด

คำอธิบาย

ไม่มีอะไรแฟนซีที่นี่เพียงแค่นับพีชคณิตที่ไม่เหมือนใครโดยที่ทุกกลุ่มขององค์ประกอบที่อยู่ติดกันมีความยาว 1

#ȯ¬ṁtguP
       P  Permutations.
      u   Remove duplicates.
#ȯ        Count how many satisfy the following condition:
     g    group adjacent elements,
   ṁt     concatenate tails of groups
  ¬       and negate.

2

Ruby, 84 76 ไบต์

f=->a,x=p{i=s=0;a.map{a[i-=1]-=1;a[i]<0||i!=x&&s+=f[a,i];a[i]+=1}.max>0?s:1}

ฟังก์ชั่นแลมบ์ซ้ำแบบเรียกซ้ำได้ ดูแต่ละสีที่เป็นไปได้และเพิ่มปริมาณการค้นหาต้นไม้แบบเรียกซ้ำโดยนับจำนวนครั้งที่ใช้แถบสีทั้งหมด

คำอธิบาย (สำหรับเวอร์ชั่นเก่า):

f=->
  a, # a is the input array in [3,3,4] form
  x = -1 # x is the last color placed (-1 when run normaly, used in recursive calls)
{
  j = i = s = 0;
  # i is the index
  # s is the sum of valid final patterns (the answer)
  # j is used to count the total stripes

  a.map{|e| # Iterate over array of colors

    a[i] -= 1; # remove a stripe of current color (the array will be used in recursive call)

    s += f[a,i] if i!=x && e>0;
      # add to sum recursively if:
        # we are not using the same color as the last color AND
        # we have stripes of the current color left to paint

    a[i] += 1; # replace the stripe we removed above 

    j += a[i]; # add stripes to j

    i+=1 # increment the index

  }; # End loop

  j == 0 ? 1 : s
  # if we had stripes, give the recursive sum, otherwise return 1 
}

x=pเป็นเงื่อนไขเริ่มต้น? pทำหน้าที่เป็นนามแฝงของnilในกรณีนี้และควรเป็นไปตามเช็คที่ใช้
หมึกมูลค่า

1

MATL , 11 8 ไบต์

Y@Xu!dAs

รูปแบบอินพุต[1 1 1 1 2 2 2]สำหรับ[4 3]เป็นต้น

หน่วยความจำหมดสำหรับกรณีทดสอบครั้งสุดท้าย

ลองออนไลน์!

คำอธิบาย

Y@    % Implicit input. Matrix of all permutations. Each row is a permutation
Xu    % Unique rows
!     % Transpose
d     % Consecutive differences along each column
A     % All: true for columns such that all its entries are nonzero
s     % Sum. Implicitly display
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.