Geht dieser Code noch einfacher?

petepetepete

Mitglied
Servus zusammen!

Also, ich hab eine Class "Carpet" geschrieben, die mir für 3 selbstzubestimmende Int-Variablen ein Teppichmuster mit den Zeichen "." und "#" ausgibt.
z.B.: java Carpet 4 3 1 gibt aus:

. . . . ####. . . .
. . . . ####. . . .
. . . . ####. . . .
. . . . ####. . . .
####. . . . ####
####. . . . ####
####. . . . ####
####. . . . ####
. . . . ####. . . .
. . . . ####. . . .
. . . . ####. . . .
. . . . ####. . . .

Variable 1 (hier mit dem Wert 4): Anzahl der Elemente (Länge und Breite) eines Punkt- bzw. Rautequaders
Variable 2 (hier mit dem Wert 3): Anzahl der Quader für die Länge und Breite des "Teppiches"
Variable 3 (hier mit dem Wert 1): Mit welchem Muster beginnt das Feld (0 = Raute / 1 = Punkt)

Jetzt geht das Programm folgendermaßen vor:

Es zeichnet mir die erste Zeile mit dem ersten Muster (hier: Punkte).
Dann zeichnet es mir die erste Zeile mit dem zweiten Muster (hier: Raute)
Dies geschieht in EINER for-Schleife. Danach wird die komplette erste Zeile nach unten entsprechend den eingegebenen Variablen vervielfältigt (alles mit for-Schleifen).
Jetzt muss ich natürlich die erste Zeile zuvor halbieren, da ich sonst am Ende doppelt so viele Quader in der Breite hab wie gewollt. (Das liegt daran, dass die ersten beide Schritte wie bereits erwähnt in EINER for-Schleife laufen).
Halbiere ich jedoch Int-Variablen, die ungerade sind, sprich wie im obigen Beispiel "3", so kriege ich nur einen Quader in die Breite (int 3/2 = 1). Deshalb lasse ich noch per Modulo-Rechnung auf eine eventuell ungerade Quader-Anzahl prüfen und hänge dann dementprechend diese fehlenden Quader an.
Am Ende wird noch ein Absatz gemacht und das Muster nach jeder vollständigen Quader-Reihe verschachtelt (quasi wie ein Schachbrett).
Jetzt ist die eigentliche Frage:
Wie kann ich diesen Code derart vereinfachen, dass ich höchsten 2 bis 3 for-Schleifen verwende und alles auch mit einer ungeraden Quader-Anzahl funktioniert? Das Programm an sich funktioniert ja perfekt, aber geht es auch einfacher?

Hier der Code:

Java:
public class Carpet {

	public static void main(String args[]){

		//einzugebende Variablen
		int lengthQuad = Integer.parseInt(args[0]);
		int amountQuad = Integer.parseInt(args[1]);
		int pattern = Integer.parseInt(args[2]);
		//fortlaufende Zahlen
		int n_0;
		int n_1;
		int n_2;
		int n_3;
		int n_4;
		int n_5;
		int n_6;
		//Teppichmuster-Variablen
		String cross = "#";
		String dot = ".";

		//vervielfältigt erste Quader-Reihe nach unten
		for(n_0 = 1; n_0 <= amountQuad; n_0++){
			//komplette erste Quader-Reihe
			for(n_1 = 1; n_1 <= lengthQuad; n_1++){
				for(n_2 = 1; n_2 <= amountQuad/2; n_2++){
					//Muster A erste Zeile
					for(n_3 = 1; n_3 <= lengthQuad; n_3++){
					
						if(pattern == 0){
							System.out.print(cross);
						}
						else if(pattern == 1){
							System.out.print(dot);
						}
					}

					//Muster B erste Zeile
					for(n_4 = 1; n_4 <= lengthQuad; n_4++){

						if(pattern == 0){
							System.out.print(dot);
						}
						else if(pattern == 1){
							System.out.print(cross);
						}
					}
				}

				//falls Quader-Anzahl ungerade: vervollständigen der ersten Zeile
				for(n_5 = 1; n_5 <= lengthQuad; n_5++){

					if(pattern == 0 && amountQuad%2 == 1){
						System.out.print(cross);
					}
				}

				for(n_6 = 1; n_6 <= lengthQuad; n_6++){

					if(pattern == 1 && amountQuad%2 == 1){
						System.out.print(dot);
					}
				}
				//Absatz nach jeder Zeile
				System.out.println("");
			}
			//verschachteln des Musters
			if(pattern == 0){

				pattern = 1;

			}
			else if(pattern == 1){

				pattern = 0;

			}
		}

	}

}

