चुनौती को चुनौती 1: सांता अपने वर्तमान तिजोरी को खोलने में मदद करें!


18

अगला >>

वर्णनात्मक कीवर्ड (खोज के लिए): दो मैट्रिक्स समतुल्य बनाएं, ओवरलैप, सरणी, खोजें

चुनौती

सांता का अतीत में अपनी तिजोरी से चोरी करने वाले कल्पित बौने का इतिहास रहा है, इसलिए इस साल उन्होंने एक ऐसा ताला डिजाइन किया, जिसे तोड़ना बहुत कठिन है, और ऐसा लगता है कि इस साल कल्पित बौने बाहर रहते हैं। दुर्भाग्य से, उसने संयोजन खो दिया है और वह यह पता नहीं लगा सकता है कि इसे कैसे खोलें! सौभाग्य से, उन्होंने संयोजन खोजने के लिए एक कार्यक्रम लिखने के लिए आपको काम पर रखा है। यह कम से कम एक होने की जरूरत नहीं है, लेकिन वह इसे जितनी जल्दी हो सके खोजने की जरूरत है!

उनका बहुत सख्त कार्यक्रम है और वह बहुत लंबे समय तक इंतजार नहीं कर सकते। आपका स्कोर स्कोरिंग इनपुट के लिए आपके प्रोग्राम के आउटपुट के चरणों की संख्या से गुणा आपके कार्यक्रम का कुल रन-टाइम होगा। सबसे कम स्कोर जीतता है।

विशेष विवरण

लॉक 1s और 0s का एक वर्ग मैट्रिक्स है। यह 1s और 0s की यादृच्छिक व्यवस्था के लिए सेट है और इसे एक निर्दिष्ट कोड पर सेट करना होगा। सौभाग्य से, सांता को आवश्यक कोड याद है।

वहाँ कुछ कदम वह प्रदर्शन कर सकते हैं। प्रत्येक चरण किसी भी सन्निहित उप-मैट्रिक्स पर किया जा सकता है (अर्थात, आपको एक उप-मैट्रिक्स का चयन करना होगा जो पूरी तरह से एक ऊपरी-बाएँ और नीचे-दाएं कोने से घिरा हुआ है) (यह एक गैर-वर्ग उप-मैट्रिक्स हो सकता है):

  1. दाएं घुमाएं 90 डिग्री *
  2. बाईं ओर 90 डिग्री घुमाएँ *
  3. 180 डिग्री घुमाएँ
  4. प्रत्येक पंक्ति nतत्वों को दाएं या बाएं चक्रित करें (लपेटें)
  5. प्रत्येक स्तंभ mतत्वों को ऊपर या नीचे (लपेटें)
  6. क्षैतिज फ्लिप
  7. ऊर्ध्वाधर रूप से पलटें
  8. मुख्य विकर्ण पर पलटें *
  9. मुख्य एंटी-विकर्ण पर पलटें *

* केवल अगर उप-मैट्रिक्स चौकोर है

बेशक, वह पूरे मैट्रिक्स पर इन चरणों का प्रदर्शन भी कर सकता है। चूँकि 1s और 0s को केवल मैट्रिक्स पर स्वैप किया जा सकता है, लेकिन एक वर्ग का मान सीधे बदला नहीं जा सकता है, 1s और 0s की संख्या प्रारंभ और अंत कॉन्फ़िगरेशन के लिए समान है।

स्वरूपण विनिर्देशों + नियम

आपको दो वर्ग मैट्रिसेस (शुरुआती स्थिति और समाप्ति की स्थिति) के रूप में इनपुट दिया जाएगा जो आप चाहते हैं किसी भी उचित प्रारूप में। आउटपुट किसी भी पठनीय प्रारूप में इन चरणों का एक क्रम होना चाहिए। चूंकि यह कोड-गोल्फ नहीं है, कृपया इसे आसानी से सत्यापित करने योग्य प्रारूप बनाएं, लेकिन यह एक सख्त आवश्यकता नहीं है। यदि आप चाहें तो मैट्रिसेस की साइड-लेंथ चुन सकते हैं।

आपका कार्यक्रम मेरे कंप्यूटर पर चलाया जाएगा (लिनक्स मिंट, अनुरोध पर उपलब्ध सटीक संस्करण विवरण यदि कोई भी परवाह करता है: पी) और मैं इसे कमांड लाइन पर "एन्टर" दबाने के बीच के समय की मात्रा के आधार पर और समय पर करूँगा कमांड से बाहर निकलता है।

परीक्षण के मामलों

1 0 0 1    0 0 0 0
0 1 1 0 -> 0 0 0 0
0 1 1 0 -> 1 1 1 1
1 0 0 1    1 1 1 1
  1. पूरी मैट्रिक्स लो। प्रत्येक कॉलम को 1 तक साइकिल चलाएं।
  2. एक उप-मैट्रिक्स के रूप में मध्य दो कॉलम लें। प्रत्येक कॉलम को नीचे 2 चक्र करें।
