From 534d2cac4ab2aeb974cd672ab7b02cdb7568e59c Mon Sep 17 00:00:00 2001 From: mippolito Date: Fri, 24 Feb 2017 15:36:30 +0100 Subject: [PATCH] Adds problem79's solution --- data/p079_keylog.txt | 50 ++++++++++++++++++++++++++++++++++++++++++++ problem79.py | 50 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 data/p079_keylog.txt create mode 100644 problem79.py diff --git a/data/p079_keylog.txt b/data/p079_keylog.txt new file mode 100644 index 0000000..41f1567 --- /dev/null +++ b/data/p079_keylog.txt @@ -0,0 +1,50 @@ +319 +680 +180 +690 +129 +620 +762 +689 +762 +318 +368 +710 +720 +710 +629 +168 +160 +689 +716 +731 +736 +729 +316 +729 +729 +710 +769 +290 +719 +680 +318 +389 +162 +289 +162 +718 +729 +319 +790 +680 +890 +362 +319 +760 +316 +729 +380 +319 +728 +716 diff --git a/problem79.py b/problem79.py new file mode 100644 index 0000000..438cf6d --- /dev/null +++ b/problem79.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +""" +A common security method used for online banking is to ask the user for three random characters from a passcode. +For example, if the passcode was 531278, they may ask for the 2nd, 3rd, and 5th characters; +the expected reply would be: 317. + +The text file, keylog.txt, contains fifty successful login attempts. + +Given that the three characters are always asked for in order, analyse the file so as to determine +the shortest possible secret passcode of unknown length. +""" + +from collections import defaultdict + + +def pop_empty(dictionary): + for k, v in dictionary.iteritems(): + if not v: + del dictionary[k] + return k + else: + raise ValueError(u"No empty key") + + +def remove_value(dictionary, value): + for value_set in dictionary.itervalues(): + if value in value_set: + value_set.remove(value) + + +if __name__ == '__main__': + digits_preceding = defaultdict(set) + + with open('data/p079_keylog.txt') as f: + for line in map(str.strip, f): + for idx in xrange(len(line)): + c = line[idx] + digits_preceding[c].update(line[:idx]) + + solution = '' + + while digits_preceding: + first = pop_empty(digits_preceding) + remove_value(digits_preceding, first) + solution += first + + print solution