Vielen Dank schonmal!
Ich hoffe ich hab hier niemanden mit so viel Text erschlagen😀
 
Zuletzt bearbeitet:
Wie wärs hiermit?
Java:
	public static void main(String[] args) {
		printCarpet(4, 3, ".", "#");
	}

	public static void printCarpet(int squareSize, int squareCnt, String squareCharacter1, String squareCharacter2) {
		String squareLine1 = multiplyString(squareCharacter1, squareSize);
		String squareLine2 = multiplyString(squareCharacter2, squareSize);

		for(int i=0;i<squareCnt*squareSize;++i) {
			for(int e=0;e<squareCnt;++e) {
				if((i/squareSize)%2==0 != (e%2==0)) {
					System.out.print(squareLine2);
				}
				else {
					System.out.print(squareLine1);
				}
			}
			System.out.println();
		}
	}

	public static String multiplyString(String s, int cnt) {
		StringBuilder result = new StringBuilder();
		for(int i=0;i<cnt;++i) {
			result.append(s);
		}
		return result.toString();
	}
könnte man natürlich auf viel weniger Zeilen kürzen wenn man es weniger leserlich machen will, fänd ich aber nicht so sinnvoll.

EDIT: fixed size
 
Zuletzt bearbeitet:
Einfacher ist immer relativ... kürzer gehts...
Java:
public class Test {
	public static void main(String[] args) {
		printCarpet(4, 3, 1);
	}

	public static void printCarpet(int squareLength, int numSqares, int patternStart) {
		for (int i = 0; i < squareLength * numSqares; i++) {
			for (int j = 0; j < squareLength * numSqares; j++) {
				System.out.print(((((j / squareLength) % 2 + (i / squareLength) % 2) + patternStart) % 2 == 0) ? '.' : '#');
			}
			System.out.println();
		}
	}
}

kann man zwar nicht lesen und nicht warten... aber naja ;-)
 
bzw man kanns ja noch etwas vereinfachen...

Java:
public class Test {
	public static void main(String[] args) {
		printCarpet(4, 3, 0);
	}

	public static void printCarpet(int squareLength, int numSqares, int patternStart) {
		for (int line = 0; line < squareLength * numSqares; line++) {

			int linePattern = (line / squareLength);

			for (int col = 0; col < squareLength * numSqares; col++) {

				int colPattern = (col / squareLength);
				int pattern = linePattern + colPattern + patternStart;
				System.out.print(pattern % 2 == 0 ? '.' : '#');
			}
			System.out.println();
		}
	}
}
 
Oder in einer einzigen Schleife
Java:
public class Carpet {
  public static void main(String[] args){
    paint(3,3,".","#");
    System.out.println("-----------------------------");
    paint(3,4,".","#");
    System.out.println("-----------------------------");
    paint(4,3,".","#");
    System.out.println("-----------------------------");
    paint(4,4,".","#");
    System.out.println("-----------------------------");
  }

  public static void paint(int x, int y, String a, String b){
    for(int i = 0; i< (x*x*y*y); i++){
      if(i>= 0 && i % (x*y) == 0){
        System.out.println();
      }
      if( ((y%2 == 1) && ((i/x)+(i/(x*y*x))) % 2 ==  (i/(x*y))% 2) || (y%2 == 0 && ((i/x) % 2 ==  (i/(x*x*y)) % 2 ))){
        System.out.print(a);
      } else {
        System.out.print(b);
      }
    }
  }
}
 