1 0 1 0 1    0 1 0 1 0
0 1 0 1 0    1 0 1 0 1
1 0 1 0 1 -> 0 1 1 1 0
0 1 0 1 0    1 0 1 0 1
1 0 1 0 1    0 1 0 1 0
  1. पूरी मैट्रिक्स लो। प्रत्येक कॉलम को नीचे 1 चक्र करें।
  2. बीच का कॉलम लें। इसे 2 चक्र करें।
  3. शीर्ष 2 पंक्तियों को लें। इसे लंबवत पलटें।
  4. शीर्ष पंक्ति के सबसे दाहिने 2 तत्वों को लें। उन्हें स्वैप करें (दाएं / बाएं 1 घुमाएं, क्षैतिज रूप से फ्लिप करें)।
  5. शीर्ष पंक्ति के सबसे बाएं 2 तत्वों को लें। उन्हें स्वैप करें।

अधिक कुशल तरीके हो सकते हैं, लेकिन इससे कोई फर्क नहीं पड़ता। अगर आपको एक मिल जाए तो बेझिझक उन्हें टिप्पणियों में इंगित करें :)

जजमेंट टेस्ट केस

इस परीक्षण मामले का उपयोग आपके सबमिशन को दर्शाने के लिए किया जाएगा। अगर मुझे लगता है कि परीक्षण के मामले के लिए एक जवाब बहुत अधिक विशेषज्ञता वाला है, तो मुझे एक यादृच्छिक इनपुट को दोहराने और नए मामले के साथ सभी उत्तरों को फिर से बताने का अधिकार है। परीक्षण का मामला यहां पाया जा सकता है जहां शीर्ष शुरू है और नीचे वांछित विन्यास है।

अगर मुझे लगता है कि उत्तर बहुत अधिक विशेषज्ञता वाले हैं, तो अगले परीक्षण मामले का एमडी 5 है 3c1007ebd4ea7f0a2a1f0254af204eed। (यह अभी अपने आप को धोखा देने के आरोपों से मुक्त करने के लिए यहाँ लिखा गया है: P)

स्टैंडर्ड लोफॉल्स लागू होते हैं। कोई उत्तर स्वीकार नहीं किया जाएगा। हैप्पी कोडिंग!

नोट: मैंने इस चुनौती श्रंखला के लिए Advent of Code से प्रेरणा ली । मेरा इस साइट से कोई जुड़ाव नहीं है

आप यहां पहली चुनौती के 'लिंक्ड' सेक्शन को देखकर श्रृंखला की सभी चुनौतियों की सूची देख सकते हैं ।


जानकारी: परीक्षण के मामले में 192 0और 64 है 1, और कुल 256 choose 64 ≈ 1.9 × 10⁶¹पहुंच योग्य मैट्रीस हैं। (जो एक मेगामिनक्स की तुलना में है, और एक रूबिक्स रिवेंज से बड़ा है, हालांकि प्रोफेसर के घन से बहुत कम है)
user202729

जवाबों:


1

जावा

import java.util.Arrays;

public class SantaMatrix4 {
	
	public static void flipV(int[][] matrix, int row1, int col1, int row2, int col2) {
		for (int row = row1; row <= (row2 - row1) / 2 + row1; row++) {
			for (int col = col1; col <= col2; col++) {
				int tmp = matrix[row][col];
				matrix[row][col] = matrix[row2 - row + row1][col];
				matrix[row2 - row + row1][col] = tmp;
			}
		}
	}
	
	public static void flipH(int[][] matrix, int row1, int col1, int row2, int col2) {
		for (int row = row1; row <= row2; row++) {
			for (int col = col1; col <= (col2 - col1) / 2 + col1; col++) {
				int tmp = matrix[row][col];
				matrix[row][col] = matrix[row][col2 - col + col1];
				matrix[row][col2 - col + col1] = tmp;
			}
		}
	}

	public static void main(String[] args) {
		int counter = 0;
		int n = Integer.parseInt(args[counter++]);
		int[][] matrix1 = new int[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				matrix1[i][j] = Integer.parseInt(args[counter++]);
			}
		}
				
