2012-04-12 10 views
9

मेरे पास एक प्रोजेक्ट है जिसमें मुझे 3x1 और 4.5x1 वाले ब्लॉक से पैनल बनाना है। संरचनात्मक अखंडता के लिए, ब्लॉक के बीच की जगह आसन्न पंक्तियों में लाइन नहीं होनी चाहिए। मुझे सभी संभावित संयोजनों की गणना करनी है। कुछ उदाहरण हैं 7.5x1 पैनल में 2 संभावित समाधान हैं, 7.5x2 पैनल में 2 संभावित समाधान हैं, 12x3 पैनल में 4 संभावित तरीके हैं, और 27x5 में 7 9 58 संभावित तरीके हैं। मेरी समस्या यह है कि जब मैं उच्च चौड़ाई में उठता हूं तो मुझे और समाधान मिल रहे हैं तो मुझे चाहिए। मुझे लगता है कि इसके साथ ऐसा करना है कि मुझे एक संभावना है कि मुझे डुप्लिकेट टेबल मिल रहे हैं, लेकिन मैं नहीं देख सकता कि यह कहां हो रहा है या इसे कैसे ठीक किया जाए। किसी भी तरह की सहायता का स्वागत किया जाएगा। कोड नीचे आता है।ब्लॉक के साथ अद्वितीय पैनल संयोजन - जावा में कोड

import java.util.ArrayList; 
import java.util.List; 

import puzzle.Row; 

public class panel { 
/** 
* This program will return the number of unique tables that for structural  integrity don't have blocks that line up 
* in adjacent rows. The width is to be between 3 and 48 and the height between 1 and 10. The width 
* should also be a multiple of 0.5. 
* 
* @param width, height 
* @return totalTables 
*/ 
public static void main(String[] args) { 
    int width = 0; 
    int height = 0; 

    // Check to make sure that two arguments were passed. 
    if (args.length != 2) { 
     System.out.println("Please enter both a height and a width."); 
     System.exit(1); 
    } else { 
     // Check that a data type of double was entered. 
     if ((args[0].matches("^[0-9]+(\\.[0-9]+)?$")) && 
       (Double.valueOf(args[0].trim()).doubleValue() >= 3.0) && 
       (Double.valueOf(args[0].trim()).doubleValue() <= 48.0) && 
       (Double.valueOf(args[0].trim()).doubleValue()) % 0.5 == 0) { 
      width = (int) (Double.valueOf(args[0].trim()).doubleValue() * 2); // Double the width so that we are working with an integer. 
     } else { 
      System.out.println("Please enter a number for your width that is between 3 and 48 and divisable by 0.5."); 
      System.exit(1); 
     } 
     // Check that a data type of integer was entered. 
     if ((args[1].matches("^[0-9]+$")) && (Integer.valueOf(args[1]) >= 1) && (Integer.valueOf(args[1]) <= 10)) { 
      height = Integer.valueOf(args[1].trim()).intValue(); 
     } else { 
      System.out.println("Please enter an integer for your height that is between 1 and 10."); 
      System.exit(1); 
     } 

     List<Row> allRows = new ArrayList<Row>(); // Holds all the possible rows and needed information 
     findAllRows(width, 0, 0, allRows); 
     findMatches(allRows); 
     long totalTables = findUniqueTables(allRows, height); 
     System.out.println(totalTables); 
    } 
} 

/** 
* Recursively calculates all possible row combinations for supplied width. 
* Row configuration is stored in binary format with 1 indicating gaps. Each bit is 
* represented by 3 inches. The bits 1, 2, nth are dropped as they are not needed. 
* 
* i.e. width of 12 would produce 
* width = 12 * 2 = 24 
* 
* Bricks    Binary    Stored Binary Decimal Value 
* 6 x 6 x 6 x 6  0 1 0 1 0 1 0 1  1 0 1 0 1  21 
* 9 x 9 x 6   0 0 1 0 0 1 0 1  0 1 0 0 1  9 
* 9 x 6 x 9   0 0 1 0 1 0 0 1  0 1 0 1 0  10 
* 6 x 9 x 9   0 1 0 0 1 0 0 1  1 0 0 1 0  18 
*/ 

public static void findAllRows(int width, int currLen, int rowConfig, List<Row> root) { 
    if (currLen + 6 == width) { 
     root.add(new Row(width, rowConfig)); // Add current row configuration as an acceptable row. 
     return; 
    } else if (currLen + 9 == width) { 
     rowConfig = rowConfig << 1; 
     root.add(new Row(width, rowConfig)); // Add current row configuration as an acceptable row. 
     return; 
    } else if (currLen + 6 > width) { 
     return; // Current configuration is longer than the width is allowed. Do not add. 
    } else { 
     int nextConfig = (rowConfig << 2) + 1; // 
     findAllRows(width, currLen + 6, nextConfig, root); 

     nextConfig = (rowConfig << 3) + 1; 
     findAllRows(width, currLen + 9, nextConfig, root); 
    } 
    return; 
} 

/** 
* Finds all possible row matches for the given row that do not have gaps that line up. 
*/ 
public static void findMatches(List<Row> rows) { 
    for (Row row : rows) { 
     for (Row rowC : rows) { 
      if (matchesBelow(row.getGaps(), rowC.getGaps())) { 
       row.addChilcRows(rowC.getGaps()); 
      } 
     } 
    } 
} 

/** 
* Does a bitwise AND to see if there are any gaps that line up. If there are no gaps then 
* the resulting AND should equal to 0. 
*/ 
public static boolean matchesBelow(int row, int rows) { 
    if ((row & rows) == 0) { 
     return true; 
    } else { 
     return false; 
    } 
} 

/** 
* Finds all the unique tables and returns the count. 
*/ 
public static long findUniqueTables(List<Row> allRows, int height) { 
    long tableCount = 0; 
    for (Row row : allRows) { 
     tableCount += findTables(row, height); 
    } 
    return tableCount; 
} 


/** 
* This makes all possible tables. 
*/ 
public static long findTables(Row row, int tableHeight) { 
    long count; 
    if (tableHeight == 1) { 
     return 1; 
    } else { 
     count = 0; 
     for (int i = 0; i < row.getChildRowsSize(row); i++) { 
      count += findTables(row, tableHeight -1); 
     } 
    } 
    return count; 
} 
} 

