ফ্রি এন-পলিওমিনোস সহ একটি এন এক্স এন স্কোয়ারের স্বতন্ত্র টিলিংয়ের সংখ্যা


17

নতুন "চমৎকার" OEIS ক্রম, A328020 , শুধু একটি মাত্র কয়েক মিনিট আগে প্রকাশিত হয়েছিল।

ফ্রি এন-পলিওমিনোস সহ একটি এন এক্স এন স্কোয়ারের স্বতন্ত্র টিলিংয়ের সংখ্যা।

এই ক্রমটি বর্গক্ষেত্রের প্রতিসাম্য পর্যন্ত tilings গণনা করে। ক্রমটির ছয়টি পদ রয়েছে তবে আমি দেখতে চাই যে এখানে লোকেরা আরও বাড়িয়ে দিতে পারে।

উদাহরণ

জন্য n=4সেখানে 22 ধরনের গ্রিডের, যেমন OEIS থেকে এই ছবিতে দেখানো হয়। ক্রেডিট: জেফ বোভারমাস্টার, এ 328020 এর চিত্র (4)।A328020 (4)

চ্যালেঞ্জ

পূর্ববর্তী চ্যালেঞ্জের মতো, এই চ্যালেঞ্জের লক্ষ্যটি এই ক্রমটিতে যতগুলি সম্ভব শর্তাদি গণনা করা শুরু হয়, যা শুরু হয়1, 1, 2, 22, 515, 56734 এবং যেখানে এন-থিম শব্দটি এন-পলিমিনয়েসযুক্ত এন এক্স এন গ্রিডের সংখ্যার সংখ্যা।

আপনি যতক্ষণ চান আপনার কোড চালান। এই চ্যালেঞ্জটির বিজয়ী হবেন এমন ব্যবহারকারী যা তাদের কোড তৈরি করার সাথে সাথে ক্রমটির সর্বাধিক শর্তাদি পোস্ট করে। যদি দু'জন ব্যবহারকারী একই সংখ্যক শর্তাদি পোস্ট করেন, তবে যিনি তাদের সর্বশেষতম মেয়াদটি জয়লাভ করেন।


3
তাহলে এই বর্গাকার মডুলো প্রতিসাম্য?
পিটার টেলর

@ পিটারটেলর, ঠিক আছে আমি প্রশ্নে এটি disambiguated করেছি।
পিটার কেজি

নিখরচায় আমি বলব যে n'th এন্ট্রি গণনা করতে সংখ্যা_ফ_ফিক্সড_ন_পোলিওমিনোস n ( n -1) অপারেশন নেবে । সুতরাং এন = 7 এর জন্য এটি 760 ^ 6 ≈ 2 ^ 57.4 অপারেশন নিতে পারে। আপনি সম্ভবত এটি অনেকটা কেটে ফেলতে পারেন তবে এটি শুরু করার জন্য এটি একটি বড় সংখ্যা ...
জি স্লিপেন

স্লিপেন, আমি আশা করি আপনি ব্যাকট্র্যাকিংয়ের মাধ্যমে আপনি এটিকে অনেকটা কমাতে পারবেন। বিশেষত, অনেকগুলি স্থির বহুপদী রয়েছে যা কোণে স্থাপন করা যায় না এবং একবার কোনও বৈধ পলিমিনো কোথাও স্থাপন করা হলে এটি তার পাশের অংশগুলি কীভাবে স্থাপন করা যায় তা সীমাবদ্ধ করে দেয়।
পিটার কেজি

@ পিটারকাগেই, আপনি ঠিক বলেছেন আমার ধারণা এটির সাহায্য করে যদি আপনি ইতিমধ্যে এম এন-পলিমিনোজ রেখেছেন, আপনি পলিওমিনোকে সবচেয়ে খারাপ অবস্থানে রাখার চেষ্টা করার জন্য পরবর্তী অবস্থানটি বেছে নেন, আপনি এটি অনেকটা কেটে ফেলতে পারেন।
জি স্লিপেন

উত্তর:


9

@ গ্রিমির কোডে এক্সটেনশানটি এন = 8 পেয়ে যায়

