How to resolve the algorithm De Bruijn sequences step by step in the Ruby programming language
How to resolve the algorithm De Bruijn sequences step by step in the Ruby programming language
Table of Contents
Problem Statement
The sequences are named after the Dutch mathematician Nicolaas Govert de Bruijn.
A note on Dutch capitalization: Nicolaas' last name is de Bruijn, the de isn't normally capitalized unless it's the first word in a sentence. Rosetta Code (more or less by default or by fiat) requires the first word in the task name to be capitalized.
In combinatorial mathematics, a de Bruijn sequence of order n on a size-k alphabet (computer science) A is a cyclic sequence in which every possible length-n string (computer science, formal theory) on A occurs exactly once as a contiguous substring. Such a sequence is denoted by B(k, n) and has length kn, which is also the number of distinct substrings of length n on A; de Bruijn sequences are therefore optimally short. There are: distinct de Bruijn sequences B(k, n).
For this Rosetta Code task, a de Bruijn sequence is to be generated that can be used to shorten a brute-force attack on a PIN-like code lock that does not have an "enter" key and accepts the last n digits entered.
Note: automated teller machines (ATMs) used to work like this, but their software has been updated to not allow a brute-force attack.
A digital door lock with a 4-digit code would have B (10, 4) solutions, with a length of 10,000 (digits). Therefore, only at most 10,000 + 3 (as the solutions are cyclic or wrap-around) presses are needed to open the lock. Trying all 4-digit codes separately would require 4 × 10,000 or 40,000 presses.
(The last requirement is to ensure that the verification tests performs correctly. The verification processes should list any and all missing PIN codes.) Show all output here, on this page.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm De Bruijn sequences step by step in the Ruby programming language
The provided Ruby code defines two methods, deBruijn
and validate
, to generate and validate a de Bruijn sequence.
deBruijn Method:
-
The
deBruijn
method takes two parameters:k
: The number of symbols in the alphabet (in this case, 10 digits).n
: The length of the desired de Bruijn sequence.
-
It initializes:
alphabet
as a string containing the digits "0123456789".@a
as an array of sizek * n
filled with zeros.@seq
as an empty array.
-
It defines a nested method
db
:db
takes four parameters:k
: The number of symbols in the alphabet.n
: The length of the desired de Bruijn sequence.t
: The current position in the sequence.p
: The period of the sequence.
- It checks if
t
is greater thann
. If so, it checks ifn
is divisible byp
. If it is, it concatenates the firstp
elements of@a
to@seq
. - If
t
is not greater thann
, it sets@a[t]
to@a[t - p]
. It then callsdb
recursively withk
,n
,t + 1
, andp
. - It sets
j
to@a[t - p] + 1
and loops whilej
is less thank
. Within the loop, it sets@a[t]
toj
, callsdb
recursively withk
,n
,t + 1
, andt
, and incrementsj
.
-
Finally, the
deBruijn
method callsdb
withk
,n
, 1, and 1 to generate the de Bruijn sequence.
validate Method:
-
The
validate
method takes a stringdb
as a parameter. -
It initializes:
le
to the length ofdb
.found
as an array of 10000 zeros.errs
as an empty array.
-
It iterates over all substrings of length 4 in
db
and checks if they consist only of digits. If so, it converts the substring to an integer and increments the corresponding element in thefound
array. -
After the iteration, it checks each element in
found
. If an element is 0, it adds an error message to theerrs
array indicating that the corresponding PIN number is missing. If an element is greater than 1, it adds an error message indicating that the PIN number occurs multiple times. -
If
errs
is empty, it prints "No errors found." Otherwise, it prints the number of errors found and lists the error messages.
Usage:
The code demonstrates the usage of deBruijn
and validate
methods. It generates a de Bruijn sequence of length 10^4, prints its first and last 130 digits, and then validates the sequence. It also overlays the sequence with a dot character at position 4443 and re-validates it to showcase error detection.
Source code in the ruby programming language
def deBruijn(k, n)
alphabet = "0123456789"
@a = Array.new(k * n, 0)
@seq = []
def db(k, n, t, p)
if t > n then
if n % p == 0 then
temp = @a[1 .. p]
@seq.concat temp
end
else
@a[t] = @a[t - p]
db(k, n, t + 1, p)
j = @a[t - p] + 1
while j < k do
@a[t] = j # & 0xFF
db(k, n, t + 1, t)
j = j + 1
end
end
end
db(k, n, 1, 1)
buf = ""
for i in @seq
buf <<= alphabet[i]
end
return buf + buf[0 .. n-2]
end
def validate(db)
le = db.length
found = Array.new(10000, 0)
errs = []
# Check all strings of 4 consecutive digits within 'db'
# to see if all 10,000 combinations occur without duplication.
for i in 0 .. le-4
s = db[i .. i+3]
if s.scan(/\D/).empty? then
found[s.to_i] += 1
end
end
for i in 0 .. found.length - 1
if found[i] == 0 then
errs <<= (" PIN number %04d missing" % [i])
elsif found[i] > 1 then
errs <<= (" PIN number %04d occurs %d times" % [i, found[i]])
end
end
if errs.length == 0 then
print " No errors found\n"
else
pl = (errs.length == 1) ? "" : "s"
print " ", errs.length, " error", pl, " found:\n"
for err in errs
print err, "\n"
end
end
end
db = deBruijn(10, 4)
print "The length of the de Bruijn sequence is ", db.length, "\n\n"
print "The first 130 digits of the de Bruijn sequence are: ", db[0 .. 129], "\n\n"
print "The last 130 digits of the de Bruijn sequence are: ", db[-130 .. db.length], "\n\n"
print "Validating the de Bruijn sequence:\n"
validate(db)
print "\n"
db[4443] = '.'
print "Validating the overlaid de Bruijn sequence:\n"
validate(db)
You may also check:How to resolve the algorithm Arbitrary-precision integers (included) step by step in the Go programming language
You may also check:How to resolve the algorithm Abbreviations, automatic step by step in the Tcl programming language
You may also check:How to resolve the algorithm Loops/For with a specified step step by step in the TUSCRIPT programming language
You may also check:How to resolve the algorithm Null object step by step in the Babel programming language
You may also check:How to resolve the algorithm HTTPS step by step in the Frink programming language