dsa_visualizer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +323 -0
  4. data/USAGE.md +359 -0
  5. data/bin/dsa_visualizer +5 -0
  6. data/lib/dsa_visualizer/algorithms/dynamic_programming.rb +23 -0
  7. data/lib/dsa_visualizer/algorithms/graph_algorithms.rb +23 -0
  8. data/lib/dsa_visualizer/algorithms/greedy.rb +11 -0
  9. data/lib/dsa_visualizer/algorithms/searching.rb +78 -0
  10. data/lib/dsa_visualizer/algorithms/sorting.rb +77 -0
  11. data/lib/dsa_visualizer/algorithms/string_algorithms.rb +11 -0
  12. data/lib/dsa_visualizer/cli.rb +281 -0
  13. data/lib/dsa_visualizer/comparator.rb +57 -0
  14. data/lib/dsa_visualizer/data_structures/array.rb +109 -0
  15. data/lib/dsa_visualizer/data_structures/binary_tree.rb +104 -0
  16. data/lib/dsa_visualizer/data_structures/bst.rb +11 -0
  17. data/lib/dsa_visualizer/data_structures/deque.rb +11 -0
  18. data/lib/dsa_visualizer/data_structures/doubly_linked_list.rb +11 -0
  19. data/lib/dsa_visualizer/data_structures/graph.rb +11 -0
  20. data/lib/dsa_visualizer/data_structures/hash_table.rb +61 -0
  21. data/lib/dsa_visualizer/data_structures/heap.rb +17 -0
  22. data/lib/dsa_visualizer/data_structures/linked_list.rb +197 -0
  23. data/lib/dsa_visualizer/data_structures/priority_queue.rb +11 -0
  24. data/lib/dsa_visualizer/data_structures/queue.rb +110 -0
  25. data/lib/dsa_visualizer/data_structures/stack.rb +207 -0
  26. data/lib/dsa_visualizer/data_structures/string.rb +11 -0
  27. data/lib/dsa_visualizer/data_structures/trie.rb +11 -0
  28. data/lib/dsa_visualizer/data_structures/union_find.rb +11 -0
  29. data/lib/dsa_visualizer/fundamentals/complexity.rb +264 -0
  30. data/lib/dsa_visualizer/fundamentals/memory.rb +285 -0
  31. data/lib/dsa_visualizer/fundamentals/pointers.rb +311 -0
  32. data/lib/dsa_visualizer/fundamentals/recursion.rb +63 -0
  33. data/lib/dsa_visualizer/memory_tracker.rb +49 -0
  34. data/lib/dsa_visualizer/notes_manager.rb +85 -0
  35. data/lib/dsa_visualizer/version.rb +3 -0
  36. data/lib/dsa_visualizer/visualizer.rb +58 -0
  37. data/lib/dsa_visualizer.rb +114 -0
  38. metadata +157 -0