		int[][] matrix2 = new int[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				matrix2[i][j] = Integer.parseInt(args[counter++]);
			}
		}
			
		int[] ops = new int[5 * matrix1.length * matrix1.length * 2];
		int numOps = 0;
		int opsI = 0;
		
		for (int row = 0; row < n; row++) {
			for (int col = 0; col < n; col++) {
				int goal = matrix2[row][col];
				boolean gotIt = false;
				
				//Look for required number to the right
				for (int i = row; i < n && !gotIt; i++) {
					for (int j = col; j < n && !gotIt; j++) {
						if (i == row && j == col) continue;
						if (matrix1[i][j] == goal) {
							flipH(matrix1, row, col, i, j);
							flipV(matrix1, row, col, i, j);
							ops[opsI++] = 1;
							ops[opsI++] = row;
							ops[opsI++] = col;
							ops[opsI++] = i;
							ops[opsI++] = j;
							numOps++;
							
							gotIt = true;
						}
					}
				}

				//Look for required number below and to the left
				for (int i = row + 1; i < n && !gotIt; i++) {
					for (int j = 0; j < col && !gotIt; j++) {
						if (matrix1[i][j] == goal) {
							flipH(matrix1, i, j, i, col);
							ops[opsI++] = 2;
							ops[opsI++] = i;
							ops[opsI++] = j;
							ops[opsI++] = i;
							ops[opsI++] = col;
							
							flipV(matrix1, row, col, i, col);
							ops[opsI++] = 3;
							ops[opsI++] = row;
							ops[opsI++] = col;
							ops[opsI++] = i;
							ops[opsI++] = col;
							
							numOps += 2;
							gotIt = true;
						}
					}
				}
				
			}
		}

		System.out.println(Arrays.toString(ops));
		System.out.println(numOps);
	}
}

थोड़ा तेज़ हार्ड-कोडेड संस्करण: इसे ऑनलाइन आज़माएं!

इनपुट कमांड लाइन के माध्यम से अंतरिक्ष अलग पूर्णांकों है। पहला पूर्णांक दो मैट्रिसेस की चौड़ाई है। शेष पूर्णांक उनके तत्व हैं, पंक्ति-दर-पंक्ति।

एक मैट्रिक्स का प्रत्येक क्रमांकन केवल क्षैतिज फ्लिप और ऊर्ध्वाधर फ्लिप ऑपरेटरों के साथ प्राप्त किया जा सकता है, इसलिए मैंने 180 डिग्री के रोटेशन के साथ एक ही क्षेत्र में लगातार vFlip और hFlip को बदलने के अलावा बाकी को अनदेखा किया।

कार्यक्रम प्रत्येक तत्व के माध्यम से स्कैन करता है। जब भी हम किसी ऐसे तत्व का सामना करते हैं जिसमें गलत बिट है, तो यह सही बिट के साथ एक स्पॉट खोजने के लिए सरणी के माध्यम से आगे दिखता है। मैंने खोज क्षेत्र को दो में विभाजित किया है: एक समान या बड़े स्तंभ समन्वय वाले, और एक छोटे स्तंभ समन्वय वाले। ध्यान दें कि उत्तरार्द्ध में एक बड़ी पंक्ति का समन्वय होना चाहिए, जिस तरह से हम सरणी को ट्रेस कर रहे हैं, उसके आधार पर। यदि हम पहले खोज क्षेत्र में एक सही बिट पाते हैं, तो हम केवल एक ऑपरेशन के लिए दो तत्वों को फैलाते हुए उप-मैट्रिक्स को 180 डिग्री तक घुमा सकते हैं। यदि यह दूसरे क्षेत्र में है, तो हम सही बिट को एक ही कॉलम में गलत बिट के रूप में स्थानांतरित करने के लिए एक क्षैतिज फ्लिप का उपयोग कर सकते हैं और फिर उप-मैट्रिक्स को कुल दो ऑपरेशनों के लिए दोनों को फैला सकते हैं।

कार्यक्रम का आउटपुट एक सरणी है जिसे मानसिक रूप से पांच के समूहों में विभाजित किया जाना चाहिए। प्रत्येक समूह (i, row1, col1, row2, col2) है जहां मैं 0 से एक नो-ऑप के लिए 1, 180 डिग्री से रोटेशन के लिए 1, क्षैतिज प्रवाह के लिए 2, और ऊर्ध्वाधर फ्लिप के लिए 3 है। शेष 4 घटक उस क्षेत्र का वर्णन करते हैं जिस पर ऑपरेशन चलता है। मुझे यकीन नहीं है कि यह एक पठनीय प्रारूप है।

दिए गए परीक्षण मामले के लिए, मुझे अपने कंप्यूटर पर 258 ऑपरेशन और दो से तीन मिलीसेकंड मिलते हैं।


@ आउटरीग्राफर का उपयोग करें यह निर्दिष्ट नहीं किया गया था, और हार्ड-कोडिंग से इसे न्याय करना आसान हो जाता है।
WhatToDo

मैंने इसे कमांड लाइन से इनपुट लेने के लिए बदल दिया है
WhatToDo

यह आउटपुट प्रारूप उचित है। मुझे सरणी में 1000 नंबर मिल रहे हैं (200 संचालन?) तो 258 कहाँ से आ रहा है? मैं इससे थोड़ा उलझन में हूं कि इस से आउटपुट कैसे पढ़ें: पी
हाइपरएनुट्रिनो

जब मैं इसे चलाता हूं, तो मुझे 1290 की लंबाई मिलती है (जब तक कि नो-ऑप्स शुरू न हो जाए), जो ऑपरेशन की संख्या का पांच गुना है। 258 सिर्फ संचालन की संख्या है।
WhatToDo
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.