การนับ polystrips


18

Polystrips เป็นส่วนย่อยของ polyominoes ที่สอดคล้องกับกฎต่อไปนี้:

  • แต่ละชิ้นประกอบด้วยเซลล์อย่างน้อย 1 เซลล์
  • ไม่มีเซลล์ใดสามารถมีมากกว่าสองเพื่อนบ้าน
  • เซลล์ไม่ควรปิดรู

โพลีโม่โนอิสระจะแตกต่างกันเมื่อไม่มีการเปลี่ยนแปลงอย่างเข้มงวด (การแปล, การหมุน, การสะท้อนหรือการสะท้อนแบบร่อน) ของอีกชิ้นหนึ่ง (ชิ้นที่สามารถหยิบขึ้นมาและพลิกได้) การแปลการหมุนการสะท้อนหรือการร่อนสะท้อนให้เห็นถึงโพลีโนมิโนฟรีนั้นไม่ทำให้รูปร่างของมันเปลี่ยนไป ( Wikipedia )

ตัวอย่างเช่นมี heptastrips ฟรี 30 (polystrips ที่มีความยาว 7) นี่คือทั้งหมดของพวกเขาบรรจุในตาราง 14x15

Heptastrips

เครดิตรูปภาพ: Miroslav Vicher

เป้าหมาย

เขียนโปรแกรม / ฟังก์ชั่นที่รับจำนวนเต็มบวกnเป็นอินพุตและแจกแจงn-polystrips อิสระที่แตกต่างกัน

  • n = 1 -> 1 (สี่เหลี่ยมจัตุรัสเดียว)

  • n = 2 -> 1 (มีเพียง 2 โพลสต็อกที่เป็นไปได้ที่ทำจาก 2 สแควร์ส)

  • n = 3 -> 2 (อันที่หนึ่งประกอบด้วย 3 กำลังสองรวมกันในหนึ่งบรรทัดและอีกอันหนึ่งเป็นรูปตัว L)

  • n = 4 -> 3 (หนึ่งเส้นตรงหนึ่งรูปตัว L และรูปตัว Z หนึ่งรูป)

  • . . .

กรณีทดสอบ:

n   polystrips

1   1
2   1
3   2
4   3
5   7
6   13
7   30
8   64
9   150
10  338
11  794
12  1836
13  4313
14  10067
15  23621

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

นี่คือดังนั้นรหัสที่สั้นกว่าดีกว่า ฉันขอขอบคุณคำอธิบายรายละเอียดของอัลกอริทึมและรหัสอย่างละเอียด

การใช้การอ้างอิงบางส่วนในJ

ฉันตัดสินใจที่จะอธิบายแต่ละชิ้นในรูปแบบ "เวกเตอร์" และฉันต้องการเพียงแค่บล็อก n-2 เพื่ออธิบายชิ้นส่วนของ n-polystrip (มีเพียง 1 2-polystrip และมันกลับมาอย่างชัดเจน) บล็อกอธิบายทิศทางที่เกี่ยวข้อง: 0 - ไม่มีการเปลี่ยนแปลง 1 - เลี้ยวซ้าย 2 - เลี้ยวขวา ไม่สำคัญว่าทิศทางใดที่จะเริ่มต้น แต่เพียงเพื่อระบุว่าจะวางเซลล์ถัดไปที่ใด สามารถมีจำนวน 0 ใด ๆ ที่ต่อเนื่องกันได้ แต่ 1s และ 2s จะเป็นแบบเดี่ยวเสมอ การใช้งานนี้เป็นบางส่วนเนื่องจากไม่ได้คำนึงถึงรู - โซลูชันสำหรับ n> 6 นับชิ้นด้วยรู

ลองออนไลน์!


1
OEIS ที่เกี่ยวข้อง (แต่ไม่รวมถึงหลุม)
Martin Ender

@ Martin Ender ขอบคุณฉันไม่รู้
Galen Ivanov

2
เพื่อให้แน่ใจว่าฉันคิดว่าถ้าคุณกรอกตาราง 3x3 ยกเว้นตรงกลางและอีกมุมหนึ่งที่นับเป็นรู ( 101010ในรูปตัวอย่างของคุณ)?
Ton Hospel

@Ton Hospel ใช่แน่นอน - นี่เป็นชิ้นส่วนเฮปเพสท์เดียวที่มีรู
Galen Ivanov

1
อาจเป็นคำถามที่ดีสำหรับคณิตศาสตร์ SE
Jonah

คำตอบ:


12

Python 3 , 480 433 406 364 309 299 295 ไบต์

ดูเหมือนว่าเป็นจุดที่ดีในการเริ่มต้นอาชีพ PPCG ของฉัน (หรือไม่?)

def C(s):
 S,*a={''},0,1;n=d=r=1
 for c in s:d=c*d*1jor d;n+=d;a+=n,;r*=not{n}&S;x,*a=a;S|={x+t+u*1jfor t in A for u in A}
 return r
