From e583266394a051c59c905f2471aa63441770bf81 Mon Sep 17 00:00:00 2001 From: raj_mathe Date: Tue, 26 Oct 2021 14:49:42 +0200 Subject: [PATCH] =?UTF-8?q?master=20>=20master:=20code=20-=20genau=201=20G?= =?UTF-8?q?etr=C3=A4nk=20sei=20vergiftet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- code/algorithms/search/poison.py | 41 +++++++++++++++++++------------- code/config.yml | 2 -- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/code/algorithms/search/poison.py b/code/algorithms/search/poison.py index f585530..c99adcc 100644 --- a/code/algorithms/search/poison.py +++ b/code/algorithms/search/poison.py @@ -21,26 +21,25 @@ from code.algorithms.methods import *; # CHECKS # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -def preChecks(L: List[int], **_): - # TODO +def preChecks(L: List[bool], **_): + assert sum(L) > 0, 'Mindestens ein Getränk muss vergiftet sein!'; + assert sum(L) == 1, 'Höchstens ein Getränk darf vergiftet sein!'; return; -def postChecks(L: List[int], indexes: List[int], **_): - if sum(L) > 0: - assert [ k for k in range(len(L)) if L[k] == True ] == indexes, 'Der Algorithmus hat die vergifteten Getränke nicht erfolgreich bestimmt.'; - else: - assert len(indexes) == 0, 'Der Algorithmus sollte erkennen, dass Gift nicht vorhanden ist.'; +def postChecks(L: List[bool], index: int, **_): + assert L[index] == True, 'Der Algorithmus hat das vergiftete Getränk nicht erfolgreich bestimmt.'; return; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ALGORITHM find poison # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -@algorithmInfos(name='Giftsuche (O(n) Vorkoster)', outputnames='indexes', checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks) -def FindPoison(L: List[bool]) -> List[int]: +@algorithmInfos(name='Giftsuche (O(n) Vorkoster)', outputnames='index', checks=True, metrics=True, preChecks=preChecks, postChecks=postChecks) +def FindPoison(L: List[bool]) -> int: ''' Inputs: L = Liste von Getränken: durch boolesche Werte wird dargestellt, ob ein Getränk vergiftet ist. - Outputs: Die Liste aller Indexes i mit L[i] == true, was den vergifteten Getränken entspricht. + Annahme: Genau ein Getränk sei vergiftet. + Outputs: Der Index des vergifteten Getränks, falls es eines gibt, ansonsten -1. NOTE: Zeitkosten hier messen nur die Anzahl der Vorkoster. ''' @@ -55,7 +54,9 @@ def FindPoison(L: List[bool]) -> List[int]: effects = waitForEffects(L, testers); logDebug('Effekte auswerten, um vergiftete Getränke zu lokalisieren.'); poisened = evaluateEffects(testers, effects); - return poisened; + if len(poisened) > 0: + return poisened[0]; + return -1; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ALGORITHM find poison fast @@ -65,7 +66,8 @@ def FindPoison(L: List[bool]) -> List[int]: def FindPoisonFast(L: List[bool]) -> List[int]: ''' Inputs: L = Liste von Getränken: durch boolesche Werte wird dargestellt, ob ein Getränk vergiftet ist. - Outputs: Die Liste aller Indexes i mit L[i] == true, was den vergifteten Getränken entspricht. + Annahme: Genau ein Getränk sei vergiftet. + Outputs: Der Index des vergifteten Getränks, falls es eines gibt, ansonsten -1. NOTE: Zeitkosten hier messen nur die Anzahl der Vorkoster. ''' @@ -75,16 +77,21 @@ def FindPoisonFast(L: List[bool]) -> List[int]: testers = []; ## Für jedes Bit i=0 bis p ... for i in range(p+1): - AddToCounter(2); - logDebug('Füge Vorkoster hinzu, der alle Getränke k testet mit {i}. Bit = 1.'.format(i=i)) - testers.append([ k for k in range(n) if nthBit(number=k, digit=i) == 1 ]); + tester0 = [ k for k in range(n) if nthBit(number=k, digit=i) == 0 ]; + tester1 = [ k for k in range(n) if not (k in tester0) ]; + # NOTE: tester1 ist virtuell: aus den Effekten auf tester0 und den Annahmen lassen sich die Effekte auf tester0 erschließen. + # Darum zählen wir nicht 2 sondern 1 Vorkoster. + AddToCounter(1); logDebug('Füge Vorkoster hinzu, der alle Getränke k testet mit {i}. Bit = 0.'.format(i=i)) - testers.append([ k for k in range(n) if nthBit(number=k, digit=i) == 0 ]); + testers.append(tester0); + testers.append(tester1); logDebug('Warte auf Effekte'); effects = waitForEffects(L, testers); logDebug('Effekte auswerten, um vergiftete Getränke zu lokalisieren.'); poisened = evaluateEffects(testers, effects); - return poisened; + if len(poisened) > 0: + return poisened[0]; + return -1; # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # AUXILIARY METHOD wait for effects, evaluate effects diff --git a/code/config.yml b/code/config.yml index a65806e..179ebd3 100644 --- a/code/config.yml +++ b/code/config.yml @@ -37,8 +37,6 @@ parts: description: 'Freiwilliges ÜB2, A4, Beispiel' inputs: &ref_inputs_ueb2_4 L: [ false, false, false, false, false, false, false, false, true, false, false, false, false, false ] - # L: [ false, false, false, false, false, false, false, false, true, false, false, false, true, false ] - # L: [ false, false, false, false, false, false, false, false, false, false, false, false, false, false ] - command: 'algorithm-search-poison-fast' description: 'Freiwilliges ÜB2, A4, Beispiel' inputs: *ref_inputs_ueb2_4