সিজেম, 189 187 বাইট
এটি কারও ব্যাখ্যা করা শক্ত হবে ... সময়ের জটিলতা হওয়ার নিশ্চয়তা রয়েছে O(scary)
।
qi:N_3>{,aN*]N({{:L;N,X)-e!{X)_@+L@@t}%{X2+<z{_fe=:(:+}%:+!},}%:+}fX{:G;N3m*{_~{G@==}:F~F\1m>~F\F=}%:*},:L,({LX=LX)>1$f{\_@a\a+Ne!\f{\:M;~{M\f=z}2*\Mff==}:|{;}|}\a+}fX]:~$e`{0=1=},,}{!!}?
আপনি যদি যথেষ্ট সাহসী হন তবে অনলাইনে চেষ্টা করুন । আমার ক্রেপি ল্যাপটপে আমি জাভা ইন্টারপ্রেটারের সাথে 6 বা অনলাইন ইন্টারপ্রেটারে 5 পেতে পারি।
ব্যাখ্যা
আমার কোনও গণিতের ব্যাকগ্রাউন্ড নেই (সবেমাত্র হাই স্কুল শেষ হয়েছে, পরের সপ্তাহে ইউনিতে সিএস শুরু হবে)। সুতরাং আমি যদি ভুল করি, সুস্পষ্ট কথা বলি বা মারাত্মকভাবে অকার্যকর উপায়ে জিনিসগুলি করি তবে আমার সাথে সহ্য করুন।
আমার দৃষ্টিভঙ্গি একটি নিষ্ঠুর শক্তি, যদিও আমি এটিকে কিছুটা চালাক করার চেষ্টা করেছি। প্রধান পদক্ষেপগুলি হ'ল:
- সব সম্ভব operands জেনারেট করুন * আদেশের একটি দলের জন্য এন (অর্থাত, আদেশের সকল গোষ্ঠী গনা এন );
- জেনারেট করুন সব সম্ভব bijections φ আদেশের দুই দলের মধ্যে এন ;
- ধাপ 1 এবং 2 থেকে ফলাফল ব্যবহার করে, আদেশের দুই দলের মধ্যে সব isomorphisms নির্ধারণ এন ;
- পদক্ষেপ 3 থেকে ফলাফলটি ব্যবহার করে, আইসোমরফিজম পর্যন্ত গোষ্ঠীর সংখ্যা গণনা করুন।
প্রতিটি পদক্ষেপ কীভাবে হয় তা দেখার আগে আসুন কিছু তুচ্ছ কোড বেরিয়ে আসুন:
qi:N_ e# Get input as integer, store in N, make a copy
3>{...} ? e# If N > 3, do... (see below)
{!!} e# Else, push !!N (0 if N=0, 1 otherwise)
নিম্নলিখিত অ্যালগরিদমটি এন <4 দিয়ে সঠিকভাবে কাজ করে না , 0 থেকে 3 পর্যন্ত কেসগুলি দ্বিগুণ প্রত্যাখ্যানের সাথে পরিচালিত হয়।
এখন থেকে, একটি গোষ্ঠীর উপাদানগুলি {1, a, b, c, ... as হিসাবে লেখা হবে , যেখানে 1 পরিচয়ের উপাদান। সিজেএম বাস্তবায়নে, সংশ্লিষ্ট উপাদানগুলি হ'ল the 0, 1, 2, 3, ...} , যেখানে 0 পরিচয় উপাদান।
প্রথম পদক্ষেপ 1 থেকে শুরু করা যাক অর্ডার n এর একটি গ্রুপের জন্য সমস্ত সম্ভাব্য অপারেটরদের লেখা সমস্ত বৈধ n × n কেলে টেবিল তৈরির সমান । প্রথম সারি এবং কলামটি তুচ্ছ: এগুলি উভয়ই {1, a, b, c, ...} (বাম-থেকে-ডান, উপরে-ডাউন)।
e# N is on the stack (duplicated before the if)
,a e# Generate first row [0 1 2 3 ...] and wrap it in a list
N* e# Repeat row N times (placeholders for next rows)
] e# Wrap everything in a list
e# First column will be taken care of later
একটি কেলে টেবিল হ্রাস করা ল্যাটিন স্কোয়ার ( জেনে রাখা সম্পত্তি কারণে) এটি সম্ভব সারণী-সারি সারণী তৈরি করতে দেয় Know দ্বিতীয় সারির (সূচী 1) থেকে শুরু করে, আমরা প্রথম সারিতে সূচকের মানকে স্থির রেখে, এই সারিটির জন্য সমস্ত অনন্য অনুমান তৈরি করি ।
N({ }fX e# For X in [0 ... N-2]:
{ }% e# For each table in the list:
:L; e# Assign the table to L and pop it off the stack
N, e# Push [0 ... N-1]
X) e# Push X+1
- e# Remove X+1 from [0 ... N-1]
e! e# Generate all the unique permutations of this list
{ }% e# For each permutation:
X)_ e# Push two copies of X+1
@+ e# Prepend X+1 to the permutation
L@@t e# Store the permutation at index X+1 in L
{...}, e# Filter permutations (see below)
:+ e# Concatenate the generated tables to the table list
এই সমস্ত অনুমতিটি বৈধ নয়, অবশ্যই: প্রতিটি সারি এবং কলামে অবশ্যই সমস্ত উপাদান অবশ্যই এক সময় থাকতে হবে। এই উদ্দেশ্যে একটি ফিল্টার ব্লক ব্যবহার করা হয় (সত্যবাদী মান ক্রমান্বয়ে রাখে, একটি মিথ্যাবাদী এটিকে সরিয়ে দেয়):
X2+ e# Push X+2
< e# Slice the permutations to the first X+2 rows
z e# Transpose rows and columns
{ }% e# For each column:
_fe= e# Count occurences of each element
:( e# Subtract 1 from counts
:+ e# Sum counts together
:+ e# Sum counts from all columns together
! e# Negate count sum:
e# if the sum is 0 (no duplicates) the permutation is kept
e# if the sum is not zero the permutation is filtered away
নোট করুন যে আমি প্রজন্মের লুপের ভিতরে ফিল্টার করছি: এটি কোডটি কিছুটা দীর্ঘ করে তোলে (স্বতন্ত্র প্রজন্ম এবং ফিল্টারিংয়ের তুলনায়), তবে কার্য সম্পাদনকে অনেক উন্নত করে। একটি সেট আকারের ক্রমের সংখ্যা এন হয় এন! , তাই সংক্ষিপ্ত সমাধানের জন্য প্রচুর স্মৃতি এবং সময় প্রয়োজন।
বৈধ কেলে টেবিলগুলির তালিকা অপারেটরদের গণনার পক্ষে একটি দুর্দান্ত পদক্ষেপ, তবে এটি 2 ডি কাঠামো হওয়ায় এটি সাহচর্যতার জন্য যাচাই করতে পারে না, এটি একটি 3 ডি সম্পত্তি। সুতরাং পরবর্তী পদক্ষেপটি অ-অ্যাসোসিয়েটিভ ফাংশনগুলি ফিল্টার করছে।
{ }, e# For each table, keep table if result is true:
:G; e# Store table in G, pop it off the stack
N3m* e# Generate triples [0 ... N-1]^3
{ }% e# For each triple [a b c]:
_~ e# Make a copy, unwrap top one
{ }:F e# Define function F(x,y):
G@== e# x∗y (using table G)
~F e# Push a∗(b∗c)
\1m> e# Rotate triple right by 1
~ e# Unwrap rotated triple
F\F e# Push (a∗b)∗c
= e# Push 1 if a∗(b∗c) == (a∗b)∗c (associative), 0 otherwise
:* e# Multiply all the results together
e# 1 (true) only if F was associative for every [a b c]
রাম রাম! প্রচুর কাজ, তবে এখন আমরা অর্ডার এন এর সমস্ত গ্রুপকে গণনা করেছি (বা আরও ভাল, এটিতে অপারেশনগুলি - তবে সেটটি স্থির হয়েছে, সুতরাং এটি একই জিনিস)। পরবর্তী পদক্ষেপ: আইসোমরফিজমগুলি সন্ধান করুন। আইসোমরফিজম হ'ল groups (x ∗ y) = φ (x) ∗ φ (y) এর মধ্যে দুটি দলের মধ্যে একটি সক্ষমতা । সিজেমে এই বাইজিকেশনগুলি তৈরি করা তুচ্ছ - Ne!
এটি করবে। আমরা কীভাবে সেগুলি পরীক্ষা করতে পারি? আমার সমাধানটি x ∗ y এর জন্য কেলে টেবিলের দুটি অনুলিপি থেকে শুরু হয় । একটি অনুলিপিতে, সারি বা কলামগুলির ক্রম স্পর্শ না করে φ সমস্ত উপাদানগুলিতে প্রয়োগ করা হয়। এটি φ (x ∗ y) এর জন্য সারণী তৈরি করে । অন্যটি উপর হিসাবে তারা উপাদান ফেলে রাখা হয়, কিন্তু সারি এবং কলাম মাধ্যমে ম্যাপ করা হয় φ । অর্থাৎ সারি / কলামx সারি / কলাম φ (x) হয় । এটি φ (x) ∗ φ (y) এর জন্য সারণী তৈরি করে । এখন যেহেতু আমাদের দুটি টেবিল রয়েছে, আমাদের কেবল তাদের তুলনা করতে হবে: যদি সেগুলি একই হয় তবে আমরা একটি আইসোমরফিজম পেয়েছি।
অবশ্যই, আইসোমরফিজমটি পরীক্ষা করার জন্য আমাদের গ্রুপগুলির জোড়াও তৈরি করতে হবে। আমাদের গ্রুপগুলির সমস্ত 2-সংমিশ্রণ প্রয়োজন । দেখে মনে হচ্ছে সিজেমের সংমিশ্রণের জন্য কোনও অপারেটর নেই। আমরা প্রতিটি গ্রুপ নিয়ে এবং তালিকায় এটি অনুসরণকারী উপাদানগুলির সাথে একত্রিত করে এগুলি উত্পন্ন করতে পারি। মজাদার ঘটনা: 2-সংমিশ্রণের সংখ্যা n × (n - 1) / 2 , যা প্রথম এন - 1 প্রাকৃতিক সংখ্যার যোগফল। এই জাতীয় সংখ্যাকে ত্রিভুজাকার সংখ্যা বলা হয়: কাগজে অ্যালগরিদম চেষ্টা করুন, নির্দিষ্ট উপাদান প্রতি এক সারি, এবং আপনি কেন তা দেখতে পাবেন।
:L e# List of groups is on stack, store in L
,( e# Push len(L)-1
{ }fX e# For X in [0 ... len(L)-2]:
LX= e# Push the group L[X]
LX)> e# Push a slice of L excluding the first X+1 elements
1$ e# Push a copy of L[X]
f{...} e# Pass each [L[X] Y] combination to ... (see below)
e# The block will give back a list of Y for isomorphic groups
\a+ e# Append L[X] to the isomorphic groups
] e# Wrap everything in a list
উপরের কোডটি জোড়ার প্রথম উপাদান, এল [এক্স] সংশোধন করে এবং এটিকে অন্যান্য গোষ্ঠীর সাথে সংযুক্ত করে (আসুন Y ওয়াইগুলির প্রত্যেককে কল করুন )। এটি জুটিটি একটি আইসোমরফিজম টেস্ট ব্লকে পাস করে যা আমি এক মুহুর্তে দেখাব। ব্লকটি ওয়াইয়ের মানগুলির একটি তালিকা ফিরিয়ে দেয় যার জন্য এল [এক্স] ওয়াই থেকে আইসোমরফিক । তারপরে এল [এক্স] এই তালিকায় যুক্ত হবে। তালিকাগুলি কেন এমনভাবে সেট আপ করা হয় তা বোঝার আগে আসুন আইসোমর্ফিিজম পরীক্ষার দিকে নজর দেওয়া যাক:
\_@ e# Push a copy of Y
a\a+ e# L[X] Y -> [L[X] Y]
Ne! e# Generate all bijective mappings
\f{ } e# For each bijection ([L[X] Y] extra parameter):
\:M; e# Store the mapping in M, pop it off the stack
~ e# [L[X] Y] -> L[X] Y
{ }2* e# Repeat two times (on Y):
M\f= e# Map rows (or transposed columns)
z e# Transpose rows and columns
e# This generates φ(x) ∗ φ(y)
\Mff= e# Map elements of L[X], generates φ(x ∗ y)
= e# Push 1 if the tables are equal, 0 otherwise
:| e# Push 1 if at least a mapping was isomorphic, 0 otherwise
{;}| e# If no mapping was isomorphic, pop the copy of Y off the stack
দুর্দান্ত, এখন আমাদের কাছে [{এল [0], ওয়াই 1, ওয়াই 2, ...}, {এল [1], ওয়াই 1, ...}, ...] এর মতো সেটগুলির একটি তালিকা রয়েছে । এখানে ধারণাটি হ'ল, ট্রানজিটিভ সম্পত্তি দ্বারা, যদি কোনও দুটি সেটের কমপক্ষে একটি উপাদান মিল থাকে তবে দুটি সেটের সমস্ত গ্রুপ isomorphic। এগুলিকে একক সেটে একত্রিত করা যায়। হিসাবে এল [X] হল দ্বারা উত্পন্ন সমন্বয় প্রদর্শিত হবে না এল [এক্স + ...] , isomorphisms প্রতিটি সেট সমষ্টি পর এক অনন্য উপাদান থাকবে। সুতরাং, আইসোমর্ফিজমের সংখ্যা পাওয়ার জন্য, সমস্ত সেট আইসমোরফিক গ্রুপে একবারে ঠিক কতগুলি গ্রুপ উপস্থিত হবে তা গণনা করা যথেষ্ট। এটি করার জন্য, আমি সেটগুলি আনপাট করি যাতে তারা [এল [0], ওয়াই 1, ওয়াই 2, ..., এল [1], ওয়াই 1, ...] এর মতো দেখতে একই গ্রুপের ক্লাস্টার তৈরি করতে তালিকাটি বাছাই করে এবং শেষ পর্যন্ত আরএলই-এনকোড করুন
:~ e# Unwrap sets of isomorphic groups
$ e# Sort list
e` e# RLE-encode list
{ }, e# Filter RLE elements:
0= e# Get number of occurrences
1= e# Keep element if occurrences == 1
, e# Push length of filtered list
e# This is the number of groups up to isomorphism
লোকেরা, সব।