ম্যাট্রিক্স সম্পত্তি এক্স পুনর্বিবেচনা (বা এক্স এর জয়)


11

এই চ্যালেঞ্জটি আংশিকভাবে একটি অ্যালগরিদম চ্যালেঞ্জ, আংশিকভাবে একটি অপ্টিমাইজেশন চ্যালেঞ্জ এবং আংশিকভাবে কেবল একটি দ্রুততম কোড চ্যালেঞ্জ।

এটি ম্যাট্রিক্স সম্পূর্ণরূপে তার প্রথম সারি rএবং প্রথম কলাম দ্বারা নির্দিষ্ট করা হয়েছে c। ম্যাট্রিক্সের প্রতিটি অবশিষ্ট উপাদানটি ত্রিভুজভাবে উপরে এবং বামে থাকা উপাদানটির একটি অনুলিপি। যে M[i,j] = M[i-1,j-1]। আমরা টি ম্যাট্রিককে অনুমতি দেব যা বর্গক্ষেত্র নয়। তবে আমরা সবসময় ধরে নিই যে সারিগুলির সংখ্যা কলামের সংখ্যার চেয়ে বেশি নয়। উদাহরণস্বরূপ, নিম্নলিখিত 3 দ্বারা 5 টি ম্যাট্রিক্স বিবেচনা করুন।

10111
11011
11101

আমরা বলি যে একটি ম্যাট্রিক্সের প্রপার্টি এক্স রয়েছে যদি এটিতে অ-অভিন্ন পরিচয় সূচকযুক্ত কলামগুলির দুটি খালি খালি সেট থাকে যা একই (ভেক্টর) যোগফল। এক বা একাধিক কলামের ভেক্টর যোগফলটি তাদের কলামগুলির কেবলমাত্র উপাদান-ভিত্তিক সংমিশ্রণ। এটি উপাদানযুক্ত দুটি বা ততোধিক কলামগুলির যোগফল এবং এর মধ্যে xপ্রতিটি উপাদান রয়েছে এমন আরও একটি কলাম x। একটি কলামের যোগফল তুচ্ছভাবে কলাম নিজেই।

উপরের ম্যাট্রিক্সটি তুচ্ছভাবে X এর সম্পত্তি হিসাবে প্রথম এবং শেষের কলামগুলি একই। পরিচয় ম্যাট্রিক্সে কখনই এক্স সম্পত্তি থাকে না।

যদি আমরা কেবল উপরের ম্যাট্রিক্সের শেষ কলামটি সরিয়ে ফেলি তবে আমরা এমন একটি উদাহরণ পাই যাতে প্রপার্টি এক্স নেই এবং 4/3 এর স্কোর দেয়।

1011
1101
1110

কাজটি

কাজের বাইনারি এন্ট্রি সর্বোচ্চ স্কোরিং টি ম্যাট্রিক্স এটি লেখার কোডে আর কোনটা নয় স্পষ্টতার জন্য সম্পত্তি এক্স আছে, বাইনারি এন্ট্রিগুলির সাথে একটি ম্যাট্রিক্স সম্পত্তি যে তার এন্ট্রির প্রতিটি এক হয় 0 বা 1 আছে।

স্কোর

আপনার স্কোরটি আপনার সেরা স্কোরিং ম্যাট্রিক্সের সারিগুলির সংখ্যা দ্বারা বিভক্ত সংখ্যা কলামগুলি হবে।

টাইব্রেকার

দুটি উত্তরের যদি একই স্কোর থাকে তবে একটি জমা দেয় প্রথমে।

(অত্যন্ত) অসম্ভব ইভেন্টে যে কেউ সীমাহীন স্কোর পাওয়ার জন্য কোনও পদ্ধতি আবিষ্কার করে, এই জাতীয় সমাধানের প্রথম বৈধ প্রমাণ গ্রহণ করা হবে। এর চেয়েও বেশি সম্ভাবনাময় ইভেন্টে আপনি একটি সীমাবদ্ধ ম্যাট্রিক্সের অনুকূলতার প্রমাণ খুঁজে পেতে পারেন অবশ্যই আমি জয়ের পুরস্কারও দেব।

