Buch Cover Buch Cover Buch Cover Buch Cover

Web-Code: - Webcode Help

Code Knacken (Simulationen)

Hannas fünfstelliges Zahlenschloss wurde verstellt. Das Zahlenschloss besteht aus fünf Ringen mit je zehn möglichen Einstellungen ('0', '1', '2', ..., '9').


Irgend eine Klassenkameradin hat ihr den Code abgeschaut und nun neu eingestellt.
Die Klassenkameradin hat den neuen Code leider vergessen. Aufgrund von Lieblingszahlen und Mustern haben die beiden zusammen jedoch folgendes rekonstruieren können:

  • Der neue Code enthält keine 5.
  • Der neue Code enthält mindestens einmal die Ziffer 3.
  • Der neue Code enthält mindestens einmal die Ziffer 6.
  • Der neue Code startet nicht mit einer geraden Ziffer, auch nicht mit der Null ("0").
  • Der neue Code ist fast aufsteigend. Das heißt, die nachfolgenden Ziffern sind nicht kleiner als die vorangehenden (z. b. "23368"). Dies jedoch mit maximal einer Ausnahme. An einer Stelle darf die Ziffernfolge absteigend sein (z. b. 23326); aber wie erwähnt: maximal einmal!



Lohnt es sich nun, von den theoretisch 100'000 Möglichkeiten die verbleibenden auszuprobieren? Oder soll Hanna doch besser ein neues Zahlenschloss anschaffen.

Teilaufgabe 1: Schreiben Sie ein Programm, das alle verbleibenden
Möglichkeiten ausgibt.

Teilaufgabe 2: Hanna kann eine Kombination in drei (3) Sekunden ausprobieren. Gehen wir davon aus, dass sie die richtige Kombination nach Durchprobieren etwa der Hälfte aller Möglichkeiten gefunden haben wird; wird sie es in weniger als einer Stunde schaffen?

1 Kommentare

Bitte melde dich an um einen Kommentar abzugeben

Kommentare (1)

Tobias 14. September 2020 20:06   reply report
Cooles Beispiel!

18 Lösung(en)

package ch.programmieraufgaben.simulation.zahlenschloss;


/**
 * Programmieraufgabe Zahlenschloss
 * Web-Code: d4ko-cgvt
 * @version 0.1 (Apr 21, 2018)
 * @author Philipp Gressly Freimann 
 *         (phi@gress.ly)
 */
public class Zahlenschloss {

	final int ANZAHL_ZIFFERN       =      5;
	final int MAX_CODE             = 99_999;
	final int SEKUNDEN_PRO_VERSUCH =      3;

	public static void main(String[] args) {
		new Zahlenschloss().top();
	}


	void top() {
		int anzahlMoeglichkeiten = 0;
		for(int m = 0; m < MAX_CODE; m++) {
			if(istMoeglicherCode(m)) {
				anzahlMoeglichkeiten = anzahlMoeglichkeiten + 1;
				printMoeglichkeit(m);
			}
		}
		System.out.println("Total Möglichkeiten: " + anzahlMoeglichkeiten);
		int sekunden = anzahlMoeglichkeiten * SEKUNDEN_PRO_VERSUCH;
		int minuten  = sekunden / 60;
		System.out.println("Total Minuten für alle Möglichkeiten: " + minuten);
		System.out.println("Erwartungswert: " + minuten/2 + " Minuten.");
	}


	public boolean istMoeglicherCode(int m) {
		return okAufsteigend(m) &&
		       okZiffern(m)     &&
		       okNichtBeginnendMitGeraderZiffer(m);
	}


	boolean okNichtBeginnendMitGeraderZiffer(int m) {
		return   1 == ((codeToString(m)).charAt(0) - '0') % 2;
	}


	void printMoeglichkeit(int m) {
		System.out.println(m);
	}


	boolean okAufsteigend(int code) {
		return 1 >= anzahlAbstiege(code);
	}


	int anzahlAbstiege(int code) {
		int abstiege = 0;
		String codeZiffern = codeToString(code);
		for(int pos = 0; pos+1 < codeZiffern.length(); pos++) {
			if(codeZiffern.charAt(pos) > codeZiffern.charAt(pos+1)) {
				abstiege = abstiege + 1;
			}
		}
		return abstiege;
	}


