Tim Varley Logo
Tim Varley Principal AI Engineer and Tech Leader
Problem #79 medium

Passcode Derivation

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.

View on Project Euler

Implementations

cpp
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <fstream>
std::string passcode_derivation() {
std::ifstream file("keylog.txt");
std::vector<std::string> logs;
std::string line;
while (std::getline(file, line)) {
if (line.size() == 3) logs.push_back(line);
}
std::vector<std::set<int>> graph(10);
std::vector<int> indegree(10, 0);
std::set<int> digits;
for (const auto& log : logs) {
int a = log[0] - '0', b = log[1] - '0', c = log[2] - '0';
digits.insert(a);
digits.insert(b);
digits.insert(c);
if (graph[a].find(b) == graph[a].end()) {
graph[a].insert(b);
++indegree[b];
}
if (graph[b].find(c) == graph[b].end()) {
graph[b].insert(c);
++indegree[c];
}
}
std::queue<int> q;
for (int d : digits) {
if (indegree[d] == 0) q.push(d);
}
std::string passcode;
while (!q.empty()) {
int d = q.front(); q.pop();
passcode += '0' + d;
for (int next : graph[d]) {
--indegree[next];
if (indegree[next] == 0) q.push(next);
}
}
return passcode;
}
#if ! defined UNITTEST_MODE
int main(int argc, char const *argv[]) {
std::cout << passcode_derivation() << std::endl;
}
#endif
View on GitHub
O(n) time complexity

Solution Notes

Mathematical Background

The problem involves reconstructing a secret passcode from partial sequences. Each login attempt provides three consecutive digits in order.

This is a graph problem where digits are nodes, and the order constraints are edges. The shortest passcode is found using topological sorting.

Algorithm Analysis

Build a directed graph where an edge A->B means A appears before B in some triple.

Use Kahn’s algorithm (BFS topological sort) to find the order with no cycles.

The resulting sequence is the passcode.

Performance Analysis

  • Time Complexity: O(n + v) where n is triples, v is digits (10)
  • Space Complexity: O(v + e) for graph
  • Execution Time: Very fast, milliseconds
  • Scalability: Linear in input size

Key Insights

  • Topological sort reconstructs the sequence from partial orders
  • The graph must be a DAG (no cycles)
  • Answer is 73162890

Educational Value

This problem teaches:

  • Graph construction from constraints
  • Topological sorting algorithms
  • Solving problems with partial information

Problem #79 is taken from Project Euler and licensed under CC BY-NC-SA 4.0.