ইঙ্গিত

সম্পত্তি X ছাড়াই সর্বাধিক স্কোরিং ম্যাট্রিক্সের উত্তরগুলি এখানে বৈধ তবে তারা অনুকূল নয়। প্রোটি এক্স ছাড়া টি ম্যাট্রিক রয়েছে যা চক্র নয়।

উদাহরণস্বরূপ, সম্পত্তি X ব্যতীত 7 বাই 12 টি ম্যাট্রিক্স রয়েছে তবে এরকম চক্রীয় ম্যাট্রিক্স নেই।

21/11 এটি এবং পূর্ববর্তী চ্যালেঞ্জ থেকে সমস্ত বর্তমান উত্তরগুলিকে পরাজিত করবে।

ভাষা ও গ্রন্থাগার

আপনি যে কোনও ভাষা নিখরচায় উপলব্ধ সংকলক / দোভাষী / ইত্যাদি ব্যবহার করতে পারেন। লিনাক্স এবং যে কোনও লাইব্রেরির জন্য লিনাক্সের জন্য নিখরচায় উপলব্ধ।

বোনাস 2 এরও বেশি স্কোর সহ প্রথম উত্তরটি সাথে সাথে 200 পয়েন্ট বন্টি পুরষ্কার পায়। টন হসপেল এখন এটি অর্জন করেছে!


বর্তমান নেতা বোর্ড

  • সি ++ । টন হসপেলের দ্বারা 31/15 স্কোর
  • জাভা । পিটার টেলর দ্বারা 36/19 স্কোর
  • Haskell, । আলেকজান্দার-ব্রেট দ্বারা 14/8 স্কোর