	boolean okZiffern(int code) {
		return
		  !enthaeltZiffer('5', code) && 
		   enthaeltZiffer('3', code) &&
		   enthaeltZiffer('6', code);
	}


	String codeToString(int code) {
		String str = "" + code;
		while(str.length() < ANZAHL_ZIFFERN) {
			str = "0" + str;
		}
		return str;
	}


	boolean enthaeltZiffer(char ziffer, int code) {
		return (codeToString(code)).contains(""+ziffer);
	}

} // end of class Zahlenschloss

                

Lösung von: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

import time


def no_five(nr):
    if '5' in nr:
        return 1
    return 0


def used_three(nr):
    if '3' in nr:
        return 0
    return 2


def used_six(nr):
    if '6' in nr:
        return 0
    return 3


def starts_with_valid(nr):
    digit = int(nr[0])

    if digit == 0 or digit % 2 == 0:
        return 4
    return 0


def is_ascending(nr):
    exception = 1

    for i in range(0, len(nr) - 1):
        if int(nr[i]) > int(nr[i + 1]):
            exception -= 1

    if exception < 0:
        return 5
    return 0


def check_number(nr):
    ok = no_five(nr)
    if ok == 0:
        ok = used_three(nr)
    if ok == 0:
        ok = used_six(nr)
    if ok == 0:
        ok = starts_with_valid(nr)
    if ok == 0:
        ok = is_ascending(nr)

    return ok


number_of_codes = 0

print('start...')

t0 = time.time()

for i in range(0, 100000):
    code = '{0:05d}'.format(i)
    is_code = check_number(code)

    if is_code == 0:
        print('found code number {0}: {1}'.format(number_of_codes, code))
        number_of_codes += 1

print('finished!\n')

t1 = time.time()

print('found {0} valid codes in {1} seconds'.format(number_of_codes, t1 - t0))

seconds_per_code = 3

used_seconds = 0.5 * seconds_per_code * number_of_codes

print('the lock will be cracked in {0} seconds - that are {1} minutes and {2} seconds'.format(used_seconds,
                                                                                         used_seconds // 60,
                                                                                         used_seconds % 60))

                