@@ -0,0 +1,23 @@
1
+ module DSAVisualizer
2
+ module Algorithms
3
+ class DynamicProgramming
4
+ def self.learn_intro
5
+ Visualizer.print_header("DYNAMIC PROGRAMMING - Optimization Technique")
6
+ puts "\nšŸ“š Coming soon: Memoization and tabulation"
7
+ puts "Topics: Overlapping subproblems, optimal substructure"
8
+ end
9
+
10
+ def self.learn_fibonacci
11
+ Visualizer.print_header("FIBONACCI - DP Example")
12
+ puts "\nšŸ“š Coming soon: From recursion to DP"
13
+ puts "Topics: Top-down vs bottom-up, space optimization"
14
+ end
15
+
16
+ def self.learn_knapsack
17
+ Visualizer.print_header("0/1 KNAPSACK PROBLEM")
18
+ puts "\nšŸ“š Coming soon: Classic DP problem"
19
+ puts "Topics: 2D DP table, backtracking solution"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module DSAVisualizer
2
+ module Algorithms
3
+ class GraphAlgorithms
4
+ def self.learn_bfs
5
+ Visualizer.print_header("BREADTH-FIRST SEARCH (BFS)")
6
+ puts "\nšŸ“š Coming soon: Level-order graph traversal"
7
+ puts "Topics: Queue-based, shortest path in unweighted graph"
8
+ end
9
+
10
+ def self.learn_dfs
11
+ Visualizer.print_header("DEPTH-FIRST SEARCH (DFS)")
12
+ puts "\nšŸ“š Coming soon: Deep exploration"
13
+ puts "Topics: Stack/recursion-based, cycle detection, topological sort"
14
+ end
15
+
16
+ def self.learn_dijkstra
17
+ Visualizer.print_header("DIJKSTRA'S ALGORITHM")
18
+ puts "\nšŸ“š Coming soon: Shortest path in weighted graph"
19
+ puts "Topics: Priority queue, greedy approach, non-negative weights"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ module DSAVisualizer
2
+ module Algorithms
3
+ class Greedy
4
+ def self.learn_intro
5
+ Visualizer.print_header("GREEDY ALGORITHMS")
6
+ puts "\nšŸ“š Coming soon: Making locally optimal choices"
7
+ puts "Topics: Activity selection, Huffman coding, coin change"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,78 @@
1
+ module DSAVisualizer
2
+ module Algorithms
3
+ class Searching
4
+ def self.learn_linear
5
+ demo
6
+ end
7
+
8
+ def self.learn_binary
9
+ demo
10
+ end
11
+
12
+ def self.demo
13
+ Visualizer.print_header("SEARCHING ALGORITHMS - Core Level Visualization")
14
+
15
+ Visualizer.print_section("1. Linear Search")
16
+
17
+ ruby_code = <<~RUBY
18
+ def linear_search(arr, target)
19
+ arr.each_with_index do |val, idx|
20
+ return idx if val == target
21
+ end
22
+ -1
23
+ end
24
+ RUBY
25
+
26
+ cpp_code = <<~CPP
27
+ int linearSearch(int arr[], int n, int target) {
28
+ for(int i = 0; i < n; i++) {
29
+ if(arr[i] == target)
30
+ return i;
31
+ }
32
+ return -1;
33
+ }
34
+ CPP
35
+
36
+ explanation = "Sequential scan through array. Time: O(n), Space: O(1). Works on unsorted arrays."
37
+
38
+ Visualizer.print_comparison(ruby_code, cpp_code, explanation)
39
+
40
+ Visualizer.print_section("2. Binary Search")
41
+
42
+ ruby_code2 = <<~RUBY
43
+ def binary_search(arr, target)
44
+ left, right = 0, arr.length - 1
45
+ while left <= right
46
+ mid = (left + right) / 2
47
+ return mid if arr[mid] == target
48
+ arr[mid] < target ? left = mid + 1 : right = mid - 1
49
+ end
50
+ -1
51
+ end
52
+ RUBY
53
+
54
+ cpp_code2 = <<~CPP
55
+ int binarySearch(int arr[], int n, int target) {
56
+ int left = 0, right = n - 1;
57
+ while(left <= right) {
58
+ int mid = left + (right - left) / 2;
59
+ if(arr[mid] == target) return mid;
60
+ if(arr[mid] < target) left = mid + 1;
61
+ else right = mid - 1;
62
+ }
63
+ return -1;
64
+ }
65
+ CPP
66
+
67
+ explanation2 = "Divide and conquer on sorted array. Time: O(log n), Space: O(1). Requires sorted input."
68
+
69
+ Visualizer.print_comparison(ruby_code2, cpp_code2, explanation2)
70
+
71
+ puts "\n\nšŸŽÆ Key Takeaways:".colorize(:green).bold
72
+ puts " 1. Linear: O(n) - works on any array"
73
+ puts " 2. Binary: O(log n) - requires sorted array"
74
+ puts " 3. Binary search eliminates half the search space each iteration"
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,77 @@
1
+ module DSAVisualizer
2
+ module Algorithms
3
+ class Sorting
4
+ def self.learn_bubble
5
+ demo
6
+ end
7
+
8
+ def self.learn_merge
9
+ puts "\nšŸ“š Coming soon: Merge Sort - Divide and Conquer"
10
+ end
11
+
12
+ def self.learn_quick
13
+ puts "\nšŸ“š Coming soon: Quick Sort - Partition-based"
14
+ end
15
+
16
+ def self.demo
17
+ Visualizer.print_header("SORTING ALGORITHMS - Core Level Visualization")
18
+
19
+ Visualizer.print_section("1. Bubble Sort")
20
+
21
+ ruby_code = <<~RUBY
22
+ def bubble_sort(arr)
23
+ n = arr.length
24
+ (n-1).times do |i|
25
+ (n-i-1).times do |j|
26
+ if arr[j] > arr[j+1]
27
+ arr[j], arr[j+1] = arr[j+1], arr[j]
28
+ end
29
+ end
30
+ end
31
+ arr
32
+ end
33
+ RUBY
34
+
35
+ cpp_code = <<~CPP
36
+ void bubbleSort(int arr[], int n) {
37
+ for(int i = 0; i < n-1; i++) {
38
+ for(int j = 0; j < n-i-1; j++) {
39
+ if(arr[j] > arr[j+1]) {
40
+ std::swap(arr[j], arr[j+1]);
41
+ }
42
+ }
43
+ }
44
+ }
45
+ CPP
46
+
47
+ explanation = "Both implementations identical in logic. Ruby's swap is cleaner syntax. Time: O(n²), Space: O(1). Stable sort."
48
+
49
+ Visualizer.print_comparison(ruby_code, cpp_code, explanation)
50
+
51
+ arr = [64, 34, 25, 12, 22]
52
+ puts "\nOriginal: #{arr.inspect}"
53
+
54
+ # Simulate one pass
55
+ puts "\nAfter first pass:"
56
+ n = arr.length
57
+ (n-1).times do |j|
58
+ if arr[j] > arr[j+1]
59
+ arr[j], arr[j+1] = arr[j+1], arr[j]
60
+ puts " Swapped #{arr[j+1]} and #{arr[j]}: #{arr.inspect}"
61
+ end
62
+ end
63
+
64
+ Visualizer.print_section("2. Quick Sort")
65
+ puts "\nDivide and conquer algorithm"
66
+ puts "Average: O(n log n), Worst: O(n²)"
67
+ puts "In-place, not stable"
68
+
69
+ puts "\n\nšŸŽÆ Sorting Comparison:".colorize(:green).bold
70
+ puts " Bubble Sort: O(n²) - simple, slow"
71
+ puts " Quick Sort: O(n log n) - fast, in-place"
72
+ puts " Merge Sort: O(n log n) - stable, needs extra space"
73
+ puts " Heap Sort: O(n log n) - in-place, not stable"
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,11 @@
1
+ module DSAVisualizer
2
+ module Algorithms
3
+ class StringAlgorithms
4
+ def self.learn_kmp
5
+ Visualizer.print_header("KMP PATTERN MATCHING")
6
+ puts "\nšŸ“š Coming soon: Efficient string search"
7
+ puts "Topics: LPS array, O(n+m) complexity"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,281 @@
1
+ require 'io/console'
2
+
3
+ module DSAVisualizer
4
+ class CLI
5
+ CURRICULUM = {
6
+ "1" => {
7
+ title: "Fundamentals",
8
+ topics: {
9
+ "1.1" => { name: "Time & Space Complexity", key: :complexity_basics },
10
+ "1.2" => { name: "Memory Management", key: :memory_basics },
11
+ "1.3" => { name: "Pointers & References", key: :pointers_basics },
12
+ "1.4" => { name: "Recursion Basics", key: :recursion_basics }
13
+ }
14
+ },
15
+ "2" => {
16
+ title: "Basic Data Structures",
17
+ topics: {
18
+ "2.1" => { name: "Arrays", key: :array },
19
+ "2.2" => { name: "Strings", key: :string },
20
+ "2.3" => { name: "Linked Lists", key: :linked_list },
21
+ "2.4" => { name: "Doubly Linked Lists", key: :doubly_linked_list },
22
+ "2.5" => { name: "Circular Linked Lists", key: :circular_linked_list }
23
+ }
24
+ },
25
+ "3" => {
26
+ title: "Stack & Queue",
27
+ topics: {
28
+ "3.1" => { name: "Stack (Array-based)", key: :stack },
29
+ "3.2" => { name: "Stack (Linked List-based)", key: :stack_linked },
30
+ "3.3" => { name: "Queue (Array-based)", key: :queue },
31
+ "3.4" => { name: "Queue (Linked List-based)", key: :queue_linked },
32
+ "3.5" => { name: "Circular Queue", key: :circular_queue },
33
+ "3.6" => { name: "Deque", key: :deque },
34
+ "3.7" => { name: "Priority Queue", key: :priority_queue }
35
+ }
36
+ },
37
+ "4" => {
38
+ title: "Hashing",
39
+ topics: {
40
+ "4.1" => { name: "Hash Functions", key: :hash_functions },
41
+ "4.2" => { name: "Hash Tables", key: :hash_table },
42
+ "4.3" => { name: "Collision Handling", key: :collision_handling },
43
+ "4.4" => { name: "Hash Maps & Sets", key: :hash_map_set }
44
+ }
45
+ },
46
+ "5" => {
47
+ title: "Trees",
48
+ topics: {
49
+ "5.1" => { name: "Binary Trees", key: :binary_tree },
50
+ "5.2" => { name: "Binary Search Trees", key: :bst },
51
+ "5.3" => { name: "Tree Traversals", key: :tree_traversals },
52
+ "5.4" => { name: "AVL Trees", key: :avl_tree },
53
+ "5.5" => { name: "Red-Black Trees", key: :red_black_tree },
54
+ "5.6" => { name: "B-Trees", key: :b_tree },
55
+ "5.7" => { name: "Segment Trees", key: :segment_tree },
56
+ "5.8" => { name: "Fenwick Trees", key: :fenwick_tree },
57
+ "5.9" => { name: "Trie", key: :trie }
58
+ }
59
+ },
60
+ "6" => {
61
+ title: "Heaps",
62
+ topics: {
63
+ "6.1" => { name: "Min Heap", key: :min_heap },
64
+ "6.2" => { name: "Max Heap", key: :max_heap },
65
+ "6.3" => { name: "Heap Operations", key: :heap_operations },
66
+ "6.4" => { name: "Heap Sort", key: :heap_sort }
67
+ }
68
+ },
69
+ "7" => {
70
+ title: "Graphs",
71
+ topics: {
72
+ "7.1" => { name: "Graph Representations", key: :graph_representation },
73
+ "7.2" => { name: "BFS (Breadth-First Search)", key: :bfs },
74
+ "7.3" => { name: "DFS (Depth-First Search)", key: :dfs },
75
+ "7.4" => { name: "Topological Sort", key: :topological_sort },
76
+ "7.5" => { name: "Shortest Path (Dijkstra)", key: :dijkstra },
77
+ "7.6" => { name: "Shortest Path (Bellman-Ford)", key: :bellman_ford },
78
+ "7.7" => { name: "Minimum Spanning Tree (Kruskal)", key: :kruskal },
79
+ "7.8" => { name: "Minimum Spanning Tree (Prim)", key: :prim },
80
+ "7.9" => { name: "Floyd-Warshall", key: :floyd_warshall }
81
+ }
82
+ },
83
+ "8" => {
84
+ title: "Sorting Algorithms",
85
+ topics: {
86
+ "8.1" => { name: "Bubble Sort", key: :bubble_sort },
87
+ "8.2" => { name: "Selection Sort", key: :selection_sort },
88
+ "8.3" => { name: "Insertion Sort", key: :insertion_sort },
89
+ "8.4" => { name: "Merge Sort", key: :merge_sort },
90
+ "8.5" => { name: "Quick Sort", key: :quick_sort },
91
+ "8.6" => { name: "Heap Sort", key: :heap_sort },
92
+ "8.7" => { name: "Counting Sort", key: :counting_sort },
93
+ "8.8" => { name: "Radix Sort", key: :radix_sort },
94
+ "8.9" => { name: "Bucket Sort", key: :bucket_sort }
95
+ }
96
+ },
97
+ "9" => {
98
+ title: "Searching Algorithms",
99
+ topics: {
100
+ "9.1" => { name: "Linear Search", key: :linear_search },
101
+ "9.2" => { name: "Binary Search", key: :binary_search },
102
+ "9.3" => { name: "Ternary Search", key: :ternary_search },
103
+ "9.4" => { name: "Jump Search", key: :jump_search },
104
+ "9.5" => { name: "Interpolation Search", key: :interpolation_search }
105
+ }
106
+ },
107
+ "10" => {
108
+ title: "Advanced Algorithms",
109
+ topics: {
110
+ "10.1" => { name: "Dynamic Programming Intro", key: :dp_intro },
111
+ "10.2" => { name: "Fibonacci (DP)", key: :dp_fibonacci },
112
+ "10.3" => { name: "Knapsack Problem", key: :knapsack },
113
+ "10.4" => { name: "Longest Common Subsequence", key: :lcs },
114
+ "10.5" => { name: "Matrix Chain Multiplication", key: :matrix_chain },
115
+ "10.6" => { name: "Greedy Algorithms", key: :greedy_intro },
116
+ "10.7" => { name: "Backtracking", key: :backtracking },
117
+ "10.8" => { name: "Divide and Conquer", key: :divide_conquer }
118
+ }
119
+ },
120
+ "11" => {
121
+ title: "String Algorithms",
122
+ topics: {
123
+ "11.1" => { name: "Pattern Matching (Naive)", key: :pattern_naive },
124
+ "11.2" => { name: "KMP Algorithm", key: :kmp },
125
+ "11.3" => { name: "Rabin-Karp", key: :rabin_karp },
126
+ "11.4" => { name: "Z Algorithm", key: :z_algorithm }
127
+ }
128
+ },
129
+ "12" => {
130
+ title: "Advanced Data Structures",
131
+ topics: {
132
+ "12.1" => { name: "Disjoint Set (Union-Find)", key: :union_find },
133
+ "12.2" => { name: "Suffix Array", key: :suffix_array },
134
+ "12.3" => { name: "Suffix Tree", key: :suffix_tree },
135
+ "12.4" => { name: "Skip List", key: :skip_list }
136
+ }
137
+ }
138
+ }
139
+
140
+ def self.start
141
+ new.run
142
+ end
143
+
144
+ def run
145
+ loop do
146
+ clear_screen
147
+ print_header
148
+ print_menu
149
+ choice = get_input
150
+
151
+ break if choice == "0"
152
+ handle_choice(choice)
153
+ end
154
+
155
+ puts "\nšŸ‘‹ Happy Learning! Keep practicing DSA!".colorize(:green)
156
+ end
157
+
158
+ private
159
+
160
+ def clear_screen
161
+ system('cls') || system('clear')
162
+ end
163
+
164
+ def print_header
165
+ puts "ā•”" + "═" * 78 + "ā•—"
166
+ puts "ā•‘" + " DSA VISUALIZER - Zero to Hero ".center(78).colorize(:cyan).bold + "ā•‘"
167
+ puts "ā•‘" + " Ruby vs C++ Implementation Comparison ".center(78).colorize(:yellow) + "ā•‘"
168
+ puts "ā•š" + "═" * 78 + "ā•"
169
+ puts ""
170
+ end
171
+
172
+ def print_menu
173
+ puts "šŸ“š CURRICULUM".colorize(:green).bold
174
+ puts "─" * 80
175
+
176
+ CURRICULUM.each do |section_num, section|
177
+ puts "\n#{section_num}. #{section[:title]}".colorize(:yellow).bold
178
+ section[:topics].each do |topic_num, topic|
179
+ puts " #{topic_num}. #{topic[:name]}"
180
+ end
181
+ end
182
+
183
+ puts "\n" + "─" * 80
184
+ puts "Commands:".colorize(:cyan)
185
+ puts " • Enter topic number (e.g., 2.1 for Arrays)"
186
+ puts " • Type 'progress' to see your learning progress"
187
+ puts " • Type 'notes' to view saved notes"
188
+ puts " • Type '0' to exit"
189
+ puts "─" * 80
190
+ end
191
+
192
+ def get_input
193
+ print "\nāž¤ Enter your choice: ".colorize(:green)
194
+ gets.chomp.strip
195
+ end
196
+
197
+ def handle_choice(choice)
198
+ case choice.downcase
199
+ when 'progress'
200
+ show_progress
201
+ when 'notes'
202
+ show_notes
203
+ else
204
+ run_topic(choice)
205
+ end
206
+ end
207
+
208
+ def run_topic(topic_code)
209
+ section_num = topic_code.split('.').first
210
+ section = CURRICULUM[section_num]
211
+
212
+ unless section
213
+ puts "\nāŒ Invalid section number!".colorize(:red)
214
+ wait_for_key
215
+ return
216
+ end
217
+
218
+ topic = section[:topics][topic_code]
219
+
220
+ unless topic
221
+ puts "\nāŒ Invalid topic number!".colorize(:red)
222
+ wait_for_key
223
+ return
224
+ end
225
+
226
+ clear_screen
227
+ DSAVisualizer.learn(topic[:key])
228
+ mark_completed(topic_code)
229
+ wait_for_key
230
+ end
231
+
232
+ def show_progress
233
+ clear_screen
234
+ puts "\nšŸ“Š YOUR LEARNING PROGRESS".colorize(:cyan).bold
235
+ puts "─" * 80
236
+
237
+ completed = load_progress
238
+ total = CURRICULUM.values.sum { |s| s[:topics].size }
239
+
240
+ puts "\nCompleted: #{completed.size}/#{total} topics"
241
+ puts "Progress: #{'ā–ˆ' * (completed.size * 50 / total)}#{'ā–‘' * (50 - completed.size * 50 / total)} #{(completed.size * 100 / total)}%"
242
+
243
+ if completed.any?
244
+ puts "\nāœ… Completed Topics:"
245
+ completed.each { |topic| puts " • #{topic}" }
246
+ end
247
+
248
+ wait_for_key
249
+ end
250
+
251
+ def show_notes
252
+ clear_screen
253
+ puts "\nšŸ“ YOUR NOTES".colorize(:cyan).bold
254
+ puts "─" * 80
255
+ puts "\nFeature coming soon! Notes will be saved automatically as you learn."
256
+ wait_for_key
257
+ end
258
+
259
+ def mark_completed(topic_code)
260
+ completed = load_progress
261
+ completed << topic_code unless completed.include?(topic_code)
262
+ save_progress(completed)
263
+ end
264
+
265
+ def load_progress
266
+ file = File.join(Dir.home, '.dsa_visualizer_progress')
267
+ return [] unless File.exist?(file)
268
+ File.read(file).split("\n")
269
+ end
270
+
271
+ def save_progress(completed)
272
+ file = File.join(Dir.home, '.dsa_visualizer_progress')
273
+ File.write(file, completed.join("\n"))
274
+ end
275
+
276
+ def wait_for_key
277
+ puts "\n\nPress any key to continue...".colorize(:light_black)
278
+ STDIN.getch
279
+ end
280
+ end
281
+ end
@@ -0,0 +1,57 @@
1
+ module DSAVisualizer
2
+ class Comparator
3
+ def self.compare_memory_model(concept)
4
+ case concept
5
+ when :array
6
+ ruby_model = <<~RUBY
7
+ # Ruby Array (Dynamic)
8
+ arr = [1, 2, 3]
9
+ # Internally: Array of object references
10
+ # Each element is a pointer to Ruby object
11
+ # Heap allocated, garbage collected
12
+ RUBY
13
+
14
+ cpp_model = <<~CPP
15
+ // C++ Array (Static)
16
+ int arr[3] = {1, 2, 3};
17
+ // Contiguous memory block
18
+ // Direct values, no indirection
19
+ // Stack or heap allocated
20
+ CPP
21
+
22
+ explanation = "Ruby arrays store references to objects (indirection), while C++ arrays store actual values in contiguous memory. Ruby provides dynamic sizing with overhead, C++ offers fixed size with better cache locality."
23
+
24
+ Visualizer.print_comparison(ruby_model, cpp_model, explanation)
25
+
26
+ when :pointer
27
+ ruby_model = <<~RUBY
28
+ # Ruby (No explicit pointers)
29
+ obj = Object.new
30
+ ref = obj # Reference copy
31
+ # Both point to same object
32
+ # Managed by GC
33
+ RUBY
34
+
35
+ cpp_model = <<~CPP
36
+ // C++ (Explicit pointers)
37
+ int* ptr = new int(42);
38
+ int* ref = ptr; // Pointer copy
39
+ // Manual memory management
40
+ delete ptr; // Must free
41
+ CPP
42
+
43
+ explanation = "Ruby abstracts pointers as object references with automatic memory management. C++ exposes raw pointers requiring manual allocation/deallocation, offering more control but more responsibility."
44
+
45
+ Visualizer.print_comparison(ruby_model, cpp_model, explanation)
46
+ end
47
+ end
48
+
49
+ def self.compare_complexity(operation, ruby_complexity, cpp_complexity, explanation)
50
+ puts "\nā±ļø Time Complexity Comparison:".colorize(:yellow).bold
51
+ puts " Operation: #{operation}"
52
+ puts " Ruby: #{ruby_complexity}".colorize(:red)
53
+ puts " C++: #{cpp_complexity}".colorize(:green)
54
+ puts " Why: #{explanation}"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,109 @@
1
+ module DSAVisualizer
2
+ module DataStructures
3
+ class Array
4
+ def self.learn
5
+ demo
6
+ end
7
+
8
+ def self.demo
9
+ Visualizer.print_header("ARRAY - Core Level Visualization")
10
+
11
+ # Memory Model Comparison
12
+ Visualizer.print_section("1. Memory Model")
13
+ Comparator.compare_memory_model(:array)
14
+
15
+ # Creation and Memory Allocation
16
+ Visualizer.print_section("2. Array Creation")
17
+ tracker = MemoryTracker.new
18
+
19
+ Visualizer.print_step(1, "Creating array in Ruby")
20
+ arr = [10, 20, 30, 40, 50]
21
+ tracker.track_allocation("Array", arr.size, arr)
22
+
23
+ puts "\nRuby internals:"
24
+ puts " - Array object created on heap"
25
+ puts " - Stores references to Integer objects"
26
+ puts " - Dynamic resizing capability"
27
+ Visualizer.visualize_memory_layout("Ruby Array", arr)
28
+
29
+ puts "\nC++ equivalent:"
30
+ puts " int arr[5] = {10, 20, 30, 40, 50};"
31
+ puts " - Contiguous memory block"
32
+ puts " - Each int: 4 bytes"
33
+ puts " - Total: 20 bytes (5 Ɨ 4)"
34
+ puts " - Stack allocated (if local)"
35
+
36
+ # Access Operation
37
+ Visualizer.print_section("3. Element Access")
38
+ Visualizer.print_step(2, "Accessing element at index 2")
39
+
40
+ element = arr[2]
41
+ tracker.track_operation("Access", "arr[2] = #{element}")
42
+ Visualizer.visualize_array(arr, 2)
43
+
44
+ puts "\nšŸ” Ruby Process:"
45
+ puts " 1. Check bounds (raises error if out of range)"
46
+ puts " 2. Calculate: base_address + (index Ɨ pointer_size)"
47
+ puts " 3. Dereference pointer to get object"
48
+ puts " 4. Return object reference"
49
+
50
+ puts "\nšŸ” C++ Process:"
51
+ puts " 1. Calculate: base_address + (index Ɨ sizeof(int))"
52
+ puts " 2. Direct memory access"
53
+ puts " 3. Return value (no indirection)"
54
+
55
+ Comparator.compare_complexity(
56
+ "Array Access",
57
+ "O(1) - with bounds checking overhead",
58
+ "O(1) - direct memory access",
59
+ "Both are constant time, but C++ is faster due to no bounds checking and direct value access"
60
+ )
61
+
62
+ # Insertion
63
+ Visualizer.print_section("4. Insertion")
64
+ Visualizer.print_step(3, "Inserting 25 at index 2")
65
+
66
+ puts "\nBefore:"
67
+ Visualizer.visualize_array(arr)
68
+
69
+ arr.insert(2, 25)
70
+ tracker.track_operation("Insert", "Inserted 25 at index 2")
71
+
72
+ puts "\nAfter:"
73
+ Visualizer.visualize_array(arr, 2)
74
+
75
+ puts "\nšŸ”„ Ruby Process:"
76
+ puts " 1. Check if resize needed (capacity vs size)"
77
+ puts " 2. If needed: allocate new array (2Ɨ capacity)"
78
+ puts " 3. Shift elements right from index 2"
79
+ puts " 4. Insert new element"
80
+ puts " 5. Update size"
81
+
82
+ puts "\nšŸ”„ C++ Process (std::vector):"
83
+ puts " 1. Check capacity"
84
+ puts " 2. If needed: allocate new memory"
85
+ puts " 3. Copy elements to new location"
86
+ puts " 4. Shift elements using memmove"
87
+ puts " 5. Insert element"
88
+
89
+ Comparator.compare_complexity(
90
+ "Array Insertion (middle)",
91
+ "O(n) - must shift elements",
92
+ "O(n) - must shift elements",
93
+ "Both require shifting elements. Ruby has additional overhead from object reference management."
94
+ )
95
+
96
+ # Memory Summary
97
+ tracker.print_summary
98
+
99
+ # Key Takeaways
100
+ puts "\n\nšŸŽÆ Key Takeaways:".colorize(:green).bold
101
+ puts " 1. Ruby arrays are dynamic and store object references"
102
+ puts " 2. C++ arrays can be static (fixed) or dynamic (std::vector)"
103
+ puts " 3. Ruby provides safety (bounds checking) at cost of performance"
104
+ puts " 4. C++ provides speed at cost of safety (manual management)"
105
+ puts " 5. Both use contiguous memory, but Ruby adds indirection layer"
106
+ end
107
+ end
108
+ end
109
+ end