"অ-অভিন্ন পরিচয় সূচক সহ দুটি খালি খালি কলামগুলি" দ্বারা আপনি বোঝাচ্ছেন যে দুটি কলাম বিচ্ছিন্ন? বা, এটিকে পুনরায় বিবরণ দিতে, {1, 3}, {1, 5 col কলামের বৈধ দুটি উপসেট?
pawel.boczarski

@ pawel.boczarski কোনও মতবিরোধ করবেন না। শুধু অ-অভিন্ন। সুতরাং {1, 3}, {1, 5 valid বৈধ।

ঠিক আছে. এম [i, 1] সম্পর্কে কী - এটি এম [আই -1] এর শেষ কলাম থেকে "orrowণ" নেওয়া (শূন্যটি বৈধ ম্যাট্রিক্স কলাম সূচক নয়)? এবং আসলে এটি "উপরে এবং বাম" না হয়ে "উপরে এবং বাম"।
pawel.boczarski

@ pawel.boczarski "ডান" একটি টাইপ ছিল। ধন্যবাদ। প্রথম সারি এবং কলামটি আপনার পছন্দের যেকোন কিছুতে সেট করা যেতে পারে। তারা ম্যাট্রিক্সের পুরো অংশটি সংজ্ঞায়িত করে। এতে আপনার প্রশ্নের উত্তর হলো কি?

ঠিক আছে, আমি বুঝতে পেরেছি. প্রথম কলামটিও সংজ্ঞায়িত হয়ে মনোযোগ সহকারে না পড়লে আমার দোষ ছিল।
pawel.boczarski

উত্তর:


6

সি ++, স্কোর 23/12 25/13 27/14 28/14 31/15

পরিশেষে> 2 2 এর সাথে ফলাফল:

rows=15,cols=31
1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 1 0 
1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 1 
1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 1 
1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 0 
1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 1 
0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 1 
0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 1 
1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 1 
0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 0 
0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 0 
0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 0 
1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 1 
0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 
0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 0 
1 0 0 1 0 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 0 1 1 

আমি 1 থেকে 14 টি সারি পুরোপুরি অন্বেষণ করেছি। সম্পূর্ণরূপে অন্বেষণ করতে 15 খুব বেশি সময় নেয়। ফলাফলগুলি হ'ল:

1/1   = 1
2/2   = 1
4/3   = 1.333
5/4   = 1.25
7/5   = 1.4
9/6   = 1.5
12/7  = 1.714
14/8  = 1.75
16/9  = 1.778
18/10 = 1.8
20/11 = 1.818
23/12 = 1.917
25/13 = 1.923
28/14 = 2

নীচে দেওয়া কোডটি প্রোগ্রামটির একটি পুরানো সংস্করণ। সর্বশেষতম সংস্করণটি https://github.com/thospel/personal-propertyX এ রয়েছে

/*
  Compile using something like:
    g++ -Wall -O3 -march=native -fstrict-aliasing -std=c++11 -g propertyX.cpp -lpthread -o propertyX
*/
#include <cstdint>
#include <climits>
#include <ctgmath>
#include <iostream>
#include <vector>
#include <array>
#include <chrono>
#include <mutex>
#include <atomic>
#include <thread>

using namespace std;

const int ELEMENTS = 2;

using uint    = unsigned int;
using Element = uint64_t;
using Column  = array<Element, ELEMENTS>;
using Set     = vector<Column>;
using Sum     = uint8_t;
using Index   = uint32_t;
using sec = chrono::seconds;

int const PERIOD = 5*60;
int const MAX_ROWS = 54;
int const COL_FACTOR = (MAX_ROWS+1) | 1;                // 55
int const ROW_ZERO   = COL_FACTOR/2;                    // 27
int const ROWS_PER_ELEMENT = CHAR_BIT * sizeof(Element) / log2(COL_FACTOR); //11
Element constexpr ELEMENT_FILL(Element v = ROW_ZERO, int n = ROWS_PER_ELEMENT) {
    return n ? ELEMENT_FILL(v, n-1) * COL_FACTOR + v : 0;
}
Element constexpr POWN(Element v, int n) {
    return n ? POWN(v, n-1)*v : 1;
}
Element const ELEMENT_TOP = POWN(COL_FACTOR, ROWS_PER_ELEMENT -1);
int const MAX_COLS = ROWS_PER_ELEMENT * ELEMENTS;       // 22

atomic<Index> col_next;
atomic<uint>  period;
chrono::steady_clock::time_point start;
mutex period_mutex;

uint ratio_row;
uint ratio_col;
mutex ratio_mutex;

auto const nr_threads = thread::hardware_concurrency();
// auto const nr_threads = 1;

struct State {
    State(uint cols);
    void process(Index i);
    void extend(uint row);
    void print(uint rows);
    Index nr_columns() const { return static_cast<Index>(1) << cols_; }

    Column last_;
    Element top_;
    int top_offset_;
    uint ratio_row_ = 0;
    uint ratio_col_ = 1;
    uint cols_;
    array<Sum, MAX_ROWS + MAX_COLS -1> side;
    vector<Set> sets;
};

ostream& operator<<(ostream& os, Column const& column) {
    for (int i=0; i<ELEMENTS; ++i) {
        auto v = column[i];
        for (int j=0; j<ROWS_PER_ELEMENT; ++j) {
            auto bit = v / ELEMENT_TOP;
            cout << " " << bit;
            v -= bit * ELEMENT_TOP;
            v *= COL_FACTOR;
        }
    }
    return os;
}

State::State(uint cols) : cols_{cols} {
    sets.resize(MAX_ROWS+2);
    for (int i=0; i<2; ++i) {
        sets[i].resize(2);
        for (int j=0; j < ELEMENTS; ++j) {
            sets[i][0][j] =  ELEMENT_FILL();
            sets[i][1][j] =  static_cast<Element>(-1) - ELEMENT_FILL(1);
        }
    }
    top_ = POWN(COL_FACTOR, (cols_-1) % ROWS_PER_ELEMENT);
    top_offset_ = ELEMENTS - 1 - (cols_-1) / ROWS_PER_ELEMENT;
}

void State::print(uint rows) {
    for (auto c=0U; c<cols_;c++) {
        for (auto r=0U; r<rows;r++) {
            cout << static_cast<int>(side[cols_-c+r-1]) << " ";
        }
        cout << "\n";
    }
    cout << "----------" << endl;
}

void check(uint cols, uint t) {
    State state(cols);

    Index nr_columns = state.nr_columns();
    while (1) {
        Index col = col_next++;
        if (col >= nr_columns) break;
        state.process(col);

        auto now = chrono::steady_clock::now();
        auto elapsed = chrono::duration_cast<sec>(now-start).count();
        if (elapsed >= period) {
            lock_guard<mutex> lock{period_mutex};
            if (elapsed >= period) {
                cout << "col=" << col << "/" << nr_columns << " (" << 100.*col/nr_columns << "% " << elapsed << " s)" << endl;
                period = (elapsed/PERIOD+1)*PERIOD;
            }
        }
    }
}

void State::process(Index col) {
    last_.fill(0);
    for (uint i=0; i<cols_; ++i) {
        Element bit = col >> i & 1;
        side[i] = bit;
        Element carry = 0;
        for (int j=0; j<ELEMENTS; ++j) {
            auto c = last_[j] % COL_FACTOR;
            last_[j] = last_[j] / COL_FACTOR + carry * ELEMENT_TOP;
            if (j == top_offset_ && bit) last_[j] += top_;
            carry = c;
        }
    }
    // cout << "col=" << col << ", value=" << last_ << "\n";
    extend(0);
}

void State::extend(uint row) {
    // cout << "Extend row " << row << " " << static_cast<int>(side[cols_+row-1]) << "\n";
    if (row >= MAX_ROWS) throw(range_error("row out of range"));

    // Execute subset sum. The new column is added to set {from} giving {to}
    // {sum} is the other set.
    auto const& set_from = sets[row];
    auto const& set_sum  = sets[row + 1];
    auto      & set_to   = sets[row + 2];
    if (set_to.size() == 0) {
        auto size = 3 * set_from.size() - 2;
        set_to.resize(size);
        for (int j=0; j<ELEMENTS; ++j)
            set_to[size-1][j] = static_cast<Element>(-1) - ELEMENT_FILL(1);
    }

    // Merge sort {set_from - last_} , {set_from} and {set_from + last_}
    auto ptr_sum    = &set_sum[1][0];
    auto ptr_low    = &set_from[0][0];
    auto ptr_middle = &set_from[0][0];
    auto ptr_high   = &set_from[0][0];
    Column col_low, col_high;
    for (int j=0; j<ELEMENTS; ++j) {
        col_low   [j] = *ptr_low++  - last_[j];
        col_high  [j] = *ptr_high++ + last_[j];
    }

    auto ptr_end = &set_to[set_to.size()-1][0];
    auto ptr_to  = &set_to[0][0];
    while (ptr_to < ptr_end) {
        for (int j=0; j<ELEMENTS; ++j) {
            if (col_low[j] < ptr_middle[j]) goto LOW;
            if (col_low[j] > ptr_middle[j]) goto MIDDLE;
        }
        // low == middle
        // cout << "low == middle\n";
        return;

      LOW:
        // cout << "LOW\n";
        for (int j=0; j<ELEMENTS; ++j) {
            if (col_low[j] < col_high[j]) goto LOW0;
            if (col_low[j] > col_high[j]) goto HIGH0;
        }
        // low == high
        // cout << "low == high\n";
        return;

      MIDDLE:
        // cout << "MIDDLE\n";
        for (int j=0; j<ELEMENTS; ++j) {
            if (ptr_middle[j] < col_high[j]) goto MIDDLE0;
            if (ptr_middle[j] > col_high[j]) goto HIGH0;
        }
        // middle == high
        // cout << "middle == high\n";
        return;

      LOW0:
        // cout << "LOW0\n";
        for (int j=0; j<ELEMENTS; ++j) {
            *ptr_to++  = col_low[j];
            col_low[j] = *ptr_low++ - last_[j];
        }
        goto SUM;

      MIDDLE0:
        // cout << "MIDDLE0\n";
        for (int j=0; j<ELEMENTS; ++j)
            *ptr_to++ = *ptr_middle++;
        goto SUM;

      HIGH0:
        // cout << "HIGH0\n";
        for (int j=0; j<ELEMENTS; ++j) {
            *ptr_to++ = col_high[j];
            col_high[j] = *ptr_high++ + last_[j];
        }
        goto SUM;
      SUM:
        for (int j=-ELEMENTS; j<0; ++j) {
            if (ptr_to[j] > ptr_sum[j]) {
                ptr_sum += ELEMENTS;
                goto SUM;
            }
            if (ptr_to[j] < ptr_sum[j]) goto DONE;
        }
        // sum == to
        for (int j=-ELEMENTS; j<0; ++j)
            if (ptr_to[j] != ELEMENT_FILL()) {
                // sum == to and to != 0
                // cout << "sum == to\n";
                // cout << set_sum[(ptr_sum - &set_sum[0][0])/ELEMENTS-1] << "\n";
                return;
            }
      DONE:;
    }
    // cout << "Wee\n";
    auto row1 = row+1;
    if (0)
        for (uint i=0; i<row1+2; ++i) {
            cout << "Set " << i << "\n";
            auto& set = sets[i];
            for (auto& column: set)
                cout << column << "\n";
        }

    if (row1 * ratio_col_ > ratio_row_ * cols_) {
        ratio_row_ = row1;
        ratio_col_ = cols_;
        lock_guard<mutex> lock{ratio_mutex};

        if (ratio_row_ * ratio_col > ratio_row * ratio_col_) {

            auto now = chrono::steady_clock::now();
            auto elapsed = chrono::duration_cast<sec>(now-start).count();
            cout << "cols=" << cols_ << ",rows=" << row1 << " (" << elapsed << " s)\n";
            print(row1);
            ratio_row = ratio_row_;
            ratio_col = ratio_col_;
        }
    }

    auto last = last_;

    Element carry = 0;
    for (int j=0; j<ELEMENTS; ++j) {
        auto c = last_[j] % COL_FACTOR;
        last_[j] = last_[j] / COL_FACTOR + carry * ELEMENT_TOP;
        carry = c;
    }

    side[cols_+row] = 0;
    extend(row1);

    last_[top_offset_] += top_;
    side[cols_+row] = 1;
    extend(row1);

    last_ = last;
}

void my_main(int argc, char** argv) {
    if (!col_next.is_lock_free()) cout << "col_next is not lock free\n";
    if (!period.  is_lock_free()) cout << "period is not lock free\n";

    int min_col = 2;
    int max_col = MAX_COLS;
    if (argc > 1) {
        min_col = atoi(argv[1]);
        if (min_col < 2)
            throw(range_error("Column must be >= 2"));
        if (min_col > MAX_COLS)
            throw(range_error("Column must be <= " + to_string(MAX_COLS)));
    }
    if (argc > 2) {
        max_col = atoi(argv[2]);
        if (max_col < min_col)
            throw(range_error("Column must be >= " + to_string(min_col)));
        if (max_col > MAX_COLS)
            throw(range_error("Column must be <= " + to_string(MAX_COLS)));
    }

    for (int cols = min_col; cols <= max_col; ++cols) {
        cout << "Trying " << cols << " columns" << endl;
        ratio_row = 0;
        ratio_col = 1;
        col_next = 0;
        period = PERIOD;
        start = chrono::steady_clock::now();
        vector<thread> threads;
        for (auto t = 1U; t < nr_threads; t++)
            threads.emplace_back(check, cols, t);
        check(cols, 0);
        for (auto& thread: threads)
            thread.join();
    }
}

int main(int argc, char** argv) {
    try {
        my_main(argc, argv);
    } catch(exception& e) {
        cerr << "Error: " << e.what() << endl;
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

এটা অসাধারণ. দুর্দান্ত রহস্যটি হ'ল আপনি যদি কখনও 2 এর স্কোর পেতে পারেন

এক্সট্রাপোলেশন দ্বারা, 28/14 এর অস্তিত্ব থাকা উচিত আমার মনে হয় যা সত্যই উত্তেজনাপূর্ণ হবে। তবে এটি কি ধরাছোঁয়ার বাইরে?

n = 14 আমার 8-কোর সিপিইউতে আমার বর্তমান কোড সহ প্রায় 200 দিন লাগবে। কোডটি সম্ভবত 30% বা আরও বাড়ানো যেতে পারে। এর পরে আমি ধারণার বাইরে চলে যাই। এবং আপনার এক্সট্রোপোলেশনটি
যেকোনোভাবেই

আমার মনে হয় প্রথম সারিতে 01011011100010111101000001100111110011010100011010 সহ 50 মাই 25 এর ম্যাট্রিক্সটি কাজ করতে পারে। এটি একটি অপ্টিমাইজেশন হিউরিস্টিকের দ্বারা পাওয়া গেছে যা কার্যকর হতে পারে।

এন = 14 এর সম্পূর্ণ কভারের জন্য 140 ঘন্টা খুব চিত্তাকর্ষকভাবে আমি বলতে চাই have

2

হাসেল 14/8 = 1.75

1 1 0 0 0 1 0 1 1 0 1 1 0 0
1 1 1 0 0 0 1 0 1 1 0 1 1 0
0 1 1 1 0 0 0 1 0 1 1 0 1 1
1 0 1 1 1 0 0 0 1 0 1 1 0 1
0 1 0 1 1 1 0 0 0 1 0 1 1 0
0 0 1 0 1 1 1 0 0 0 1 0 1 1
0 0 0 1 0 1 1 1 0 0 0 1 0 1
0 0 0 0 1 0 1 1 1 0 0 0 1 0

পূর্বে 9/6 = 1.5

1 0 1 0 1 1 0 0 1
1 1 0 1 0 1 1 0 0
1 1 1 0 1 0 1 1 0
1 1 1 1 0 1 0 1 1
1 1 1 1 1 0 1 0 1
1 1 1 1 1 1 0 1 0

আমি এটি লিখেছিলাম, তারপরে অন্য প্রশ্নের উত্তরগুলি তাকিয়েছিলাম এবং নিরুৎসাহিত হয়েছিল।

import Data.List
import Data.Hashable
import Control.Monad
import Control.Parallel.Strategies
import Control.Parallel
import qualified Data.HashSet as S

matrix§indices = [ matrix!!i | i<-indices ]

powerset :: [a] -> [[a]]
powerset = filterM (const [True, False])

hashNub :: (Hashable a, Eq a) => [a] -> [a]
hashNub l = go S.empty l
    where
      go _ []     = []
      go s (x:xs) = if x `S.member` s
        then go s xs
        else x : go (S.insert x s) xs

getMatrix :: Int -> Int -> [Int] -> [[Int]]
getMatrix width height vector = [ vector § [x..x+width-1] | x<-[0..height-1] ]

hasDuplicate :: (Hashable a, Eq a) => [a] -> Bool
hasDuplicate m = go S.empty m
    where
        go _ [] = False
        go s (x:xs) = if x `S.member` s
            then True
            else go (S.insert x s) xs

hasProperty :: [[Int]] -> Bool
hasProperty matrix =
    let
        base = replicate (length (matrix !! 0)) 0::[Int]
    in
        if elem base matrix then
            False
        else
            if hasDuplicate matrix then
                False
            else
                if hasDuplicate (map (foldl (zipWith (+)) base) (powerset matrix)) then
                    False
                else
                    True


pmap = parMap rseq

matricesWithProperty :: Int -> Int -> [[[Int]]]
matricesWithProperty n m =
    let
        base = replicate n 0::[Int]
    in
    filter (hasProperty) $
    map (getMatrix n m) $
    sequence [ [0,1] | x<-[0..n+m-1] ]

firstMatrixWithProperty :: Int -> Int -> [[Int]]
firstMatrixWithProperty n m = head $ matricesWithProperty n m

main = mapM (putStrLn. show) $ map (firstMatrixWithProperty 8) [1..]

ধন্যবাদ! একটি হাস্কেল উত্তর সর্বদা খুব স্বাগত। আমি মনে করি প্রথম আকর্ষণীয় কেসটি 12/7। আপনি এটি পেতে পারেন?

আমি এটি একটি ডুয়াল-কোর ২০০৯ এর ল্যাপটপে চালাচ্ছি, তাই না :) আমি আবার একটি দ্রুত মেশিনে আবার চেষ্টা করব
আলেকান্দার-ব্রেট

খুব সুন্দর. আমি কেবল একটি মন্তব্য যুক্ত করেছি যে 21/11 পূর্ববর্তী সমস্ত উত্তরগুলিকে পরাজিত করবে।

আপনার কোড আউটপুট ঠিক কি দয়া করে ব্যাখ্যা করতে পারেন?

ইন main, সংখ্যা (এই ক্ষেত্রে 8) ম্যাট্রিক্সের উচ্চতা এবং প্রোগ্রামটি প্রস্থের মাধ্যমে পুনরাবৃত্তি করে [1..]। প্রতিটি উচ্চতা / প্রস্থের সংমিশ্রণের জন্য, এটি একটি বৈধ ম্যাট্রিক্সের কলামগুলির একটি অ্যারে প্রিন্ট করে।
আলেকজান্ডার-ব্রেট

1

সি

এখানে একটি উত্তর যা কাজ করে এবং হাস্কেলের চেয়ে উল্লেখযোগ্যভাবে আরও মেমরি-দক্ষ। দুর্ভাগ্যক্রমে, আমার কম্পিউটার এখনও কোনও যুক্তিসঙ্গত দৈর্ঘ্যে 14/8 এর চেয়ে ভাল অর্জন করতে খুব ধীর।

এর সাথে সংকলন করে gcc -std=c99 -O2 -fopenmp -o matrices.exe matrices.cচলার চেষ্টা করুন matrices.exe width heightবা এর সাথে মিলে যায় । আউটপুটটি একটি পূর্ণসংখ্যা, উদাহরণস্বরূপ, বিটগুলিতে প্রশ্নের ম্যাট্রিক্সের ভিত্তি তৈরি হয়:

$ matrices.exe 8 14
...
valid i: 1650223

তারপরে, যেহেতু 1650223 = 0b110010010111000101111, প্রশ্নের ম্যাট্রিক্স হ'ল:

0 0 1 1 1 0 1 0 0 1 0 0 1 1
0 ...
1 ...
0
1
1
1
1

যদি 8 টি কোর এবং হাতে থাকা কেউ যদি কিছু সময়ের জন্য এটি চালাতে চায় তবে আমি মনে করি কিছু ভাল জিনিসের ফল হতে পারে :)


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

/*
 * BEGIN WIKIPEDIA CODE
 */
const long long m1  = 0x5555555555555555; //binary: 0101...
const long long m2  = 0x3333333333333333; //binary: 00110011..
const long long m4  = 0x0f0f0f0f0f0f0f0f; //binary:  4 zeros,  4 ones ...
const long long m8  = 0x00ff00ff00ff00ff; //binary:  8 zeros,  8 ones ...
const long long m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ...
const long long m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones
const long long hff = 0xffffffffffffffff; //binary: all ones
const long long h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3...
//This uses fewer arithmetic operations than any other known
//implementation on machines with fast multiplication.
//It uses 12 arithmetic operations, one of which is a multiply.
long long hamming(long long x) {
    x -= (x >> 1) & m1;             //put count of each 2 bits into those 2 bits
    x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits
    x = (x + (x >> 4)) & m4;        //put count of each 8 bits into those 8 bits
    return (x * h01)>>56;  //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...
}
/*
 * END WIKIPEDIA CODE
 */

int main ( int argc, char *argv[] ) {
    int height;
    int width;

    sscanf(argv[1], "%d", &height);
    sscanf(argv[2], "%d", &width);

    #pragma omp parallel for
    for (
        /*
         * We know that there are 2^(h+w-1) T-matrices, defined by the entries
         * in the first row and first column. We'll let the long long i
         * represent these entries, with 1s represented by set bits.
         *
         * The first (0) and last (1) matrix we will ignore.
         */
        long long i = 1;
        i < (1 << (height+width-1))-1;
        i++
    ) {
        // Flag for keeping track as we go along.
        int isvalid = 1;

        /*
         * Start by representing the matrix as an array of columns, with each
         * non-zero matrix entry as a bit. This allows us to construct them and
         * check equality very quickly.
         */
        long *cols = malloc(sizeof(long)*width);
        long colmask = (1 << height)-1;
        for (int j = 0; j < width; j++) {
            cols[j] = (i >> j) & colmask;
            if (cols[j] == 0) {
                //check no zero rows
                isvalid = 0;
            } else {
                //check no duplicate rows
                for (int k = 0; k < j; k++) {
                    if (cols[j] == cols[k]) {
                        isvalid = 0;
                    }
                }
            }
        }

        if (isvalid == 1) {
            /*
             * We'll also represent the matrix as an array of rows, in a
             * similar manner.
             */
            long *rows = malloc(sizeof(long)*height);
            long rowmask = (1 << width)-1;
            for (int j = 0; j < height; j++) {
                rows[j] = (i >> j) & rowmask;
            }

            int *sums[(1 << width)];
            for (long j = 0; j < 1<<width; j++) {
                sums[j] = (int*)malloc(sizeof(int)*height);
            }

            for (
                /*
                 * The powerset of columns has size 2^width. Again with the
                 * long; this time each bit represents whether the
                 * corresponding row is a member of the subset. The nice thing
                 * about this is we can xor the permutation with each row,
                 * then take the hamming number of the resulting number to get
                 * the sum.
                 */
                long permutation = 1;
                (isvalid == 1) && (permutation < (1 << width)-1);
                permutation ++
            ) {
                for (int j = 0; j < height; j++) {
                    sums[permutation][j] = hamming( rows[j] & permutation);
                }
                for (int j = permutation-1; (isvalid == 1) && (j > -1); j--) {
                    if (memcmp(sums[j], sums[permutation], sizeof(int)*height) == 0) {
                        isvalid = 0;
                    }
                }
            }

            for (long j = 0; j < 1<<width; j++) {
                free(sums[j]);
            }

            free(rows);

        }

        if (isvalid == 1) {
            printf ("valid i: %ld\n", i);
        }

        free(cols);
    }

    return 0;
}

আমি আলেকজান্দার-ব্রেটসিটি পেয়েছি: ফাংশনটিতে 'প্রধান': আলেকজান্দার-ব্রেট সিটি: 107: 21: সতর্কতা: ফাংশনটির 'মেমক্যাম্প' এর অন্তর্নিহিত ঘোষণা [[উইম্প্লিফিক-ফাংশন-ডিক্লারেশন]] যদি (মেমক্যাম্প (স্যামস [জে], অঙ্কগুলি [অনুচ্ছেদ], আকারের (অন্তর্নিহিত) * উচ্চতা) == 0) lex lex আলেকজান্ডার-ব্রেট সিট: 122: 13: সতর্কতা: ফর্ম্যাট '% এলডি' 'দীর্ঘ ইনট' টাইপের আর্গুমেন্টের প্রত্যাশা করে, তবে আর্গুমেন্ট 2 টাইপ করে ' দীর্ঘ দীর্ঘ ইন্ট '[-Wformat =] প্রিন্টফ ("বৈধ i:% ld \ n", i);

আপনার কতক্ষণ সময় নিবে ./alexender-brett 8 14?

হাই লেম্বিক, 8 14 কোয়াড কোর মেশিনে আমার জন্য 5 ঘন্টা উত্তর পেয়েছে। আমি উইন্ডোতে এই শিরোলেখগুলির সাথে সংকলন পরিচালনা করেছিলাম, মেমক্যাম্পটি নিখোঁজ হলে এটি আরও বেআইনী হত ...
আলেকজান্দার-ব্রেট


আমি আপনার কোডটি 7 12 দিয়ে চেষ্টা করেছি এবং এর উত্তরগুলির মধ্যে একটি হ'ল valid i: 7481। পাইথন বিনে (7481) 0 বি 1110100111001 যা যথেষ্ট দীর্ঘ নয়। কি হচ্ছে কোনো ধারনা আছে?
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.