Lösung von: Ich Bins (tubs)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Code knacken
https://www.programmieraufgaben.ch/aufgabe/code-knacken/d4kocgvt
"""

# Programmieraufgabe:
#     Hannas fünfstelliges Zahlenschloss wurde verstellt. Das Zahlenschloss
#     besteht aus fünf Ringen mit je zehn möglichen Einstellungen ('0', '1', '2',
#     ..., '9').
#     Irgend eine Klassenkameradin hat ihr den Code abgeschaut und nun neu
#     eingestellt. Die Klassenkameradin hat den neuen Code leider vergessen.
#     Aufgrund von Lieblingszahlen und Mustern haben die beiden zusammen jedoch
#     folgendes rekonstruieren können:
#         Der neue Code enthält keine 5.
#         Der neue Code enthält mindestens einmal die Ziffer 3.
#         Der neue Code enthält mindestens einmal die Ziffer 6.
#         Der neue Code startet nicht mit einer geraden Ziffer, auch nicht mit
#         der Null ("0").
#         Der neue Code ist fast aufsteigend. Das heißt, die nachfolgenden Ziffern
#         sind nicht kleiner als die vorangehenden (z. b. "23368"). Dies jedoch
#         mit maximal einer Ausnahme. An einer Stelle darf die Ziffernfolge
#         absteigend sein (z. b. 23326); aber wie erwähnt: maximal einmal!
#     Schreiben Sie ein Programm, das alle verbleibenden Möglichkeiten ausgibt.
#
# Autor, Erstellung:
#     Ulrich Berntien, 2018-06-08
#
# Sprache:
#     Python 3.6.6


import itertools
from typing import *


def is_hannas_code(code: Tuple[int, ...]) -> bool:
    """
    Die Funktion prüft ob es eine Kombination von Hanna sein kann.
    :param code: Zu überprüfenden Zahlencode.
    :return: True, genau dann, wenn der Code von Hanna sein kann.
    """
    # Bereits vorher wurde festgelegt: keine 5 enthalten und erste Ziffer ungerade
    assert 5 not in code
    assert code[0] % 2 == 1
    # Ziffer 3 und 6 müssen enthalten sein
    # erste Ziffer muss ungerade und keine 0 sein
    # Nur maximal einmal darf die Ziffernfolge aufsteigend sein
    return 3 in code and \
           6 in code and \
           sum(a > b for (a, b) in zip(code, code[1:])) <= 1


print("Programmieraufgabe Code Knacken, http://www.programmieraufgaben.ch")
# Die Kombination besteht aus den Ziffer 0..9 ohne die Ziffer 5
hannas_digits = [digit for digit in range(10) if digit != 5]
# Die erste Ziffer muss ungerade und keine 0 sein.
hannas_first_digit = [digit for digit in hannas_digits if digit % 2 == 1]
# Hannas Kombination hat 5 Stellen und weitere Kritrien müssen erfüllt sein.
hannas_options = [code for code in itertools.product(hannas_first_digit, *(hannas_digits,) * 4) if is_hannas_code(code)]
for number in hannas_options:
    print(number)
print("Anzahl der Kombinationen:", len(hannas_options))
print("Bei 3s pro Kombination und 50% ausprobieren: {:.0f}min".format(len(hannas_options) * 3 / 2 / 60))
                

Lösung von: Ulrich Berntien ()

'12.6.2018 - Powerbasic 10

#COMPILE EXE
#DIM ALL

FUNCTION PBMAIN () AS LONG

DIM i AS LONG
DIM x AS INTEGER
DIM Loesung AS STRING
DIM AnzMgl AS LONG
DIM anzAbst AS INTEGER
DIM ZeitInMin AS INTEGER

FOR i = 00000 TO 99999
    'Startet nicht mit gerader Zahl, auch nicht 0
    IF (i \ 10000) MOD 2 = 0 THEN ITERATE
    'Enthält nicht die Ziffer 5
    IF LEN(RETAIN$(FORMAT$(i),ANY "5")) THEN ITERATE
    'Enthält mindestens einmal die Ziffern 3 und 6
    IF TALLY(FORMAT$(i),ANY "3") < 1 THEN ITERATE
    IF TALLY(FORMAT$(i),ANY "6") < 1 THEN ITERATE

    'Check Aufsteigend
    anzAbst = 0
    FOR x = 1 TO LEN(FORMAT$(i)) -1
        IF VAL(MID$(FORMAT$(i),x,1)) > VAL(MID$(FORMAT$(i),x+1,1)) THEN anzAbst += 1
    NEXT x
    IF anzAbst > 1 THEN ITERATE

    Loesung += FORMAT$(i) & $CRLF
    AnzMgl += 1
NEXT i


'Teilaufgabe 1
MSGBOX STR$(AnzMgl) & $CRLF & loesung

'Teilaufgabe 2
ZeitInMin = FIX((anzMgl * 3 / 2) / 60)
MSGBOX "Erwartet werden ca. " &  FORMAT$(ZeitInMin) & " Minuten für die Hälfte der Codes"

END FUNCTION


                

Lösung von: Markus Sägesser (keine)

def Zahlprüfen(x,y):                    # Funktion zum Prüfen von Ziffern y innerhalb einer Zahl x
    strx = str(x)                       # Umwandeln der Zahlen in Strings
    stry = str(y)
    if stry in strx:                    # Prüfung der Strings mit entsprechender Ausgabe True or False
        return True
    else:
        return False

def ErsteZifferPrüfen(x, y):
    strx = str(x)                       # Umwandeln der Zahlen in Strings
    stry = str(y)
    if strx.startswith(stry):           # Prüfung der Strings
        return True
    else:
        return False

def ZahlZuArray(x):
    l = len(str(x))                     # Bestimme Anzahl der Ziffern 
    A = [0]                             # Definiere Liste
    for k in range (0,l):                           # itteriere über alle Ziffern der Zahl 
        aneu = (x - (x%10**(l-k-1)))/10**(l-k-1)    # Berechne Listeneinträge beginnend von vorn
        x = x - aneu*10**(l-k-1)                    # kürze bisherige Zahl um höchste 10er Potenz genaue Erläuterungen siehe unten 
        A.append(aneu)                              # Füge neues Listenelement hinzu
        #print (repr(x).rjust(2), repr(aneu))
    del A[0]                                        # entferne ersten Listeneintrag (aus Definition vom Beginn) 
    return A

def FastAufsteigend(x):
    A = ZahlZuArray(x)
    l = len(A)
    pr = 0                                        # Prüfzahl zum zählen der aufsteigenden Stellen
    for k in range (0,l-1):
        if A[k] > A[k+1]:
            pr = pr + 1
            #print (repr("nicht Aufsteigend").rjust(2), repr(pr))
    if pr <= 1:
        return True
    else:
        return False 

code = 0
j = 1
while code < 99999:
    if ErsteZifferPrüfen(code,0) == True:   # Prüfung von Bedingung 4 (am meisten einschränkende)
        code = code + 10**4
    elif ErsteZifferPrüfen(code,2) == True:
        code = code + 10**4
    elif ErsteZifferPrüfen(code,4) == True:
        code = code + 10**4
    elif ErsteZifferPrüfen(code,5) == True:
        code = code + 10**4
    elif ErsteZifferPrüfen(code,6) == True:
        code = code + 10**4
    elif ErsteZifferPrüfen(code,8) == True:
        code = code + 10**4
    elif FastAufsteigend(code) == False:    # Prüfung von Bedingung 5
        code = code + 1
    elif Zahlprüfen(code, 5) == True:       # Prüfung von Bedingung 1
        code = code + 1
    elif Zahlprüfen(code, 3) == False:      # Prüfung von Bedingung 2
        code = code + 1
    elif Zahlprüfen(code, 6) == False:      # Prüfung von Bedingung 3
        code = code + 1
    else:
        print (repr(j).rjust(2) , repr(code))
        code = code + 1
        j = j+1

"""
Berechnung der Listenelemente für eine gegebene natürliche Zahl