और मेरे puzzle.Row वर्ग।

package puzzle; 

import java.util.ArrayList; 
import java.util.List; 

public class Row { 
int gaps; 
int width; 
List<Long> potChildRows = new ArrayList<Long>(); 

public Row(int width, int gaps) { 
    this.gaps = gaps; 
    this.width = width; 
} 

public int getGaps() { 
    return this.gaps; 
} 

public int getWidth() { 
    return this.width; 
} 

public long getChildRowsSize(Row row) { 
    return row.potChildRows.size(); 
} 

public void addChilcRows(long row) { 
    this.potChildRows.add(row); 
} 
} 
+1

आप एक मामले में जहां यह विफल रहता है प्रदान कर सकते हैं? क्या "27x5 में 7958 संभावित तरीके हैं" एक त्रुटि केस का प्रतिनिधित्व करता है? यदि हां, तो समाधान कौन सा होगा? यदि नहीं, तो क्या आप ऐसा मामला प्रदान कर सकते हैं जहां यह विफल हो जाए? उत्तर को पोस्ट न करने के लिए – Zecas

उत्तर

2

मुझे लगता है कि मैंने अभी असाइनमेंट हल किया है। हालांकि सवाल पूछने के दो महीने बाद, मैंने सोचा कि यह हल करने के लिए एक मजेदार समस्या की तरह दिख रहा है, इसलिए मैंने इसे एक शॉट दिया। मैं "होमवर्क" टैग (2 महीने के बाद भी) के कारण अपना कोड पोस्ट नहीं करना चाहता, इसलिए मैं बस अपने दृष्टिकोण का वर्णन करूंगा। मैंने पायथन का उपयोग किया, लेकिन मैं जावा में किसी भी शब्दावली का अनुवाद करने की कोशिश करूंगा।

