Gyakorlati alapok
Virtuális kerékpárzár-feltörés
Mindenki látott már számkombinációs kerékpárzárat. Van 3 számos...
...4 számos...
...sőt 5 számos változata is:
A zár lényege, hogy nyitókulcsként be kell állítanunk egy titkos számkombinációt, amelyet meg is kell jegyeznünk. A zár bezárása azt jelenti, hogy eltekerjük a számtárcsákat és csakis akkor tudjuk kinyitni, ha a számtárcsákon beállítottuk a nyitókulcs titkos számkombinációját.
A kerékpárzár Nagy Sándor-stílusban (emlékezzünk vissza híres esetére a gordiuszi csomóval)...
...elegánsan feltörhető 1 db óriási vágóollóval...
...amelyet profi biciklitolvajok szoktak spontán viselni kabátjuk alatt. Ebben a fejezetben ezt a mozdulatot nem tudjuk modellezni (bár ha lecsapjuk a kinti biztosítékot, akkor gépünkön szintén valami hasonlóan erőszakfélét követünk el), helyette írunk egy olyan Java-programot, amelyben tetszőleges ideig találgathatunk a számkombinációk között, hogy eltaláljuk a nyitókulcs számkombinációját.
Először arra gondoltam, hogy a tetszőleges ideig való találgatást végtelen ciklussal oldom meg...
...ám ez programozás-technikailag enyhén szólva nem volna elegáns megoldás.
Marad tehát az, ami az oktatási módszertan jelenlegi szintjén megengedhető és megvalósítható:
-
előzetes adatbekérés, miszerint a felhasználó hány elemű számkombinációt (értsd: kerékpárzárat) szeretne találgatni (3-4-5),
-
előzetes adatbekérés, miszerint a felhasználó hány körben szeretne találgatni (1 és 2000000 között),
-
titkos számkombináció generálása véletlenszámok segítségével,
-
a fentiek alapszintű bemeneti ellenőrzése,
-
a találgatási körök lefuttatása és minden kör végén ellenőrzés.
A kód legfontosabb megoldandó problémája, hogy a számkombinációt nem generálhatjuk egyszerű int típusú számként, mert a véletlenszám-generátor sohasem fog generálni például ilyen számkombinációt: 002. Következésképpen a titkos számkombinációt számjegyenként (digitenként) kell legenerálni.
A feladat jellegéből az is egyértelműen következik, hogy folyamatosan
oda-vissza kell konvertálni String és
int adattípusok között. A program
alapértelmezésben kiírja a titkos számkombinációt is, ám egy rövid
kommentjellel
könnyen eltüntethetjük, ebben az esetben már tényleg tippmixelhetünk:
//System.out.print("(A titkos számkombináció: " + stringSzamkombinacio + ".)");
Nézzük meg a futtatható Java-kódot!
import java.util.*;
public class Main {
public static void main(String[] args) {
String bekeres = "";
String stringSzamkombinacio = "";
int talalgatasiKorSzam = 0;
int szamKombinacioSzam = 0;
Scanner scanner = new Scanner(System.in);
do{
System.out.println("Kérem, hogy adja meg a számkombinációk számát (3-4-5)!");
bekeres = scanner.nextLine();
}while(!bekeres.equals("3") && !bekeres.equals("4") && !bekeres.equals("5"));
szamKombinacioSzam = Integer.parseInt(bekeres);
do{
System.out.println("Kérem, hogy adja meg, hány kör találgatást szeretne (0 < n
< 2000000!)");
bekeres = scanner.nextLine();
talalgatasiKorSzam = Integer.parseInt(bekeres);
}while((talalgatasiKorSzam < 1) || (talalgatasiKorSzam > 2000000));
int tombSzamKombinacio[] = new int[szamKombinacioSzam];
for (int i = 0; i < tombSzamKombinacio.length; i++){
Random random = new Random();
tombSzamKombinacio[i] = random.nextInt(9) + 0;
}
System.out.println();
switch(szamKombinacioSzam){
case 3: stringSzamkombinacio = String.valueOf(tombSzamKombinacio[0])
+ String.valueOf(tombSzamKombinacio[1])
+ String.valueOf(tombSzamKombinacio[2]); break;
case 4: stringSzamkombinacio = String.valueOf(tombSzamKombinacio[0])
+ String.valueOf(tombSzamKombinacio[1])
+ String.valueOf(tombSzamKombinacio[2])
+ String.valueOf(tombSzamKombinacio[3]); break;
case 5: stringSzamkombinacio = String.valueOf(tombSzamKombinacio[0])
+ String.valueOf(tombSzamKombinacio[1])
+ String.valueOf(tombSzamKombinacio[2])
+ String.valueOf(tombSzamKombinacio[3])
+ String.valueOf(tombSzamKombinacio[4]); break;
}
System.out.print("(A titkos számkombináció: " + stringSzamkombinacio + ".)");
int tippTomb[] = new int[szamKombinacioSzam];
for(int i = 0; i < talalgatasiKorSzam; i++){
String talalatiTipp = "";
for(int j = 0; j < szamKombinacioSzam; j++){
boolean joAdat = true;
do{
System.out.println ("\nKérem, hogy adja meg az " + (i+1) + ". találgatási kör
" + (j+1) + ". számjegyét!");
bekeres = scanner.nextLine();
if(bekeres.equals("0")
|| bekeres.equals("1")
|| bekeres.equals("2")
|| bekeres.equals("3")
|| bekeres.equals("4")
|| bekeres.equals("5")
|| bekeres.equals("6")
|| bekeres.equals("7")
|| bekeres.equals("8")
|| bekeres.equals("9")
&& bekeres.length() > 1){
joAdat = false;
}
}while(joAdat == true);
tippTomb[j] = Integer.parseInt(bekeres);
}
switch(szamKombinacioSzam){
case 3: talalatiTipp = String.valueOf(tippTomb[0])
+ String.valueOf(tippTomb[1])
+ String.valueOf(tippTomb[2]); break;
case 4: talalatiTipp = String.valueOf(tippTomb[0])
+ String.valueOf(tippTomb[1])
+ String.valueOf(tippTomb[2])
+ String.valueOf(tippTomb[3]); break;
case 5: talalatiTipp = String.valueOf(tippTomb[0])
+ String.valueOf(tippTomb[1])
+ String.valueOf(tippTomb[2])
+ String.valueOf(tippTomb[3])
+ String.valueOf(tippTomb[4]); break;
}
System.out.println("\nAz Ön által megadott kombináció: " + talalatiTipp +
".");
if(talalatiTipp.equals(stringSzamkombinacio)){
System.out.println("A kombinációk egyeznek.");
}
else
System.out.println("A kombinációk NEM egyeznek.");
}
}
}
Végeredmény:
Kérem, hogy adja meg a számkombinációk számát (3-4-5)!
s
Kérem, hogy adja meg a számkombinációk számát (3-4-5)!
w
Kérem, hogy adja meg a számkombinációk számát (3-4-5)!
3
Kérem, hogy adja meg, hány kör találgatást szeretne (0 < n < 2000000!)
0
Kérem, hogy adja meg, hány kör találgatást szeretne (0 < n < 2000000!)
2
(A titkos számkombináció: 652.)
Kérem, hogy adja meg az 1. találgatási kör 1. számjegyét!
3
Kérem, hogy adja meg az 1. találgatási kör 2. számjegyét!
q
Kérem, hogy adja meg az 1. találgatási kör 2. számjegyét!
a
Kérem, hogy adja meg az 1. találgatási kör 2. számjegyét!
3
Kérem, hogy adja meg az 1. találgatási kör 3. számjegyét!
3
Az Ön által megadott kombináció: 333.
A kombinációk NEM egyeznek.
Kérem, hogy adja meg az 2. találgatási kör 1. számjegyét!
6
Kérem, hogy adja meg az 2. találgatási kör 2. számjegyét!
5
Kérem, hogy adja meg az 2. találgatási kör 3. számjegyét!
2
Az Ön által megadott kombináció: 652.
A kombinációk egyeznek.
Ficsor Gergely tanítványomnak nemrégiben a fent ismertetett probléma megoldását adtam fel. Ő a maga megszokott, minimalista, de hatékony stílusában tett eleget házi feladatának. Az alábbi kód lényegében funkcionálisan azonos a fentivel (kivéve, hogy nincs benne validálás):
public class Main {
public static void main(String[] args) {
int[] tombBiciklizar = new int[3];
int[] tombTalalat = new int[3];
for (int i = 0; i < 2; i++) {
tombBiciklizar[i] =
(int)(Math.random() * 10);
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 10; j++) {
if
(tombBiciklizar[i] == j) {
tombTalalat[i] = j;
}
}
}
System.out.println("A biciklizar kodja: "
+ tombBiciklizar[0] + " " +
tombBiciklizar[1] + " " + tombBiciklizar[2]);
System.out.println("Talalati kod: "
+ tombTalalat[0] + " " + tombTalalat[1] + " " + tombTalalat[2]);
}
}
Végeredmény:
A biciklizar kodja: 4 6 0
Talalati kod: 4 6 0