Magisches Quadrat (Simulationen)
Gegeben sind die folgenden neun Spielkarten eines Poker-Sets:
- Herz As (1), Herz 2 und Herz 3
- Pik As (1), Pik 2 und Pik 3
- Karo As (1), Karo 2 und Karo 3
Schreiben Sie ein Programm, das die Karten in einem Quadrat (drei Zeilen à je drei Spalten) so anordnet, dass in jeder Zeile und in jeder Spalte jede Farbe, aber auch jede Zahl einmal vorkommt.
- Geben Sie eine Lösung aus.
- Wie viele Lösungen sind es insgesamt?
0 Kommentare
5 Lösung(en)
public class MagischesQuadrat {
public static void main(String[] args) {
new MagischesQuadrat().top();
}
int[] alleKarten;
int totalMoeglichkeiten = 0;
Permutationen p = new Permutationen();
void top() {
alleKarten = new int[] {11,12,13,21,22,23,31,32,33};
test();
while(p.hatNaechstePermutation(alleKarten)) {
p.naechstePermutation(alleKarten);
test();
}
System.out.println("Total: " + totalMoeglichkeiten + " Möglichkeiten.");
}
void test() {
if(istMagisch()) {
ausgabeUndZaehlen();
}
}
void ausgabeUndZaehlen() {
System.out.println("\n");
int i = 0;
while (i < alleKarten.length) {
System.out.print(alleKarten[i] + " ");
if(0 == (i + 1) % 3) {
System.out.println();
}
i = i + 1;
}
totalMoeglichkeiten = totalMoeglichkeiten + 1;
}
int[][] testMengen = {
// Zeilen:
{ 0, 1, 2},
{ 3, 4, 5},
{ 6, 7, 8},
// Spalten:
{ 0, 3, 6},
{ 1, 4, 7},
{ 2, 5, 8}
};
boolean istMagisch() {
int aktuelleTestMengenNummer = 0;
while(aktuelleTestMengenNummer < testMengen.length) {
if(! istOkTstMenge(testMengen[aktuelleTestMengenNummer])) {
return false;
}
aktuelleTestMengenNummer = aktuelleTestMengenNummer + 1;
}
return true;
}
boolean istOkTstMenge(int[] testMengenIndizes) {
if(kommtVor( 1, testMengenIndizes) &&
kommtVor( 2, testMengenIndizes) &&
kommtVor( 3, testMengenIndizes) &&
kommtVor(10, testMengenIndizes) &&
kommtVor(20, testMengenIndizes) &&
kommtVor(30, testMengenIndizes)) {
return true;
}
return false;
}
boolean kommtVor(int zahl, int[] testMengeIndizes) {
if(zahl < 10) {
int pos = 0;
while(pos < testMengeIndizes.length) {
if(alleKarten[testMengeIndizes[pos]] % 10 == zahl) {
return true;
}
pos = pos + 1;
}
return false;
}
// Zehner
int pos = 0;
while(pos < testMengeIndizes.length) {
if(alleKarten[testMengeIndizes[pos]] / 10 == zahl / 10) {
return true;
}
pos = pos + 1;
}
return false;
}
} // end of class MagischesQuadrat
import java.util.Arrays;
public class Permutationen {
public static void main(String args []) {
new Permutationen().test();
}
void test() {
// Initialpermutation muss aufsteigend sein.
int permut[] = {1, 3, 4, 6, 9};
ausgabe(permut);
while(naechstePermutation(permut)) {
ausgabe(permut);
}
}
void ausgabe(int [] arr) {
for(int val : arr) {
System.out.print(val + "");
}
System.out.println();
}
public boolean hatNaechstePermutation(int [] permutation) {
int aktPos = permutation.length - 1;
while(aktPos > 0) {
if(permutation[aktPos - 1] < permutation[aktPos]) {
return true;
}
aktPos = aktPos - 1;
}
return false;
}
/**
* Suche numerisch die nächstgrößere Permutation
* @return false, wenn es bereits die letzte Permutation war.
*/
public boolean naechstePermutation(int[] permutation) {
int aktPos = permutation.length - 1;
while(aktPos > 0) {
if(permutation[aktPos - 1] < permutation[aktPos]) {
neuOrdnen(permutation, aktPos - 1);
return true;
}
aktPos = aktPos - 1;
}
return false;
}
/**
* Beispiel: 123956874
* Eingabe startPosition: Gegeben ist die Startposition, wo zum ersten mal "<" auftaucht.
* Im Beispiel die Position, wo die "6" steht: 123956<8>7>4
*
* 1. Finde den minimalen Tauschpartner:
* Nennen wir die Zahl an position "startPosition" kurz "startWert".
* (in Obigem beispiel: StartWert = 6)
* Der Tauschpartner ist die kleinset Zahl rechts der startPosition, die aber größer als der
* startWert ist. (im Beispiel 7)
* Die Position, wo die "7" steht, nennen wir "naechstesfureStartPos".
* 2. Tausche "7" mit "6".
* 3. Sortiere ab >startPos aufsteigend.
*
*/
void neuOrdnen(int[] permutation, int startPosition) {
int naechstesFuerStartPos = findeMinimalenTauschpartner(permutation, startPosition);
tausche(permutation, startPosition, naechstesFuerStartPos);
sortiereAb(permutation, startPosition + 1);
}
/**
* Ab "startPosition" soll aufsteigend sortiert werden.
* @param permutation
* @param startPosition
*/
void sortiereAb(int[] permutation, int startPosition) {
Arrays.sort(permutation, startPosition, permutation.length);
}
void tausche(int[] permutation, int a, int b) {
int temp = permutation[a];
permutation[a] = permutation[b];
permutation[b] = temp;
}
/**
* Siehe doku "neuOrdnen()"
*/
int findeMinimalenTauschpartner(int[] permutation, int referenzPosition) {
int referenzWert = permutation[referenzPosition];
int min = Integer.MAX_VALUE; // next
int minPos = -1;
int i = referenzPosition + 1;
while(i < permutation.length)
{
int actValue = permutation[i];
if(min > actValue && actValue > referenzWert) {
min = actValue;
minPos = i;
}
i = i + 1;
}
return minPos;
}
} // end of class Permutationen
function permute(permutation) {
let length = permutation.length,
result = [permutation.slice()],
c = new Array(length).fill(0),
i = 1, k, p;
while (i < length) {
if (c[i] < i) {
k = i % 2 && c[i];
p = permutation[i];
permutation[i] = permutation[k];
permutation[k] = p;
++c[i];
i = 1;
result.push(permutation.slice());
} else {
c[i] = 0;
++i;
}
}
return result;
}
function isMagicSquare(sq) {
let rows = [
[sq[0], sq[1], sq[2]],
[sq[3], sq[4], sq[5]],
[sq[6], sq[7], sq[8]],
[sq[0], sq[3], sq[6]],
[sq[1], sq[4], sq[7]],
[sq[2], sq[5], sq[8]]
];
for (let i = 0; i < rows.length; i++) {
let f1 = rows[i][0][0], l1 = rows[i][0][1],
f2 = rows[i][1][0], l2 = rows[i][1][1],
f3 = rows[i][2][0], l3 = rows[i][2][1];
if ( (f1 === f2) || (f1 === f3) || (f2 === f3) ) return false;
if ( (l1 === l2) || (l1 === l3) || (l2 === l3) ) return false;
}
return true;
}
let deck = ['?A', '?2', '?3', '?A', '?2', '?3', '?A', '?2', '?3'],
perms = permute(deck),
magSquares = [];
for (let i = 0; i < perms.length; i++)
if (isMagicSquare(perms[i])) magSquares.push(perms[i]);
/* ausgabe */
let rSquare = magSquares[Math.floor(Math.random() * magSquares.length)];
document.write(`
<table>
<tr><td>${rSquare[0]}</td><td>${rSquare[1]}</td><td>${rSquare[2]}</td></tr>
<tr><td>${rSquare[3]}</td><td>${rSquare[4]}</td><td>${rSquare[5]}</td></tr>
<tr><td>${rSquare[6]}</td><td>${rSquare[7]}</td><td>${rSquare[8]}</td></tr>
</table>
<p>Anzahl der Lösungen: <b>${magSquares.length}</b></p>
`);
Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)
// NET 6.x | C# 10.x | VS-2022
var lstCards = new List<string> { "HA", "H2", "H3", "PA", "P2", "P3", "KA", "K2", "K3" };
static IEnumerable<IEnumerable<T>> GetPermutations<T>(IEnumerable<T> lst, int len) {
if (len == 1) return lst.Select(x => new T[] { x });
return GetPermutations(lst, len - 1).SelectMany(x => lst.Where(y => !x.Contains(y)), (t1, t2) => t1.Concat(new T[] { t2 }));
}
static bool EqualsOr(char a, char b, char c) => a == b || b == c || c == a;
var counter = 0;
foreach (var p in GetPermutations(lstCards, lstCards.Count).ToList()) {
var c = p.ToList();
var d = false;
for (int i = 0; i < 3; i++) {
if (EqualsOr(c[i][0], c[i + 3][0], c[i + 6][0])) { d = true; break; };
if (EqualsOr(c[i][1], c[i + 3][1], c[i + 6][1])) { d = true; break; };
if (EqualsOr(c[i * 3][0], c[i * 3 + 1][0], c[i * 3 + 2][0])) { d = true; break; };
if (EqualsOr(c[i * 3][1], c[i * 3 + 1][1], c[i * 3 + 2][1])) { d = true; break; };
}
if (!d) {
counter++;
for (int i = 0; i < 3; i++)
Console.WriteLine($"{c[i]} {c[i + 3]} {c[i + 6]}");
Console.WriteLine();
}
}
Console.WriteLine($"Anzahl magischer Quadrate: {counter}");
Lösung von: Jens Kelm (@JKooP)
// C++ 17
#include <iostream>
#include <vector>
#include <algorithm>
bool equals_or(char a, char b, char c) { return a == b || b == c || c == a; }
int main() {
std::vector<std::string> v { "HA", "H2", "H3", "PA", "P2", "P3", "KA", "K2", "K3" };
auto counter{ 0 };
std::sort(v.begin(), v.end());
do {
auto d = false;
for (size_t i{ 0 }; i < 3; i++) {
if (equals_or(v[i][0], v[i + 3][0], v[i + 6][0])) { d = true; break; };
if (equals_or(v[i][1], v[i + 3][1], v[i + 6][1])) { d = true; break; };
if (equals_or(v[i * 3][0], v[i * 3 + 1][0], v[i * 3 + 2][0])) { d = true; break; };
if (equals_or(v[i * 3][1], v[i * 3 + 1][1], v[i * 3 + 2][1])) { d = true; break; };
}
if (!d) {
counter++;
for (size_t i{ 0 }; i < 3; i++)
std::cout << v[i] << " " << v[i + 3] << " " << v[i + 6] << '\n';
std::cout << '\n';
}
} while (std::next_permutation(v.begin(), v.end()));
std::cout << counter << "\n";
}
Lösung von: Jens Kelm (@JKooP)
// NET 6.x | C# 10.x | VS-2022
// Permutation 'inline' und ohne LINQ
bool EqualsOr(char a, char b, char c) => a == b || b == c || c == a;
var counter = 0;
void GetPermutations(List<string> lst, int k, int m) {
if (k == m) {
var d = false;
for (int i = 0; i < 3; i++) {
if (EqualsOr(lst[i][0], lst[i + 3][0], lst[i + 6][0])) { d = true; break; };
if (EqualsOr(lst[i][1], lst[i + 3][1], lst[i + 6][1])) { d = true; break; };
if (EqualsOr(lst[i * 3][0], lst[i * 3 + 1][0], lst[i * 3 + 2][0])) { d = true; break; };
if (EqualsOr(lst[i * 3][1], lst[i * 3 + 1][1], lst[i * 3 + 2][1])) { d = true; break; };
}
if (!d) {
counter++;
for (int i = 0; i < 3; i++)
Console.WriteLine($"{lst[i]} {lst[i + 3]} {lst[i + 6]}");
Console.WriteLine();
}
}
else
for (int i = k; i <= m; i++) {
(lst[k], lst[i]) = (lst[i], lst[k]);
GetPermutations(lst, k + 1, m);
(lst[k], lst[i]) = (lst[i], lst[k]);
}
}
var arr = new List<string> { "HA", "H2", "H3", "PA", "P2", "P3", "KA", "K2", "K3" };
GetPermutations(arr, 0, arr.Count - 1);
Console.WriteLine($"Anzahl magischer Quadrate: {counter}");
Lösung von: Jens Kelm (@JKooP)
Verifikation/Checksumme:
Es sind insgesamt 72 Möglichkeiten.
Aktionen
Neue Lösung hinzufügen
Bewertung
Durchschnittliche Bewertung:
Meta
Zeit: | 2 |
Schwierigkeit: | k.A. |
Webcode: | cmi5-4vwv |
Autor: | Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch) |