सबसे पहले, मुझे लगता है कि आप की जरूरत से अधिक डेटा के रास्ते को ट्रैक कर रहे हैं। मैंने सिर्फ युगल के एक ऐरेलिस्ट को रखा है जैसे कि किसी भी डबल i, i को ix1 ब्लॉक में प्रस्तुत किया गया था। सूची का आदेश दिया गया था कि row[0] बाएं ब्लॉक था और row[row.length-1] सही ब्लॉक था। उदाहरण के लिए, [3, 3, 4.5] बाएं से दाएं, 3x1 ब्लॉक, एक और 3x1 ब्लॉक, और 4.5x1 ब्लॉक का उपयोग करके लंबाई 10.5 की एक पंक्ति को संदर्भित करता है। इस सरल संरचना का उपयोग करके मैं आसानी से अपनी कॉन्फ़िगरेशन को देख सकता हूं। मेरी पंक्ति लंबाई एक साथ सभी तत्वों को जोड़ने के रूप में आसान है (यानी 3 + 3 + 4.5 = 10.5)। मेरी अंतराल मेरी सूची के माध्यम से चलने के दौरान चलने वाले कुल को बनाए रखने जितनी आसान है (यानी मेरे अंतराल और 3 + 3 = 6 हैं)। इस सरल डेटाटाइप का उपयोग करके आप बहुत आसानी से अपना कोड कर सकते हैं।

इसके अलावा, मुझे समस्या के बारे में सोचने में मदद मिली Depth-First Search। डीएफएस का उपयोग करना और एक बाइनरी पेड़ दिया गया है, जो रूट से शुरू होता है, आप पहले बाएं जाने की कोशिश करते हैं। फिर आप सभी बाएं जाने की कोशिश करते हैं लेकिन एक अंतिम नोड। और इसी तरह। "बाएं" और "दाएं" के बजाय, "3" और "4.5" सोचें, जहां नोड का मान चौड़ाई है और चौड़ाई चौड़ाई से अधिक हो जाने के बाद आप पेड़ को घुमाने से रोकते हैं, width। यदि आपको width के मान के साथ नोड मिलता है, तो वह पथ अब एक संभावित पंक्ति है, याद रखें। दूसरे शब्दों में, आप अपनी पंक्तियों को पहले एन 3x1 ब्लॉक (जैसे कि width + 2.5 >= N*3 >= width) की कोशिश कर रहे हैं। फिर आप (एन -1) 3x1 ब्लॉक और 1 4x1 ब्लॉक (4x1 सबसे सही होने का प्रयास करें) आज़माएं। फिर (एन -2) 3x1s, एक 4x1, और एक और 3x1। और इसी तरह। कोई बिट्सफिफ्ट नहीं, rowConfig वैरिएबल, ब्लॉक चौड़ाई के केवल एक ऐरेलिस्ट। इसके अलावा, चूंकि आप व्यवस्थित प्रत्येक पथ (यानी प्रत्येक संयोजन की कोशिश करते हैं) एक बार और केवल एक बार यात्रा करते हैं, आप जानते हैं कि आपने प्रत्येक संयोजन की कोशिश की है और आप जानते हैं कि कोई डुप्लिकेट नहीं है।

अब, अपनी दीवार का निर्माण। इसे एक संशोधित डीएफएस के रूप में भी माना जा सकता है। एक एन-आरी पेड़ की कल्पना करें जहां एन चौड़ाई width की संभावित पंक्तियों की संख्या के बराबर है। उसी, व्यवस्थित दृष्टिकोण का उपयोग करके, जब तक आपके पास ऊंचाई की दीवार न हो, तब तक प्रत्येक पथ को आजमाएं height (चूंकि प्रत्येक पंक्ति ऊंचाई 1 है)। लेकिन याद रखें, यदि आप अंतराल में से कोई भी निकट नहीं हैं तो आप केवल पथ को पार करना चाहते हैं। नीचे से नीचे, एक समय में दीवार को एक पंक्ति बनाने का प्रयास करें। दीवार के शीर्ष पर एक नई पंक्ति जोड़कर यदि केवल और यदि कोई भी अंतराल शीर्ष पंक्ति में अंतराल के निकट नहीं है, तो आप भरोसा कर सकते हैं कि आपकी आंशिक दीवार हमेशा वैध है। वहां, एक बार जब आप height पर जाते हैं, तो आप जानते हैं कि आपके पास वैध दीवार है। पथ रिकॉर्ड करें और तब तक जारी रखें जब तक कि कोई और वैध पथ अन्वेषण करने के लिए छोड़ा न जाए।

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

+0

+1 क्योंकि इसे 'होमवर्क' के रूप में टैग किया गया था :) – kentcdodds

संबंधित मुद्दे