Java:
public class Carpet
{
    public static void main(String[] args) 
    {
        printCarpet(4, 3, 0);
    }
    static void printCarpet(int s,int n,int p){System.out.println(_(s,n,p,0,0))
    ;}static String _(int í,int î,int l,int ì,int i){return i==í*î?"":ì==í*î?
    "\n"+_(í,î,l,0,i+1):((i/í+ì/í+l)%2==0?'.':'#')+_(í,î,l,ì+1,i);}
}
:smoke: :joke:
 
Wow! Vielen Dank für die unglaublich schnellen Antworten!
Das Problem ist, ich bin noch nicht soweit in Java und kenne gleich einen ganzen Haufen der Befehle nicht, die hier zur Sprache kommen^^. Ich mach das hier für den Unterricht und "kann" egtl. nach "Klassenniveau" gerichtet keine anderen Sachen wie oben in meinem Code verwenden (auch noch keine Funktionen). Aber ich werd jetzt erstmal versuchen die Antworten zu verstehen und dann schau ma mal.

Danke nochmal!
 
Zuletzt bearbeitet:
[JAVA=18]if( ((y%2 == 1) && ((i/x)+(i/(x*y*x))) % 2 == (i/(x*y))% 2) || (y%2 == 0 && ((i/x) % 2 == (i/(x*x*y)) % 2 )))[/code]

Findet ihr das denn nicht ein bisschen strange?

Das KSKB von Marco benutzt die gefährlich String-Konkatenation^^ u. Rekursion, auch gefährlich^^

Ich hätte das vielleicht mit 3 For s geschrieben, dann ist es auch leichter zugänglich. Beispiel folgt gleich.

Edit: Hier mit 4 for s:
Java:
    public static void main(String[] args) {
        char c = '.';
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 4; j++) {
                for (int k = 0; k < 4; k++) {
                    for (int l = 0; l < 4; l++) {
                        System.out.print(c);
                    }
                    c = c == '.' ? '#' : '.';
                }
                System.out.println();
            }
            c = c == '.' ? '#' : '.';
        }
    }
 
