Designing Deterministic Finite Automata for Binary Strings Divisible by a Given Number

Dec 02, 2025 · Programming · 7 views · 7.8

Keywords: DFA | automata | divisibility | binary | remainder | Python

Abstract: This article explores the methodology to design Deterministic Finite Automata (DFA) that accept binary strings whose decimal equivalents are divisible by a specified number n. It covers the remainder-based core design concept, step-by-step construction for n=5, generalization to other bases, automation via Python scripts, and advanced topics like DFA minimization.

Introduction

Deterministic Finite Automata (DFA) are abstract models used in computer science to recognize regular languages. In this context, we address the problem of designing a DFA that accepts binary strings (over the alphabet {0, 1}) whose decimal equivalent is divisible by a given integer n, where 0 < n < 10. This problem has practical applications in digital systems and number theory.

Core Concept: Remainder-Based DFA Design

The fundamental idea is to model the DFA states based on the possible remainders when dividing a number by n. For any number n, there are n possible remainders: 0, 1, ..., n-1. We define n states, each corresponding to a remainder value. State q0 represents a remainder of 0 and is designated as both the initial and accepting state, since strings with decimal equivalent divisible by n should be accepted.

A complete DFA requires that from each state, there is exactly one outgoing edge for each symbol in the alphabet. This ensures that the automaton can process any input string without missing transitions.

Step-by-Step Example: Binary DFA for n=5

To illustrate, let's construct a DFA for n=5. We start with five states: q0, q1, q2, q3, q4, corresponding to remainders 0 to 4. Initially, we add a self-loop on q0 for symbol '0', since the string "0" has decimal 0, which is divisible by 5.

Next, we incrementally add transitions for binary strings representing numbers 1, 2, 3, 4, etc. For instance, for the binary string "1" (decimal 1, remainder 1), we add a transition δ(q0, 1) → q1. Similarly, for "10" (decimal 2, remainder 2), we add δ(q1, 0) → q2. This process continues until all possible transitions are defined, resulting in a complete DFA with 10 edges (5 states × 2 symbols).

<table> <tr><th>Number</th><th>Binary</th><th>Remainder (%5)</th><th>End-state</th><th>Transition Added</th></tr> <tr><td>One</td><td>1</td><td>1</td><td>q1</td><td>δ(q0, 1) → q1</td></tr> <tr><td>Two</td><td>10</td><td>2</td><td>q2</td><td>δ(q1, 0) → q2</td></tr> <tr><td>Three</td><td>11</td><td>3</td><td>q3</td><td>δ(q1, 1) → q3</td></tr> <tr><td>Four</td><td>100</td><td>4</td><td>q4</td><td>δ(q2, 0) → q4</td></tr> <tr><td>Five</td><td>101</td><td>0</td><td>q0</td><td>δ(q2, 1) → q0</td></tr>

By following this method, we ensure that the DFA correctly accepts all binary strings divisible by 5.

Generalization to Other Bases

This approach is not limited to binary; it can be extended to any positional number system with base b. For a base b, the DFA will have n states (for remainders) and b × n edges. For example, for ternary (base 3) and n=5, we construct a DFA with 5 states and 15 edges, following a similar step-by-step addition of transitions for numbers 0, 1, 2, 10, 11, etc., in ternary representation.

Automated DFA Generation with Python

To automate the construction, a Python script can be implemented. The script uses the function divided_by_N(number, base) to generate the transition table. It iterates through numbers from 0 to number × base - 1, computes their representation in the given base, and updates the DFA transitions based on remainders.

def divided_by_N(number, base):
    ACCEPTING_STATE = START_STATE = '0'
    SYMBOL_0 = '0'
    dfa = {
        str(from_state): {
            str(symbol): 'to_state' for symbol in range(base)
        }
        for from_state in range(number)
    }
    dfa[START_STATE][SYMBOL_0] = ACCEPTING_STATE
    lookup_table = { SYMBOL_0: ACCEPTING_STATE }.setdefault
    for num in range(number * base):
        end_state = str(num % number)
        num_s = baseN(num, base)  # assume baseN function is defined
        before_end_state = lookup_table(num_s[:-1], START_STATE)
        dfa[before_end_state][num_s[-1]] = end_state
        lookup_table(num_s, end_state)
    return dfa

For instance, running the script with number=5 and base=4 produces a DFA for base-4 numbers divisible by 5, with the transition table printed and a graph visualization generated using Pygraphviz.

Advanced Considerations

Several advanced topics are relevant. First, the constructed DFA is minimized only when there is no common factor between n and the base b. Otherwise, further minimization techniques may reduce the number of states. Second, to design a DFA that accepts strings divisible by multiple numbers (e.g., 3 or 5), we can take the union of individual DFAs. Conversely, for strings divisible by both numbers (e.g., 3 and 5), we design a DFA for the least common multiple (e.g., 15).

These concepts are supported by theoretical results in automata theory, such as those discussed in the paper "Divisibility and State Complexity."

Conclusion

Designing DFAs for divisibility by a given number is a systematic process based on remainder states. This method generalizes across different bases and can be automated with programming tools. Understanding this approach provides insights into the relationship between number theory and automata, with applications in compiler design, digital circuits, and beyond.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.