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...

www.informatika-programozas.hu - Kerékpárzár

...4 számos...

 

www.informatika-programozas.hu - Kerékpárzár

 

...sőt 5 számos változata is:

www.informatika-programozas.hu - Kerékpárzár

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

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)...

 

www.informatika-programozas.hu

 

...elegánsan feltörhető 1 db óriási vágóollóval...

 

www.informatika-programozas.hu

 

...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...

 

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

...á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ó:

www.informatika-programozas.hu - Ezt most meg kell tanulni!

 

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!

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

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):

 

www.informatika-programozas.hu - Futtatható Java-kód!

 

 

 

 

 

 

 

 

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