এটি কেবলমাত্র আন্ডারলাইন করে যে @ গ্রিমি অনুগ্রহের দাবিদার:

প্রত্যেকটি সমাপ্ত পলিওমিনো পরে, পরীক্ষার কোডটি প্রসারিত করে আমি অনুসন্ধান গাছকে ছাঁটাই করতে পারি, বাকি মুক্ত স্থানটি এন দ্বারা বিভাজ্য নয় এমন আকারের অংশগুলিতে বিভক্ত হয় না that

এমন কোনও মেশিনে যেখানে মূল কোডটি এন = 7 এর জন্য 2 মি 11 সেকেন্ড নিয়েছিল, এটি 1 এম 4 লাগে এবং এন = 8 গণনা করা হয়েছিল 33 হ 46 মি। ফলাফল 23437350133।

এখানে ভিন্ন হিসাবে আমার সংযোজন:

--- tilepoly.c  2019-10-11 12:37:49.676351878 +0200
+++ tilepolyprune.c     2019-10-13 04:28:30.518736188 +0200
@@ -51,6 +51,30 @@
     return 1;
 } 

+static int check_component_sizes(u64 occupied, u64 total){
+    u64 queue[N*N];
+    while (total<N*N){
+        u64 count = 1;
+        u64 start = ctz(~occupied);
+        queue[0] = start;
+        occupied |= 1ul << start;
+        for(u64 current=0; current<count; ++current){
+            u64 free_adjacent = adjacency_matrix[queue[current]] & ~occupied;
+            occupied |= free_adjacent;
+            while (free_adjacent){
+                u64 next = ctz(free_adjacent);
+                free_adjacent &= ~(1ul << next);
+                queue[count++] = next;
+            }
+        }
+        if (count % N){
+            return 0;
+        }
+        total += count;
+    }
+    return 1;
+}
+
 static void recurse(u64 mino, u64 cell, u64 occupied, u64 adjacent, u64 forbidden)
 {
     if (cell >= N) {
@@ -61,6 +85,9 @@
             return;
         }

+        if(!check_component_sizes(occupied,N*mino))
+            return;
+
         u64 next = ctz(~occupied);
         board[next] = mino;
         recurse(mino, 1, occupied | 1ul << next, adjacency_matrix[next], 0);

এটি অনলাইন চেষ্টা করুন!


ইহা খুব সুন্দর.
আনুশ

আমাদের এখন যা দরকার তা হ'ল একটি বহুবিশ্লেষিত সিমড সংস্করণ :)
আনুশ

1
ওহ আসলেই দুর্দান্ত! আমি আসলে এই অপ্টিমাইজেশনটি বিবেচনা করেছি, তবে ভাবি নি যে এটি একটি যুক্তিসঙ্গত সময়ে এন = 8 এ পৌঁছানোর পক্ষে যথেষ্ট হবে, তাই আমি এটি বাস্তবায়নে বিরক্ত করিনি।
গ্রিমি 21

14

সি, 7 পদ

সপ্তম পদটি 19846102 । (প্রথম ছয়টি হ'ল 1, 1, 2, 22, 515, 56734, প্রশ্নে বর্ণিত হিসাবে)।

#include <stdio.h>
#include <string.h>
#include <stdint.h>

#define N 7
#define ctz __builtin_ctzl

typedef uint64_t u64;

static u64 board[N*N] = { 0 };
static u64 adjacency_matrix[N*N] = { 0 };
static u64 count = 0;

static u64 check_symmetry()
{
    static const u64 symmetries[7][3] = {
        { 0,     +N, +1 },
        { N-1,   -1, +N },
        { N-1,   +N, -1 },
        { N*N-1, -1, -N },
        { N*N-1, -N, -1 },
        { N*N-N, +1, -N },
        { N*N-N, -N, +1 },
    };

    int order[N];

    for (u64 i = 0; i < 7; ++i) {
        u64 start = symmetries[i][0];
        u64 dcol = symmetries[i][1];
        u64 drow = symmetries[i][2];
        memset(order, 0xFF, N*sizeof(int));

        for (u64 row = 0, col = 0; col < N || (col = 0, ++row < N); ++col) {
            u64 base = board[col + N*row];
            u64 symmetry = board[start + dcol*col + drow*row];
            u64 lex = 0;

            while (order[lex] != symmetry && order[lex] != -1)
                ++lex;
            order[lex] = symmetry;

            if (lex < base)
                return 0;

            if (base < lex)
                break;
        }
    }

    return 1;
} 

static void recurse(u64 mino, u64 cell, u64 occupied, u64 adjacent, u64 forbidden)
{
    if (cell >= N) {
        ++mino;

        if (mino == N) {
            count += check_symmetry();
            return;
        }

        u64 next = ctz(~occupied);
        board[next] = mino;
        recurse(mino, 1, occupied | 1ul << next, adjacency_matrix[next], 0);
        return;
    }

    adjacent &= ~occupied & ~forbidden;
    while (adjacent) {
        u64 next = ctz(adjacent);
        adjacent &= ~(1ul << next);
        forbidden |= 1ul << next;
        board[next] = mino;
        recurse(mino, cell + 1, occupied | 1ul << next, adjacent | adjacency_matrix[next], forbidden);
    }
}

int main(void)
{
    for (u64 i = 0; i < N*N; ++i) {
        if (i % N)
            adjacency_matrix[i] |= 1ul << (i - 1);
        if (i / N)
            adjacency_matrix[i] |= 1ul << (i - N);
        if (i % N != N - 1)
            adjacency_matrix[i] |= 1ul << (i + 1);
        if (i / N != N - 1)
            adjacency_matrix[i] |= 1ul << (i + N);
    }

    recurse(0, 2, 3, 4 | 3 << N, 0);
    printf("%ld\n", count);
}

এটি অনলাইন চেষ্টা করুন!(এন = for এর জন্য, যেহেতু এন = time এর সময় শেষ হয়ে যাবে))

আমার মেশিনে, এন = 6 0.171 সেকেন্ড নিয়েছে, এবং এন = 7 2 মি 23 সেকেন্ড নিয়েছে। এন = 8 কয়েক সপ্তাহ লাগবে।


3
এটা চমৎকার! আপনি যদি ওইআইএস-তে এটি যুক্ত করতে চান তবে আমাকে জানাতে — যার ফলস্বরূপ আপনি নিজেরাই ডক্সিং করতে পারেন in বা আপনি যদি আমাকে এটি যুক্ত করতে চান।
পিটার কেজি

@ পিটারকাগি দয়া করে এটি যোগ করতে নির্দ্বিধায় অনুগ্রহ করে (:
গ্রিমি

চিত্তাকর্ষক চেক_স্মেত্রী ফাংশন। আমি এই পদ্ধতির সাথে পরিচিত না হওয়ায় আপনি কি একটি সংক্ষিপ্ত ব্যাখ্যা দিতে পারেন?
জন রিস

1
@ জনআরিজ এটি সহজভাবে পরীক্ষা করে যে বর্তমান বোর্ডটি অভিধানিকভাবে its এর সমস্ত প্রতিসাম্যগুলিতে। এইভাবে প্রতিসম বোর্ডের যে কোনও সেটগুলিতে ঠিক একটি গণনা করা হয়: অভিধানিক ন্যূনতম।
গ্রিমি

একের পর এক সমাধান গণনার চেয়ে আরও ভাল করার জন্য, মাঝারিটির মধ্যে এক ধরণের মিলন প্রয়োজন। সমস্যাটি হ'ল মনে হচ্ছে এমন কিছু বিভক্ত করার কোনও উপায় নেই যা উল্লেখযোগ্য ক্লাস্টারিং পায়। উদাহরণস্বরূপ, এই উত্তর হিসাবে একই ক্যানোনিকাল ক্রম ব্যবহার করে 3 টি হেক্সোমিনোস রেখে আমি প্রতি মুখোশের প্রতি হেক্সমিনোসের গড় প্রায় 3.7 সেট পাই। আমি এই সিদ্ধান্তে মারধর করার সম্ভাবনা নেই বলে উপসংহারে পৌঁছেছি।
পিটার টেলর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.