Zuletzt bearbeitet von einem Moderator:
Ja, nochmal ernsthaft-pragmatisch (und (@hüteüberhüte) ohne die Anzahl der for-Schleifen zu erhöhen - im Gegensatz zum verringern gibt's da nämlich kaum eine Grenze :bae: ) : Ein Aspekt, der mit der Frage verbunden sein könnte (bzw. der Teil der Intention des Aufgabenstellers sein könnte, wenn er sagt, dass sowas z.B. nur mit 2 for-Schleifen gelöst werden soll - der aber auch in "Real-World-Zusammenhängen" öfter mal auftritt) könnte sein, dass man aus einer Position (Zeile, Spalte) ausrechnen muss, wo man sich gerade befindet - in zwar in bezug auf ein vordefiniertes Gitter. Ich denke da an sowas wie ein Schachbrett, das man mit n*n Pixeln großen Feldern in ein Fenster malt, und bei dem man dann anhand der Mausposition (x,y) rausfinden will, ob die Maus gerade über einem schwarzen oder einem weißen Feld ist. Vielleicht ging es aber wirklich nur darum, dass man nicht 4 Schleifen verwenden sollte, bei denen die Äußeren beiden das "Grobe" Gitter malen, und die beiden inneren jeweils ein Feld... :bahnhof:
 
Java:
public class Test {
    public static void main(String[] args) {
        printCarpet(4, 3, 0);
    }
 
    public static void printCarpet(int squareLength, int numSqares, int patternStart) {
        for (int line = 0; line < squareLength * numSqares; line++) {
 
            int linePattern = (line / squareLength);
 
            for (int col = 0; col < squareLength * numSqares; col++) {
 
                int colPattern = (col / squareLength);
                int pattern = linePattern + colPattern + patternStart;
                System.out.print(pattern % 2 == 0 ? '.' : '#');
            }
            System.out.println();
        }
    }
}

@ARadauer: Könntest du mir diesen Code Schritt für Schritt erklären? Vor allem diese Form: System.out.print(pattern % 2 == 0 ? '.' : '#');
Wofür stehen die neuen Variablen (z.B. col, colPattern, linePattern)?
 
Zuletzt bearbeitet:
Ah OK. Aber hier steht jetzt ein Modulo und kein Gleichzeichen... ich dachte, das bei diesem Ternären Operator das x und das y nicht miteinader verrechnet werden. Könntest du für mich den Ausdruck von ARadauer in eine if-else Schleife übersetzen?

Würde das so aussehen? (mit x y)
Java:
int x = 0;

if(x%2 == 0) {
  x = 0;
}
else {
  x = 1;
}

[OT]Wahnsinn wie schnell man hier Antworten kriegt:applaus:[/OT]
 
Zuletzt bearbeitet:
Java:
public class Carpet
{
    public static void main(String[] args) 
    {
        printCarpet(4, 3, 0);
    }
    static void printCarpet(int s,int n,int p){System.out.println(_(s,n,p,0,0))
    ;}static String _(int í,int î,int l,int ì,int i){return i==í*î?"":ì==í*î?
    "\n"+_(í,î,l,0,i+1):((i/í+ì/í+l)%2==0?'.':'#')+_(í,î,l,ì+1,i);}
}
:smoke: :joke:

Haha sehr geil, grenzt schon fast an trolling auf hohem level XD

Man könnte noch die printCarpet sparen und das ganze über args der main Methode machen ^^ sind nochmal 2 Zeilen drinnen XD
 
@Empire Phoenix: :lol: wer schickt dem Anfänger den am schwersten zu verstehenden, ABER kürzesten Code^^.

Also ich bin jetzt durch den Post von Marco13 durchgestiegen und habs endlich gepeilt. Das ist genau das was ich gebraucht hab! Vielen Dank an alle die mitgemacht haben ich liebe dieses Forum schon jetzt!:applaus:

Ciao zusammen!:meld:
 
Würde das so aussehen? (mit x y)
Java:
int x = 0;

if(x%2 == 0) {
  x = 0;
}
else {
  x = 1;
}

mhn fast... dieser operator erlaubt dir eine if als funktion zu benutzen die etwas zurück gibt

System.out.print(pattern % 2 == 0 ? '.' : '#');
entspricht...

Java:
    ...
    System.out.print( getZeichen(pattern));
    
    ...
    public char getZeichen(int pattern){
        if(pattern % 2 == 0){ // wenn der rest aus der division mit 2 gleich 0 ist -> zahl ist gerade
            return '.';
        }else{
            return '#';
        }
    }
 
Also, wenn einfacher bedeutet möglichst auf Schleifen, verschachtelte Schleifen oder gar Rekursion zu verzichten, dann kann ich noch eins draufsetzen.😀

Java:
public class Carpet {
	public static void main(String[] args) {
		int squareLength = 5;
		int patternLength = 4;
		int mode = 1;
		
		String even = genPattern(squareLength,"xy");
		String odd = swap(even);
		
		String patternX = genPattern(patternLength, mode==0?".":"#");
		String patternY = genPattern(patternLength, mode==0?"#":".");
		
		even = replace(even, "x", patternX, "y", patternY);
		odd = replace(odd, "x", patternX, "y", patternY);		
		
		String lines = genPattern(squareLength, "xy");
		lines = replace(lines, "x", genPattern(patternLength, "x"), "y", genPattern(patternLength, "y"));
		
		lines = replace(lines, "x", even+"\n", "y", odd+"\n");
		
		System.out.println(lines);
	}
	
	private static String replace(String s, String p1, String r1, String p2, String r2) {
		String result = s;
		result = result.replaceAll(p1, r1);
		result = result.replaceAll(p2, r2);
		return result;
	}

	public static String genPattern(int size, String pattern) {
		if (size % pattern.length() == 0) {
			return String.format("%" + (size / pattern.length()) + "s", "").replaceAll(" ", pattern);
		} else {
			return String.format("%" + (size / pattern.length()) + "s", "").replaceAll(" ", pattern) + pattern.charAt(0);
		}
	}
	
	public static String swap(String pattern){
		String result = pattern;
		result = result.replaceAll("x", "z");
		result = result.replaceAll("y", "x");
		result = result.replaceAll("z", "y");
		return result;	
	}
}
 

Zurück
Oben