from itertools import*;A=-1,0,1;n,y=int(input())-2,0;x={*filter(C,product(*[A]*n))}
while x:s=x.pop();S=*(-u for u in s),;x-={s[::-1],S,S[::-1]}-{s};y+=1
print(y)

ลองออนไลน์!

การแก้ไข:

  • Inline Dand Xและ tweaked เล็กน้อยในบางจุดที่เล่นกอล์ฟ
  • ใช้เทคนิคมากขึ้นส่วนใหญ่เกี่ยวข้องกับชุด
  • mการเปลี่ยนแปลงในรูปแบบของโปรแกรมและเปลี่ยนไปใช้ตัวเลขที่ซับซ้อนแทนจำนวนข้อ (ตัวเลขที่ซับซ้อนนั้นเป็นคุณสมบัติที่แข็งแกร่ง แต่มักเพิกเฉยต่อการเล่นกอล์ฟปรับจากโซลูชันของ xnor สำหรับความท้าทายอื่น )
  • เปลี่ยนการLFRแทนค่าสตริงเป็น-1,0,1ทูเปิลและเวลาดำเนินการเพื่อลดจำนวนไบต์ที่ลดลง (!) ตอนนี้วิธีการแก้ปัญหานั้นถูกต้องตามทฤษฎี แต่หมดเวลาก่อนที่จะส่งออกผลลัพธ์สำหรับ 15
  • หนึ่งเรียงรายขอบคุณวงโจนาธาน Frech rแล้วผมพบว่าเป็นทางเลือกที่ดีมากสำหรับการคำนวณ ในที่สุดภายใต้ 300 ไบต์ !!!
  • น่าแปลกที่1jสามารถยึดติดกับสิ่งอื่นโดยไม่ทำให้ parser (-2B) สับสนและnotมีลำดับความสำคัญต่ำ (-2B) อย่างบ้าคลั่ง

รุ่นที่ล้าสมัย (480 ไบต์):

def C(s):
 m=999;a=[0,1];n=d=1
 D={'F':{},'L':{1:m,m:-1,-1:-m,-m:1},'R':{1:-m,-m:-1,-1:m,m:1}}
 X=lambda x:{x+~m,x-m,x-m+1,x-1,x,x+1,x+m-1,x+m,x-~m}
 for c in s:
  d=D[c].get(d,d);n+=d;a+=n,
  if n in set().union(*map(X,a[:-3])):return 0
 return 1
def f(n):
 if n<3:return 1
 x={*'LF'}
 for _ in range(3,n):x={s+c for s in x for c in({*'LRF'}-{s[-1]})|{'F'}}
 y={*x}
 for s in x:
  if s in y:S=s.translate(str.maketrans('LR','RL'));y-={s[::-1],S,S[::-1]}-{s}
 return sum(map(C,y))

ลองออนไลน์!

วิธีการแก้ปัญหาที่ไม่ดีพร้อมความคิดเห็น:

t = str.maketrans('LR','RL')

# hole checking function
def check(s):
    m = 999   # (imaginary) board size enough to fit all generated polyominoes
    a = [0,1] # previous path
    n = 1     # current cell
    d = 1     # current direction
    # dict for direction change
    D = {'F':{}, 'L':{1:m, m:-1, -1:-m, -m:1}, 'R':{1:-m, -m:-1, -1:m, m:1}}
    # used to 'blur' all cells in path into 3x3
    X = lambda x: {x-m-1,x-m,x-m+1,x-1,x,x+1,x+m-1,x+m,x+m+1}
    for c in s:
        d = D[c].get(d,d) # change direction
        n += d            # move current cell
        # the polyomino has a hole if the current cell touches previous cells (including diagonally; thus the blurring function)
        if n in set().union(*map(X,a[:-2])): return False
        a.append(n)       # add current cell to the path
    return True

# main function
def f(n):
    if n < 3: return 1
    x = {*'LF'}
    # generate all polystrips using the notation similar to the reference
    for _ in range(3, n): x = {s+c for s in x for c in ({*'LRF'}-{s[-1]})|{'F'}}
    y = {*x}
    # remove duplicates (mirror, head-to-tail, mirror of head-to-tail) but retain self
    for s in x:
        if s in y:
            S = s.translate(t)
            y -= {s[::-1], S, S[::-1]} - {s}
    # finally filter out holey ones
    return sum(map(check,y))

ลองออนไลน์!

m = 999ถูกเลือกเพราะใช้เวลาในการชี้แจงทุกอย่างและใช้เวลาในการคำนวณประมาณ 8 n = 1..15วินาที อาจเป็นการดีถ้าคุณจะบันทึก 1 ไบต์โดยใช้ 99 แทน เราไม่ต้องการสิ่งนี้อีกต่อไปและตอนนี้ก็รับประกันว่าจะถูกต้องสำหรับขนาดอินพุตที่กำหนดเองด้วยจำนวนที่ซับซ้อนในตัว


