Post

PINsmith

PINsmith

DESCRIPTION

After analyzing CygnusCorp’s leaked credentials, you successfully infiltrate a secondary layer of their internal network.
During your investigation, you discover developer credentials that were inadvertently committed to an internal code repository. Among the files, you uncover a partial PIN used to access a critical system, though it is incomplete.

CygnusCorp enforces a strict security policy for PINs: no two adjacent digits can be the same.

While the full PIN is obscured, the fragments you’ve uncovered, along with a leaked access report, provide enough information to craft potential combinations. However, due to system rate-limiting and the risk of detection, brute-forcing this PIN directly on the terminal would be inefficient and risky.

Instead, you need to construct a list of valid PINs based on the known pattern. By educated brute-forcing, you can pre-generate the possibilities and test each one in rapid succession, increasing your chances of success while minimizing the time spent interacting with the system.

Your task:

Enumerate every possible valid PIN code that fits the revealed pattern, adhering to the policy of no adjacent repeats. This list will allow you to systematically and efficiently break into the target system with minimal noise.

Rules:

• Known digits are fixed and must appear in the indicated positions.

• Unknown positions are represented by “*”.

• Digits may repeat in the PIN, but not in adjacent positions.

• Output the valid PINs in ascending lexicographical order.

Input Format:

• A single string representing the PIN template.

• The length of the string determines the length of the PIN.

• Known digits are shown (“0”-“9”), unknown positions are shown as “*”.

Output Format:

• Print each valid PIN on a separate line.

• The output must be sorted in ascending lexicographical order.

2 <= number of digits in PIN <= 10

1 <= number of revealed digits <= 6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Example:
Input:
*23

Expected output:
023
123
323
423
523
623
723
823
923

SOLUTION

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def generate_pins(template):
    def backtrack(index, current):
        if index == len(template):
            print("".join(current))
            return

        if template[index] != '*':
            # Fixed digit, must match previous
            if index > 0 and current[-1] == template[index]:
                return
            current.append(template[index])
            backtrack(index + 1, current)
            current.pop() # backtrack step
        else:
            for digit in map(str, range(10)):
                # Skip if digit is same as previous to avoid adjacent repetition
                if index > 0 and current[-1] == digit:
                    continue  # skip adjacent repeat
                current.append(digit)
                backtrack(index + 1, current)
                current.pop() # backtrack step

    backtrack(0, [])

generate_pins(n)