Unit 1:
2024-07-12
Module name: Introduction to Data Structures and Algorithms
Educational Goal: To introduce the fundamental concepts of data structures and algorithms, their importance in computer science, and the relationship between them.
Topics:
\[\large\rm Program = Algorithm + Data\ Structure\]
Algorithm: A series of steps needed for a process or a function
Data Structure: A system of storing data in a way that can be retrieved.
\[\rm Choose\ 2:\ \left\{\begin{matrix}Fast\\ Small\\ Cheap\\ \end{matrix}\right.\]
\[\tiny\rm\eqalign{Number & &Factors\\ 2 &\rightarrow& 2 {}^{(Prime)}\\ 3 &\rightarrow& 3 {}^{(Prime)}\\ 4 &\rightarrow& 2 \times 2 \\ 5 &\rightarrow& 5 {}^{(Prime)}\\ 6 &\rightarrow& 2 \times 3 \\ 7 &\rightarrow& 7 {}^{(Prime)}\\ 8 &\rightarrow& 2 \times 2 \times 2\\ 9 &\rightarrow& 3 \times 3 \\ 10 &\rightarrow& 2 \times 5 \\ }\]
def find_primes1
# SETUP A CONTAINER FOR THE RESULTS
# FOR ALL NUMBERS IN TEST RANGE
# PRESUME NUM AS PRIME
# CHECK FOR FACTORS LESS THAN NUM
# IF FACTOR FOUND
# MARK AS NON-PRIME
# APPEND PRIME TO LIST OF PRIMES
def is_factor?(num1,num2)
return (num1 % num2).eql?(0)
end
def find_primes1
# SETUP A CONTAINER FOR THE RESULTS
@primes = []
# FOR ALL NUMBERS IN TEST RANGE
(2..MAX_NUM).each do |num|
# PRESUME NUM AS PRIME
is_prime = true
# CHECK FOR FACTORS LESS THAN NUM
(2...num).each do |num2|
# IF FACTOR FOUND
if is_factor?(num,num2)
# MARK NUMBER AS NON-PRIME
is_prime = false
break
end
end
end
# APPEND PRIME TO LIST OF PRIMES
if is_prime
@primes << num
end
end
def find_primes2
# CREATE A TALLY OF NUMBERS IN RANGE
# CREATE AN ARRAY FOR THE RESULTS
# TEST ALL NUMBERS IN THE RANGE
# ELIMINATE NUMBERS LESS THAN 2
# IF NEW PRIME FOUND
# APPEND PRIME TO MASTER LIST
# ELIMINATE ALL MULTIPLES OF PRIME
def find_primes2
# CREATE A TALLY OF ALL NUMBERS
tally = (0..MAX).to_a
# CREATE A LIST FOR PRIMES FOUND
@primes = []
# TEST ALL NUMBERS IN THE RANGE
(0..MAX).each do |num|
# ELIMINATE NUMBERS LESS THAN 2
if num < 2
tally[num] = nil
# IF NEW PRIME FOUND
elsif !numbers[num].nil?
#APPEND PRIME TO MASTER LIST
@primes << num
# ELIMINATE MULTIPLES OF PRIME
xnum = num
while xnum <= MAX do
numbers[xnum] = nil
xnum += num
end
end
end
end
# LOAD PRIME LIBRARY CLASS
def find_primes3
# SETUP A CONTAINER FOR THE RESULTS
# FOR ALL NUMBERS IN TEST RANGE
# IF A NUMBER IS PRIME
# SAVE IT
require 'prime'
def find_primes3
# SETUP A CONTAINER FOR THE RESULTS
@primes = []
# FOR ALL NUMBERS IN TEST RANGE
(2..MAX_NUM).each do |num|
# IF A NUMBER IS PRIME
if num.prime?
# SAVE IT
@primes << num
end
end
end
# TEST FOR POSSIBLE FACTORS
def is_factor?(num1,num2)
(num1 % num2).eql?(0)
end
def find_primes1
@primes = []
(2..MAX).each do |num|
is_prime = true
(2...num).each do |num2|
if is_factor?(num,num2)
is_prime = false
break
end
end
if is_prime
@primes << num
end
end
end
# REMOVE MULTIPLES FROM TALLY
def find_primes2
tally = (0..MAX).to_a
@primes = []
(0..MAX).each do |num|
if num < 2
tally[num] = nil
elsif !tally[num].nil?
@primes << num
xnum = num
while xnum <= MAX do
tally[xnum] = nil
xnum += num
end
end
end
end
# RUBY LIBRARY CALL
require 'prime'
def find_primes3
@primes = []
(2..MAX).each do
|num|
if num.prime?
@primes << num
end
end
end
Parameter | Algorithm 1 | Algorithm 2 | Algorithm 3 |
---|---|---|---|
Method used | Test for all possible factors | Cross multiples off a tally | Compare to list of prime numbers |
Origin | User-defined | User-defined | Ruby Class |
Time Required (msec) | 6.944 | 0.053 | 0.077 |
Memory Requirements (bytes) | 5 | 400 | 100 |
Program complexity | 40 | 18 | 15 |
Programming effort (min) | 8 | 5 | 3 |
Lines of psuedocode | 6 | 6 | 4 |
Lines of code | 14 | 15 | 8 |
\[\begin{matrix} Bit & 7 & 6 & 5 & 4 & 3 & 2 & 1 & 0\\ \hline HexDec& x80 & x40 & x20 & x10 & x08 & x04 & x02 & x01\\ 2^n &128 & 64 & 32 & 16 & 8 & 4 & 2 & 1\\ \rightarrow & 0 & 1& 1 & 0 & 0& 1 & 1 & 0 & = & 102\\ \hline BCD & 8 & 4 & 2 & 1& 8 & 4 & 2 & 1\\ \rightarrow & 0 & 1& 1 & 0 & 0& 1 & 1 & 0 & = & 66\\ \hline \end{matrix}\]
Decimal vs Hexidecimal
\[\begin{matrix} \hline xx \rightarrow & 00 & 01 & 10 & 11 & | & 00 & 01 & 10 & 11\\ \hline xx00 & 0 & 4 & 8 & 12 & | & 0 & 4 & 8 & C\\ xx01 & 1 & 5 & 9 & 13 & | &1 & 5 & 9 & D\\ xx10 & 2 & 6 &10 & 14 & | &2 & 6 &A & E \\ xx11 & 3 & 7 &11 & 15 & | &3 & 7 &B & F\\ \hline \end{matrix}\]
\[Given\ a\ 64\ bit\ number:\ 0xFEDCBA9876543210\]
\[\rm\eqalign{Byte:&\ \ 0\quad 1\quad 2\quad \ 3\quad 4\quad 5\quad 6\quad 7\quad 8\quad\\ Big-Endian: &\fbox{FE}\fbox{DC}\fbox{BA}\fbox{98}\fbox{76}\fbox{54}\fbox{32}\fbox{10}\\ &most\ significant\ byte\ first\\ Little-Endian:& \fbox{01}\fbox{23}\fbox{45}\fbox{67}\fbox{89}\fbox{AB}\fbox{CD}\fbox{EF}\\ & most\ significant\ byte\ last\\ }\]
\[\abs(-11) \rightarrow 00001011\]
\[00001011 \rightarrow 11110100\]
\[11110100 + 00000001 \rightarrow 11110101\]
Short Integer: 32 bit, -2,147,483,648 to 2,147,483,647 \(\tiny \fbox{........|........|........|........}\)
Long Integer: 64 bit, -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
\(\tiny \fbox{........|........|........|........|........|........|........|........}\)
Rational Number: 128 bit (2x64 bit) largest number: 9,223,372,036,854,775,807 smallest number: 0.0000000000000000000108
\(\tiny {Numerator:\ } \fbox{........|........|........|........} {,\ \ Denominator:\ } \fbox{........|........|........|........}\)
Floating Number: 96 bit * Max value: 1.7976931348623157e+308 * Smallest value: 2.2250738585072014e-308
puts\(\tiny {Mantissa: }\tiny\fbox{....|........|........|........|........|........|........}\ \ \ {Exponent: } \fbox{....|........|........}\)
Bignum: linked numerical structures no limits
2.size => 4 bytes
88888888888888888888888888888888888888888888888.size => 20 bytes
\[\large 14103_{10}\]
Mode | Values |
---|---|
Binary: | 1 1 0 1 1 1 0 0 0 1 0 1 1 1 |
Base 4: | 11 01 11 00 01 01 11 |
Base 8: | 11 011 100 010 111 |
Base 16: | 11 0111 0001 0111 |
Base 32: | 1101 11000 10111 |
Addition with adjustment
\[\eqalign{ Number\ A: & 1&9&5&3\\ Number\ B: & 0&5&4&3\\ === Sum & 1&e&9&6\\ Adjusted: & 2&4&9&6\\ }\]
Subtraction
\[\eqalign{ Number\ A: & 2&0&0&0\\ Adjusted A: & 1&9&9&a\\ Number\ B: & 0&5&4&3\\ Diff: &1&4&3&7\\ }\]
x = 2
200.times do |y|
GC.start
t = Time.now
10000.times do
x *= 2
end
puts "#{Time.now - t}, #{#{x.size}}"
end
https://www.ruby-lang.org/en/downloads/
$ irb
: to write ruby in the terminal'
in ruby, use "
instead{}
with do end
and vice versa –– not true for hashes or #{}
escapings[1,2].map(&:to_i)
integer
: number without decimalfloat
: number with decimal$
: global variable@
: instance variable@@
: class variable1_000_000
: 1000000 –– just easier to readmy_variable = “Hello”
my_variable.capitalize! # ! changes the value of the var same as my_name = my_name.capitalize
my_variable ||= "Hi" # ||= is a conditional assignment only set the variable if it was not set before.
MY_CONSTANT = # something
my_array = [a,b,c,d,e]
my_array[1] # b
my_array[2..-1] # c , d , e
multi_d = [[0,1],[0,1]]
[1, 2, 3] << 4 # [1, 2, 3, 4] same as [1, 2, 3].push(4)
hash = { "key1" => "value1", "key2" => "value2" } # same as objects in JavaScript
hash = { key1: "value1", key2: "value2" } # the same hash using symbols instead of strings
my_hash = Hash.new # same as my_hash = {} – set a new key like so: pets["Stevie"] = "cat"
pets["key1"] # value1
pets["Stevie"] # cat
my_hash = Hash.new("default value")
hash.select{ |key, value| value > 3 } # selects all keys in hash that have a value greater than 3
hash.each_key { |k| print k, " " } # ==> key1 key2
hash.each_value { |v| print v } # ==> value1value2
my_hash.each_value { |v| print v, " " }
# ==> 1 2 3
:symbol # symbol is like an ID in html. :symbol != "symbol"
# Symbols are often used as Hash keys or referencing method names.
# They can not be changed once created. They save memory (only one copy at a given time). Faster.
:test.to_s # converts to "test"
"test".to_sym # converts to :test
"test".intern # :test
# Symbols can be used like this as well:
my_hash = { key: "value", key2: "value" } # is equal to { :key => "value", :key2 => "value" }
"bla,bla".split(“,”) # takes string and returns an array (here ["bla","bla"])
Methods
def greeting(hello, *names) # *names is a split argument, takes several parameters passed in an array
return "#{hello}, #{names}"
end
start = greeting("Hi", "Justin", "Maria", "Herbert") # call a method by name
def name(variable=default)
### The last line in here gets returned by default
end
custom objects
class Person # class names are rather written in PascalCase (It is similar to camelCase, but the first letter is capitalized)
@@count = 0
attr_reader :name # make it readable
attr_writer :name # make it writable
attr_accessor :name # makes it readable and writable
def Methodname(parameter)
@classVariable = parameter
@@count += 1
end
def self.show_classVariable
@classVariable
end
def Person.get_counts # is a class method
return @@count
end
private
def private_method; end # Private methods go here
end
matz = Person.new("Yukihiro")
matz.show_name # Yukihiro
class DerivedClass < Base
def some_method
super(optional args) #
# Some stuff
end
end
end
module ModuleName
end
Math::PI # using PI constant from Math module.
require 'date' # to use external modules.
puts Date.today # 2016-03-18
module Action
def jump
@distance = rand(4) + 2
puts "I jumped forward #{@distance} feet!"
end
end
class Rabbit
include Action
extend Action
attr_reader :name
def initialize(name)
@name = name
end
end
peter = Rabbit.new("Peter")
peter.jump # include
Rabbit.jump # extend
Blocks are not objects. A block is just a bit of code between do..end or {}. It’s not an object on its own, but it can be passed to methods like .each or .select.
def yield_name(name)
yield("Kim") # print "My name is Kim. "
yield(name) # print "My name is Eric. "
end
yield_name("Eric") { |n| print "My name is #{n}. " }
yield_name("Peter") { |n| print "My name is #{n}. " }
Saves blocks and are objects. A proc is a saved block we can use over and over.
cube = Proc.new { |x| x ** 3 }
[1, 2, 3].collect!(&cube) # [1, 8, 27]
cube.call
lambda { |param| block }
multiply = lambda { |x| x * 3 }
y = [1, 2].collect(&multiply) # 3 , 6
"A " << "B"
=> "A B"
"A " + "B"
"A #{4} B"
=> "A 4 B"
=begin
Bla
Multiline comment
=end
# single line comment
if 1 < 2
puts “one smaller than two”
elsif 1 > 2
puts “elsif”
else
puts “false”
end
puts "be printed" if true
puts 3 > 4 ? "if true" : "else"
unless false
puts “I’m here”
else
puts “not here”
end
puts "not printed" unless true
case my_var
when "some value"
###
when "some other value"
###
else
###
end
case my_var
when "some value" then ###
when "some other value" then ###
else ###
end
&&
: and||
: or!
: not(x && (y || w)) && z
: use parenthesis to combine argumentsprint "bla"
puts "test" # puts the text in a separate line
"Hello".length # 5
"Hello".reverse # “olleH”
"Hello".upcase # “HELLO”
"Hello".downcase # “hello”
"hello".capitalize # “Hello”
"Hello".include? "i" # equals to false because there is no i in Hello
"Hello".gsub!(/e/, "o") # Hollo
"1".to_i # transform string to integer –– 1
"test".to_sym # converts to :test
"test".intern # :test
:test.to_s # converts to "test"
gets # reads a line
gets.chomp # removes new line char
i = 1
while i < 11
puts i
i = i + 1
end
i = 0
until i == 6
puts i
i += 1
end
for i in 1...10
puts i
end
i = 0
loop do
i += 1
print "I'm currently number #{i}”
break if i > 5
end
for i in 1..5
next if i % 2 == 0
print i
end
things.each do |item|
print “#{item}"
end
on hashes like so:
hashes.each do |x,y|
print "#{x}: #{y}"
end
10.times do |i|
print "#{i} this text will appear 10 times"
end
1.upto(5) { |x| print x, " " } # 1 2 3 4 5
"a".upto("c") { |x| print x, " " } # a b c
array = [5,4,1,3,2]
array.sort! # = [1,2,3,4,5]
"a" <=> "b" # 0 if a = b, 1 if a > b, -1 if a < b
array.sort! { |a, b| b <=> a } # to sort from Z to A
1.is_a? Integer # returns true
:1.is_a? Symbol # returns true
"1".is_a? String # returns true
[1,2,3].collect!() # does something to every element (overwrites original with ! mark)
.map() # is the same as .collect
1.2.floor # 1 # rounds down to the nearest integer.
cube.call # call calls procs directly
Time.now # displays the actual time
Scalar Value | 1st Byte | 2nd Byte | 3rd Byte | 4th Byte |
---|---|---|---|---|
00000000 0xxxxxxx |
0xxxxxxx | |||
00000yyy yyxxxxxx |
110yyyyy | 10xxxxxx | ||
zzzzyyyy yyxxxxxx |
1110zzzz | 10yyyyyy | 10xxxxxx | |
000uuuuu zzzzyyyy yyxxxxxx |
11110uuu | 10uuzzzz | 10yyyyy | 10xxxxxx |
Char | Coding |
---|---|
A U+0041 |
\[\small\eqalign{UTF-8: & \verb|0x41| \hfil &...&\hfil 01000001 \hfil\cr UTF-16:& \verb|0x0041|\hfil & ...&\hfil00000000 01000001\hfil\cr UTF-32: &\verb|0x00000041|\hfil & ... & \hfil0000000001000001\hfil\cr}\] |
ŋ U+14B |
\[\small\eqalign{UTF-8:& \verb|0xC5 0x8B|&... &\hfil11000101 10001011\hfil\cr UTF-16:& \verb|0x014B|\hfil& ... &\hfil0000000101001011\hfil\cr UTF-32:& \verb|0x0000014B| \hfil &...& \hfil0000000101001011\hfil\cr}\] |
ก U+E01 |
\[\small\eqalign{UTF-8:& \verb|0xE0 0xB8 0x81|\hfil &...&\hfil11100000\ 10111000\ 10000001\hfil\cr UTF-16:& \verb|0x0E01| \hfil &...&\hfil00001110\ 00000001\hfil\cr UTF-32:& \verb|0x00000E01|\hfil &...&\hfil0000111000000001\hfil\cr}\] |
က U+1000 |
\[\small\eqalign{UTF-8:&\verb|0xE1 0x80 0x80|\hfil&...&\hfil11100001\ 1000000\ 100000000\hfil\cr UTF-16:& \verb|0x1000| \hfil&...&\hfil00010000\ 00000000\hfil\cr UTF-32:& \verb|0x00001000|\hfil&...&\hfil0001000000000000\hfil\cr}\] |
☂ U+2602 |
\[\small\eqalign{UTF-8:& \verb|0xE2 0x98 0x82|\hfil&... &\hfil11100010\ 10011000\ 10000010\hfil\cr UTF-16:& \verb|0x2602|\hfil&...&\hfil 00100110\ 00000010\hfil\cr UTF-32:& \verb|0x00002602|\hfil&...&\hfil0010011000000010\hfil\cr}\] |
人 U+4EBA |
\[\tiny\eqalign{UTF-8: & \verb|0xE4 0xBA 0xBA|\hfil\ &...&\hfil11100100\ 10111010 10111010\hfil\cr UTF-16:& \verb|0x4EBA|\ \hfil&...&\hfil 01001110\ 10111010\hfil\cr UTF-32:& \verb|0x00004EBA|\hfil\ &...& \hfil 0100111010111010\hfil\cr}\] |
你 U+2F804 |
\[\small\eqalign{UTF-8: & \verb|0xF0 0xAF 0xA0 0x84|\hfil\ &...&\hfil11110000\ 10101111\ 10100000\ 10000100\hfil\cr UTF-16:& \verb|0xD87E 0xDC04|\hfil&...&\hfil1101100001111110\ 1101110000000100\hfil\cr UTF-32: & \verb|0x0002F804|\hfil&...&\hfil0000000000000010\ 1111100000000100\hfil\cr}\] |
Literal
a = 'apple'
b = 'banana'
Dynamic
c = 'I love ' + a.pluralize + ' and ' +
b.pluralize + '.'
d = <<EOM # Hereis document
I love #{a.pluralize} and #{b.pluralize}.
EOM
e = "I love #{a.pluralize} and #{b.pluralize}."
f = "I love %s and %s." %
[a.pluralize, b.pluralize]
IT212 Data Structure