5
ยินดีต้อนรับสู่ PPCG! วิธีที่น่าประทับใจในการเริ่มต้นอาชีพ PPCG ของคุณอย่างแน่นอน :)
Martin Ender

3
ยินดีต้อนรับสู่ PPCG และขอขอบคุณสำหรับการแก้ปัญหานี้! ฉันได้รับแล้วขึ้นคาดว่าจะเห็นการแก้ปัญหา :)
เลน Ivanov

3
ดูเหมือนจะเป็นจุดที่ดีที่จะเริ่มต้นอาชีพ PPCG ของฉัน(หรือไม่?) นี่เป็นคำตอบสั้น ๆ ที่น่าประหลาดใจสำหรับพวกเราส่วนใหญ่ที่ไม่คิดว่าจะเป็นไปได้แม้กระทั่งเวอร์ชั่นที่ดูไม่น่าตื่นเต้นก็ดูเรียบง่ายอย่างน่าประหลาดใจ แต่ใช่มั้ยนี่อาจเป็นวิธีเฉลี่ยในการเริ่มอาชีพ PPCG ใช่ไหม? :)
Erik the Outgolfer

1
@Erik บรรทัดนั้นเป็นเรื่องตลกไปครึ่งหนึ่ง :) แต่ใช่แล้วคำตอบก็น่าประหลาดใจสำหรับฉัน - ฉันไม่เคยคาดหวังว่าจะถอนตัวออกจากการส่งต้นฉบับ ~ 36%
Bubbler


4

APL (Dyalog Unicode) , 70 65 ไบต์

+/{∧/2≤|(⊢-¯3↓¨,\)+\0 1\0j1*⍵}¨∪{(⊃∘⍋⊃⊢)(⊢,⌽¨)⍵(-⍵)}¨2-,⍳2↓⎕⍴3

ลองออนไลน์!

โค้ดเวอร์ชันเต็มของโปรแกรมด้านล่างต้องขอบคุณAdám


APL (Dyalog Unicode) , 70 ไบต์

{+/{∧/2≤|(⊢-¯3↓¨,\)+\0 1\0j1*⍵}¨∪{(⊃∘⍋⊃⊢)(⊢,⌽¨)⍵(-⍵)}¨2-,⍳3⍴⍨0⌈⍵-2}

ลองออนไลน์!

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

รหัสข้างต้นเทียบเท่ากับคำจำกัดความต่อไปนี้:

gen←{2-,⍳3⍴⍨0⌈⍵-2}
canonicalize←{(⊃∘⍋⊃⊢)(⊢,⌽¨)⍵(-⍵)}
test←{(∧/⊢{∧/2≤|⍺-¯3↓⍵}¨,\)+\0 1\0j1*⍵}
{+/test¨∪canonicalize¨gen⍵}

สิ่งนี้ใช้งานได้เหมือนโซลูชัน Python แต่เป็นไปตามลำดับอื่น มันgenerates LFR-strips ของความยาวn-2, canonicalizes แถบแต่ละใช้แถบ nique, tests แถบแต่ละถ้ามันสัมผัสตัวเอง (1 หากไม่ได้สัมผัส, 0 อื่น ๆ ) และสรุป+/ผลการบูลีน

gen

{2-,⍳3⍴⍨0⌈⍵-2}
{            }   ⍵←input number n
        0⌈⍵-2    xmax(0, n-2)
     3⍴⍨         x copies of 3
   ,⍳            multi-dimensional indexes; x-th cartesian power of [1,2,3]
                 (`⍳` gives x-dimensional hypercube; `,` flattens it)
 2-              compute 2-k for each k in the array

 in each strip, ¯1, 0, 1 corresponds to R, F, L respectively

canonicalize

{(⊃∘⍋⊃⊢)(⊢,⌽¨)⍵(-⍵)}
{                  }   ⍵←single strip
              ⍵(-⍵)    nested array of  and its LR-flip
        (⊢,⌽¨)         concatenate their head-to-tail flips to the above
 (⊃∘⍋  )               find the index of the lexicographically smallest item
     ⊃⊢                take that item

test

{(∧/⊢{∧/2≤|⍺-¯3↓⍵}¨,\)+\0 1\0j1*⍵}
{                                  }   ⍵←single strip
                              0j1*⍵    power of i; direction changes
                            ×\         cumulative product; directions
                        0 1,     initial position(0) and direction(1)
                      +\         cumulative sum; tile locations
 (  ⊢{           }¨,\)    test with current tile(⍺) and all tiles up to ⍺(⍵):
             ¯3↓⍵         x←⍵ with last 3 tiles removed
           ⍺-             relative position of each tile of x from 
        2≤|               test if each tile of x is at least 2 units away
      ∧/                  all(...for each tile in x)
  ∧/         all(...for each position in the strip)

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