Sei x eine n-stellige natürliche Zahl, dann lässt sich x schreiben als

    x = sum_(i=0)^n d_i*10^i

Dabei sind d_i Elemente aus {0,1,2,...,9}. Ziel ist es nun diese d_i schrittweise zu isolieren. Mit obiger Darstellung gilt

   x mod 10^(n-1)       = sum_(i=0)^(n-1) d_i*10^i
=> x - x mod 10^(n-1)   = sum_(1=0)^n d_i*10^i - sum_(i=0)^(n-1) d_i*10^i
                        = d_n*10^n

Der Übersicht halber sei nun a = x - x mod 10^(n-1). Damit folgt offensichtlich

    a / 10^n = d_n*10^n/10^n = d_n
"""

                

Lösung von: Name nicht veröffentlicht

# Autor:	Remo Spichtig
# Task:		Code Knacken

#verständliche lösung:

from itertools import product as pr

def cor( val ):
	if 5 in val:
		return False
	if 3 not in val:
		return False
	if 6 not in val:
		return False
	if val[0] % 2 == 0:
		return False
	if sum([val[i] > val[i+1] for i in range(len(val)-1)]) > 1:
		return False
	return True
	
moegliche = []

for i in pr([0,1,2,3,4,5,6,7,8,9], repeat=5):
	if cor(i):
		moegliche.append(i)

print(len(moegliche))

for i in moegliche:
	print(i)
	
print("Wenn sie alle 3 sek. eine Kombination probiert wird sie höchstens {0} min benötigen.".format(3*len(moegliche)/60))
print("Wenn sie worst-case inerhalb einer Stunde fertig sein will müsste sie alle {0} sek. eine Kombination versuchen.".format(round(360/155,3)))


#schnellere lösung:


def dfs(code, absteigend, drei, sechs):
	if len(code) == 5:
		if drei and sechs:
			print(code)
	else:
		for i in [0,1,2,3,4,6,7,8,9]:
			if i >= code[-1] or not absteigend:
				dfs(code+[i], absteigend or i < code[-1], drei or i == 3, sechs or i == 6)
	
for i in [1,3,7,9]:
	dfs([i],False, i == 3, i == 6)
                

Lösung von: remo spichtig (BBW)

using System;
using System.Linq;

namespace Schloss_knacken
{
    class Program
    {
        static void Main(string[] args)
        {
            int Zutreffend = 0;
            TimeSpan Zeit = new TimeSpan(0, 0, 0);

            for(int i = 0; i < 100000; i++)
            {
                bool Fail = false;
                string Zahl = i.ToString();
                int Failstack = 0;

                if(i.ToString().Length < 5)
                {
                    for(int k = 0; k < 5 - i.ToString().Length; k++)
                    {
                        Zahl = "0" + Zahl;
                    }
                }

                // Abfragen ob bestimmte Zeichen enthalten sind
                if (Zahl.Contains('5') || !Zahl.Contains('3') || !Zahl.Contains('6')) Fail = true;

                //Abfrage ob der Start eine gerade Zahl ist
                if(Zahl.Substring(0,1) == "0" || Int32.Parse(Zahl.Substring(0,1)) % 2 == 0) Fail = true;

                //Abfrage nach größerer Ziffer
                for(int k = 0; k < Zahl.Length -1; k++)
                {
                    int Wert1 = Int32.Parse(Zahl.Substring(k, 1));
                    int Wert2 = Int32.Parse(Zahl.Substring(k + 1, 1));

                    if(Wert1 > Wert2) Failstack++;
                }

                if(Failstack > 1) Fail = true;


                if (Fail == false)
                {
                    Zutreffend++;
                    Zeit = Zeit.Add(new TimeSpan(0, 0, 3));
                }
            }

            Console.WriteLine("Zutreffende Werte = " + Zutreffend.ToString());
            Console.WriteLine("Höchstwert = " + Zeit.TotalMinutes + "min");
            Console.WriteLine("Erwartungswert = " + Zeit.TotalMinutes / 2 + "min");
            Console.ReadLine();
        }
    }
}
                

Lösung von: Tobias Golz (Wilhelm Büchner Hochschule)

public class Main {

    public static void main(String args[]) {

        Integer counter = 0;

        for (Integer i = 10000; i < 99999; i++) {
            Code code = new Code(i);
            if (!code.containsNum(5) && code.containsNum(3) && code.containsNum(6) && code.startsWithUnevenNum() && code.almostSorted()) {
                counter++;
            }
        }

        System.out.println("Anzahl Möglichkeiten: " + counter);
        System.out.println("Richtige Kombination nach " + counter / 2 + " Versuchen in " + (((counter / 2) * 3) / 60) + " Minuten");
    }
}

public class Code {

    public int[] code = new int[5];

    public Code(Integer num) {
        for (int i = 0 ; i < 5 ; i++) {
            code[i] = Integer.valueOf(num.toString().substring(i, i+1));
        }
    }

    public boolean containsNum(int num) {
        for (int i = 0 ; i < 5 ; i++) {
            if (code[i] == num) return true;
        }
        return false;
    }

    public boolean startsWithUnevenNum() {
        return code[0] != 0 && code[0] % 2 != 0;
    }

    public boolean almostSorted() {
        int sortCounter = 0;
        for (int i = 0 ; i < 4 ; i++) {
            if (code[i] > code[i+1]) sortCounter++;
            if (sortCounter > 1) return false;
        }
        return true;
    }

}

                

Lösung von: Daniel Figia (Technische Hochschule Lübeck)

#include <stdio.h>

void main(){

int a,b,c,d,e,zaehler=0;

for(a=0;a<=9;a++){
  for(b=0;b<=9;b++){
    for(c=0;c<=9;c++){
      for(d=0;d<=9;d++){
        for(e=0;e<=9;e++){
          if(a != 5 && b != 5 && c != 5 && d != 5 && e != 5){
            if(a == 3 || b == 3 || c == 3 || d == 3 || e ==3){
              if(a == 6 || b == 6 || c == 6 || d == 6 || e == 6){
                if(a != 0 && a != 2 && a != 4 && a != 6 && a != 8){
                  if( (a<=b && b<=c && c<=d && d<=e) || (a>=b && b<=c && c<=d && d<=e) || (a<=b && b>=c && c<=d && d<=e) || (a<=b && b<=c && c>=d && d<=e) || (a<=b && b<=c && c<=d && d>=e) ){
                    zaehler++;
                    printf("%d%d%d%d%d\n",a,b,c,d,e);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
printf("\nEs gibt %d Kombinationsmoeglichkeiten.\n",zaehler);
}

                

Lösung von: Fynn Koch (keine)

(ns prgrmmrfgbncdknckn.core)

(->> (remove #{5} (range 10))
     (#(for [a % b % c % d % e %
             :let [x [a b c d e]]
             :when (and
                     (some #{3} x)
                     (some #{6} x)
                     (odd? (first x))
                     (>= 1 (count
                             (filter (fn [y]
                                       (> (first y) (last y))) (map vector (butlast x) (rest x))))))]
         x))
     println)
                

Lösung von: André Trobisch ()

import java.util.Arrays;

public class Code {

	public static void main(String[] args) {

		Integer[] code = new Integer[5];
		int n = 0;
		int count = 0;
		int cmp;

		for (int a = 0; a < 10; a++) {

			if (a % 2 == 0) {
				a++;
			}
			if (a == 5) {
				a = 7;
			}

			code[0] = a;

			for (int b = 0; b < 10; b++) {

				if (b == 5) {
					b++;
				}

				code[1] = b;

				for (int c = 0; c < 10; c++) {

					if (c == 5) {
						c++;
					}

					code[2] = c;

					for (int d = 0; d < 10; d++) {

						if (d == 5) {
							d++;
						}

						code[3] = d;

						for (int e = 0; e < 10; e++) {

							if (e == 5) {
								e++;
							}

							code[4] = e;

							if (Arrays.asList(code).contains(3) && Arrays.asList(code).contains(6)) {
								for (int i = 0; i < 4; i++) {
									cmp = i + 1;

									if (code[i] > code[cmp]) {
										count++;
									}
								}
								if (count < 2) {
									n++;
									System.out.println(n + ": " + java.util.Arrays.toString(code));

								}
							}
							count = 0;
						}
					}
				}
			}
		}
		System.out.println("Kombination erraten nach " + n / 2 + " Versuchen.");
		if ((((n / 2) * 3) / 60) < 60) {
			System.out.println("Sie schafft es in " + (((n / 2) * 3) / 60) + " Minuten, also weniger als einer Stunde.");
		} else {
			System.out.println("Sie schafft es in " + (((n / 2) * 3) / 60) + " Minuten, also mehr als einer Stunde.");
		}
	}
}

                

Lösung von: Ruben Hartenstein (Bosch GmbH)

let possibleCombinations = [];

function checkCombination(c) {
  if (c.indexOf(5) != -1) return false;      // § 1: code enthält keine 5
  if (c.indexOf(3) == -1) return false;      // § 2: code enthält eine 3
  if (c.indexOf(6) == -1) return false;      // § 3: code enthält eine 6
  // § 4: weder 0 noch gerade zahl an erster stelle
  if (c[0] == 0 || c[0] % 2 == 0) return false;
  // § 5: fast aufsteigende reihenfolge
  let desc = 0;
  for (let i = 0; i < c.length-1; i++)
    if (c[i] > c[i+1]) desc++;
  if (desc > 1) return false;
  return true;
}

function numToArr(num) {
  let arr = num.toString().split('');
  for (let i = 0; i < arr.length; i++) arr[i] = parseInt(arr[i]);
  return arr;
}

// einige zahlenbereiche könnten aufgrund der bedingungen ausgelassen werden,
// das ausschreiben würde aber länger dauern als die brute-force-methode
for (let i = 10000; i <= 99999; i++)
  if (checkCombination(numToArr(i))) possibleCombinations.push(i);

document.write(`<p>Anzahl der möglichen Kombinationen:
  <b>${possibleCombinations.length}</b></p>`);

let duration = possibleCombinations.length * 3;
document.write(`<p>Benötigte Zeit für das Durchprobieren aller Kombinationen:
  <b>${duration} s </b>(${Math.ceil(duration / 60)} min)</p>`);

document.write(`<p>Möglichkeit, dass Hanna die richtige Kombination innert
  einer Stunde findet: <b>${duration / 2 <= 60*60}</b></p>`);    //lissalanda@gmx.at

                

Lösung von: Lisa Salander (Heidi-Klum-Gymnasium Bottrop)

using System;

// Programmieraufgaben.ch Aufgaben-Code:d4ko-cgvt

namespace ConsoleApp
{
    class Program
    {
        static void Main()
        {
            int counter = 0;
            // Zahl startet nicht mit 0, d.h. alle Zahlen unter 10000 scheiden Prinzipiell aus.
            for(int runs = 10000; runs < 100000;runs++)
            {
                if(MeetsRequirements(runs.ToString()))
                {
                    Console.WriteLine(runs);
                    counter++;
                }
            }
            Console.WriteLine($"Zahlenkombinationen aufgelistet: {counter}");
            CalcTimeToCrack(counter);
        }

        static Boolean MeetsRequirements(string numbers)
        {
            // Überprüfen, ob die aktuelle Kombination den Vorraussetzungen entspricht.
            // Ausgabe der Zahl falls wahr, wie in Teilaufgabe 1 gewünscht.

            int[] singleNumbers = new int[5];
            bool isTrue = true;
            bool hasDecreased = false;

            // Einzelne Zahlen in ein Array
            for (int runs = 0; runs < 5;runs++)
            {
                singleNumbers[runs] = int.Parse(numbers.Substring(runs, 1));
            }

            // Voraussetzung 1 - 3 (enthält keine 5, enthält 3, enthält 6)
            isTrue = isTrue && !numbers.Contains("5") && numbers.Contains("3") && numbers.Contains("6");

            // Voraussetzung 4 (beginnt nicht mit einer geraden Zahl (0 wird bereits ausgeschlossen indem wir erst bei 10k anfangen)
            isTrue = isTrue && singleNumbers[0] % 2 != 0 ? true : false;

            // Voraussetzung 5 Prüfe, ob eine verringerung zur vorherigen Zahl mehfach, oder nur einmal stattfindet.
            for (int runs = 1; runs <= singleNumbers.Length-1; runs++)
            {
                if(hasDecreased)
                {
                    isTrue = isTrue && (singleNumbers[(runs - 1)] > singleNumbers[runs]) ? false : isTrue;
                }
                else
                {
                    hasDecreased = singleNumbers[(runs - 1)] > singleNumbers[runs] ? true : false;
                }
            }

            return isTrue;
        }
        static void CalcTimeToCrack(int numbers)
        {
            double time = (numbers * 3.0) / 60.0 / 2;
            if(time < 60)
            {
                Console.WriteLine($"Sie schafft es in unter 60 Minuten! Sogar in ca. {Math.Floor(time)} Minuten");
            }
            else
            {
                Console.WriteLine("Sie schafft es nicht unter 60 Minuten - Sie sollte einen neuen Tresor kaufen.");
            }
        }
    }
}

                

Lösung von: Howard Dennis King (IT-Schule Stuttgart)

public class Main {

    public static void main(String[] args) {
        int zahl = 9999;
        int counter = 0;
	    while(zahl < 100000){
	        zahl++;
	        String zahlStr = Integer.toString(zahl);
	        if( zahlStr.charAt(0)%2 == 0|| zahlStr.contains("5") || !zahlStr.contains("6") || !zahlStr.contains("3") ){
	            continue;
            }
	        boolean flag = false;
	        boolean ausnahmenAughelöst = false;
            for (int i = 0; i < zahlStr.length()-1; i++) {
                if (zahlStr.charAt(i) <= zahlStr.charAt(i+1)){

                }
                else if(!ausnahmenAughelöst){
                    ausnahmenAughelöst = true;
                }
                else{
                    flag = true;
                    break;
                }
            }
	      if(!flag){
              counter++;
              System.out.println(zahl);
          }
        }
        System.out.println(counter);
        System.out.println(counter/2*3/60);
    }
}
                

Lösung von: Tobias Bressler (HTBLA)

// C++ 14 | VS-2022
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

bool check_all(const std::string& s) {
    auto contains{ [&s](char n) { return std::find(s.begin(), s.end(), n) != s.end(); } };
    auto starts_odd_or_zero{ [&s]() { return s[0] - '0' & 1 || s[0] == '0'; } };
    auto nearly_ascending = [&s]() { auto d{ 0 }; for (size_t i{ 0 }; i < s.length() - 1; i++) if (s[i] - '0' > s[i + 1] - '0') d++; return d <= 1; };
    return !contains('5') && contains('3') && contains('6') && starts_odd_or_zero() && nearly_ascending();
}

int main() {
    std::vector<std::string> v{};
    for (auto i{ 10'000 }; i < 99'999; i++) {
        const auto n{ std::to_string(i) };
        if(check_all(n)) v.push_back(n);
    }
    std::cout << "Anzahl Kombinationen: " << v.size() << "\n\n";
    std::cout << "Zeit fuers Probieren (3s): " << v.size() * 3 / 60 << "s\n\nRestliche Kombinationen: \n";
    for (const auto& i : v) std::cout << i << "\n";
}
                

Lösung von: Jens Kelm (@JKooP)

// NET 6.x | C# 10.x | VS-2022
bool CheckAll(string s) {
    var _3_6 = "36".All(s.Contains);
    var _5 = !s.Contains('5');
    var _odd_0 = (s[0]-'0') % 2 != 0 && s[0] != '0';
    bool _asc(){
        var d = 0;
        for (var i = 0; i < s.Length-1; i++)
            if (s[i] > s[i + 1]) d++;
        return d <= 1;
    }
    return _5 && _3_6 && _odd_0 && _asc();
}

List<string> lst = new();
for (int i = 10_000; i < 99_999; i++)
    if (CheckAll(i.ToString())) lst.Add(i.ToString());

Console.WriteLine($"Anzahl Kombinationen: {lst.Count}");
Console.WriteLine($"Zeit fürs Probieren: {lst.Count * 3 / 60}s\nRestliche Kombinationen:");
lst.ForEach(Console.WriteLine);
                

Lösung von: Jens Kelm (@JKooP)

// C++ 14 | VS-2022
// Hier eine "schnelle" Variante ohne Umwandlung in String:
#include <iostream>
#include <vector>

bool check_all(const int& n) {
    const auto contains{ [&n](int c) { 
        auto m{ n }; 
        while (m) { 
            if (m % 10 == c)
                return true; 
            m /= 10;
        }
        return false; } };

    const auto starts_odd_and_not_zero{ [&n]() {
        auto m{ n };
        auto k{ 5 };
        while (k-- > 1) {
            m /= 10;
        }
        return m & 1 && m != 0; } };

    const auto nearly_ascending = [&n]() { 
        auto m{ n };
        auto d{ 0 };
        auto k{ 4 };
        int arr[5]{};
        while (m) {
            arr[k--] = m % 10;
            m /= 10;
        }
        for (auto i{ 0 }; i < 4; i++)
            if (arr[i] > arr[i + 1])
                d++;
        return d <= 1; };

    return !contains(5) && contains(3) && contains(6) && starts_odd_and_not_zero() && nearly_ascending();
}

int main() {
    std::vector<int> v{};
    for (auto i{ 10'000 }; i < 99'999; i++) {
        if (check_all(i)) v.push_back(i);
    }
    std::cout << "Anzahl Kombinationen: " << v.size() << "\n\n";
    std::cout << "Zeit fuers Probieren (3s): " << v.size() * 3 / 60 << "s\n\nRestliche Kombinationen: \n";
    for (const auto& i : v) std::cout << i << "\n";
}
                

Lösung von: Jens Kelm (@JKooP)

' VBA

Function Contains(ByVal n#, ByVal c%)
    Do While n > 0
        If n Mod 10 = c Then
            Contains = True
            Exit Function
        End If
        n = n \ 10
    Loop
    Contains = False
End Function

Function StartsOddAndNotZero(ByVal n#)
    k% = 5
    Do While k > 1
        k = k - 1
        n = n \ 10
    Loop
    StartsOddAndNotZero = n Mod 2 <> 0 And n <> 0
End Function

Function NearlyAscending(ByVal n#)
    Dim arr(5)
    d% = 0
    k% = 4
    Do While n > 0
        arr(k) = n Mod 10
        n = n \ 10
        k = k - 1
    Loop
    For i% = 0 To 3
        If arr(i) > arr(i + 1) Then d = d + 1
    Next i
    NearlyAscending = d <= 1
End Function

Function CheckAll(ByVal n#)
    CheckAll = (Not Contains(n, 5)) And _
    Contains(n, 3) And _
    Contains(n, 6) And _
    StartsOddAndNotZero(n) And _
    NearlyAscending(n)
End Function

Sub Main()
    k# = 0
    For i# = 10000 To 99999
        If CheckAll(i) Then k = k + 1
    Next i
    Debug.Print "Anzahl Kominationen: " & k
    Debug.Print "Zeit fürs Probieren: " & k * 3 \ 60
End Sub
                

Lösung von: Jens Kelm (@JKooP)

Verifikation/Checksumme:

Total Möglichkeiten: 1550
Total Minuten für alle Möglichkeiten: 77
Erwartungswert: 38 Minuten.

Aktionen

Bewertung

Durchschnittliche Bewertung:

Eigene Bewertung:
Bitte zuerst anmelden

Meta

Zeit: 2
Schwierigkeit: Mittel
Webcode: d4ko-cgvt
Autor: Philipp G. Freimann (BBW (Berufsbildungsschule Winterthur) https://www.bbw.ch)

Download PDF

Download ZIP

Zu Aufgabenblatt hinzufügen