claude-agent-framework 1.0.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 (111) hide show
  1. package/README.md +128 -0
  2. package/bin/claude-framework +3 -0
  3. package/framework/agents/design-lead.md +240 -0
  4. package/framework/agents/product-owner.md +179 -0
  5. package/framework/agents/tech-lead.md +226 -0
  6. package/framework/commands/ayuda.md +127 -0
  7. package/framework/commands/a/303/261adir.md +98 -0
  8. package/framework/commands/backup.md +397 -0
  9. package/framework/commands/cambiar.md +110 -0
  10. package/framework/commands/cloud.md +457 -0
  11. package/framework/commands/code.md +142 -0
  12. package/framework/commands/debug.md +334 -0
  13. package/framework/commands/deploy.md +383 -0
  14. package/framework/commands/deshacer.md +120 -0
  15. package/framework/commands/estado.md +218 -0
  16. package/framework/commands/explica.md +227 -0
  17. package/framework/commands/feature.md +120 -0
  18. package/framework/commands/git.md +427 -0
  19. package/framework/commands/historial.md +202 -0
  20. package/framework/commands/learn.md +408 -0
  21. package/framework/commands/movil.md +245 -0
  22. package/framework/commands/nuevo.md +118 -0
  23. package/framework/commands/plan.md +134 -0
  24. package/framework/commands/prd.md +113 -0
  25. package/framework/commands/probar.md +148 -0
  26. package/framework/commands/revisar.md +208 -0
  27. package/framework/commands/seeds.md +230 -0
  28. package/framework/commands/seguridad.md +226 -0
  29. package/framework/commands/tasks.md +157 -0
  30. package/framework/skills/architecture/algorithms.md +970 -0
  31. package/framework/skills/architecture/clean-code.md +1080 -0
  32. package/framework/skills/architecture/design-patterns.md +1984 -0
  33. package/framework/skills/architecture/functional-programming.md +972 -0
  34. package/framework/skills/architecture/solid.md +991 -0
  35. package/framework/skills/cloud/cloud-aws.md +848 -0
  36. package/framework/skills/cloud/cloud-azure.md +931 -0
  37. package/framework/skills/cloud/cloud-gcp.md +848 -0
  38. package/framework/skills/cloud/message-queues.md +1229 -0
  39. package/framework/skills/core/accessibility.md +401 -0
  40. package/framework/skills/core/api.md +474 -0
  41. package/framework/skills/core/authentication.md +306 -0
  42. package/framework/skills/core/authorization.md +388 -0
  43. package/framework/skills/core/background-jobs.md +341 -0
  44. package/framework/skills/core/caching.md +473 -0
  45. package/framework/skills/core/code-review.md +341 -0
  46. package/framework/skills/core/controllers.md +290 -0
  47. package/framework/skills/core/cua.md +285 -0
  48. package/framework/skills/core/documentation.md +472 -0
  49. package/framework/skills/core/file-uploads.md +351 -0
  50. package/framework/skills/core/hotwire-native.md +296 -0
  51. package/framework/skills/core/hotwire.md +278 -0
  52. package/framework/skills/core/i18n.md +334 -0
  53. package/framework/skills/core/imports-exports.md +750 -0
  54. package/framework/skills/core/infrastructure.md +337 -0
  55. package/framework/skills/core/models.md +228 -0
  56. package/framework/skills/core/notifications.md +672 -0
  57. package/framework/skills/core/payments.md +581 -0
  58. package/framework/skills/core/performance.md +361 -0
  59. package/framework/skills/core/rails-scaffold.md +131 -0
  60. package/framework/skills/core/search.md +518 -0
  61. package/framework/skills/core/security.md +565 -0
  62. package/framework/skills/core/seeds.md +307 -0
  63. package/framework/skills/core/seo.md +542 -0
  64. package/framework/skills/core/testing.md +393 -0
  65. package/framework/skills/core/views.md +260 -0
  66. package/framework/skills/core/websockets.md +564 -0
  67. package/framework/skills/data/advanced-sql.md +1204 -0
  68. package/framework/skills/data/nosql.md +1141 -0
  69. package/framework/skills/devops/containers-advanced.md +1237 -0
  70. package/framework/skills/devops/debugging.md +834 -0
  71. package/framework/skills/devops/git-workflow.md +752 -0
  72. package/framework/skills/devops/networking.md +932 -0
  73. package/framework/skills/devops/shell-scripting.md +1132 -0
  74. package/framework/sub-agents/architecture-patterns-agent.md +1450 -0
  75. package/framework/sub-agents/cloud-agent.md +677 -0
  76. package/framework/sub-agents/data.md +504 -0
  77. package/framework/sub-agents/debugging-agent.md +554 -0
  78. package/framework/sub-agents/devops.md +483 -0
  79. package/framework/sub-agents/docs.md +176 -0
  80. package/framework/sub-agents/frontend-dev.md +349 -0
  81. package/framework/sub-agents/git-workflow-agent.md +697 -0
  82. package/framework/sub-agents/integrations.md +630 -0
  83. package/framework/sub-agents/native-dev.md +434 -0
  84. package/framework/sub-agents/qa.md +138 -0
  85. package/framework/sub-agents/rails-dev.md +375 -0
  86. package/framework/sub-agents/security.md +526 -0
  87. package/framework/sub-agents/ui.md +437 -0
  88. package/framework/sub-agents/ux.md +284 -0
  89. package/framework/templates/api-spec.md +500 -0
  90. package/framework/templates/component-spec.md +248 -0
  91. package/framework/templates/feature.json +13 -0
  92. package/framework/templates/model-spec.md +318 -0
  93. package/framework/templates/prd-template.md +80 -0
  94. package/framework/templates/task-plan.md +122 -0
  95. package/framework/templates/task-user-story.md +52 -0
  96. package/framework/templates/technical-spec.md +260 -0
  97. package/framework/templates/user-story.md +95 -0
  98. package/package.json +42 -0
  99. package/project-templates/CLAUDE.md +42 -0
  100. package/project-templates/contexts/architecture.md +25 -0
  101. package/project-templates/contexts/conventions.md +46 -0
  102. package/project-templates/contexts/design-system.md +47 -0
  103. package/project-templates/contexts/requirements.md +38 -0
  104. package/project-templates/contexts/stack.md +30 -0
  105. package/project-templates/history/active/models.md +11 -0
  106. package/project-templates/history/changelog.md +15 -0
  107. package/project-templates/workspace/.gitkeep +0 -0
  108. package/src/cli.js +52 -0
  109. package/src/init.js +104 -0
  110. package/src/status.js +75 -0
  111. package/src/update.js +88 -0
@@ -0,0 +1,970 @@
1
+ # Skill: Algorithms and Data Structures
2
+
3
+ ## Purpose
4
+ Understand algorithmic complexity and choose appropriate data structures for efficient Ruby and Rails applications.
5
+
6
+ ---
7
+
8
+ ## Big O Notation
9
+
10
+ ### Common Complexities
11
+ ```
12
+ O(1) - Constant - Hash lookup, array access by index
13
+ O(log n) - Logarithmic - Binary search, balanced tree operations
14
+ O(n) - Linear - Array iteration, linear search
15
+ O(n log n) - Linearithmic - Efficient sorting (merge sort, quick sort)
16
+ O(n²) - Quadratic - Nested loops, bubble sort
17
+ O(2ⁿ) - Exponential - Recursive fibonacci (naive), power set
18
+ O(n!) - Factorial - Permutations, traveling salesman (brute force)
19
+ ```
20
+
21
+ ### Visual Comparison
22
+ ```
23
+ n=10: O(1)=1 O(log n)=3 O(n)=10 O(n log n)=33 O(n²)=100
24
+ n=100: O(1)=1 O(log n)=7 O(n)=100 O(n log n)=664 O(n²)=10,000
25
+ n=1000: O(1)=1 O(log n)=10 O(n)=1000 O(n log n)=9,966 O(n²)=1,000,000
26
+ ```
27
+
28
+ ### Examples in Ruby
29
+ ```ruby
30
+ # O(1) - Constant time
31
+ hash = { a: 1, b: 2, c: 3 }
32
+ hash[:b] # Hash lookup
33
+ array[5] # Array access by index
34
+ array.push(item) # Array append
35
+ array.pop # Array pop
36
+
37
+ # O(log n) - Logarithmic
38
+ sorted_array.bsearch { |x| x >= target } # Binary search
39
+ # Each step cuts the search space in half
40
+
41
+ # O(n) - Linear
42
+ array.each { |item| process(item) } # Iterate all elements
43
+ array.include?(item) # Linear search
44
+ array.find { |x| x == target } # Find first match
45
+ array.max # Find maximum
46
+ array.sum # Sum all elements
47
+
48
+ # O(n log n) - Linearithmic
49
+ array.sort # Sorting
50
+ array.sort_by { |x| x.name }
51
+
52
+ # O(n²) - Quadratic
53
+ array.each do |a|
54
+ array.each do |b| # Nested loop
55
+ compare(a, b)
56
+ end
57
+ end
58
+
59
+ # O(2ⁿ) - Exponential (avoid!)
60
+ def fibonacci(n)
61
+ return n if n <= 1
62
+ fibonacci(n - 1) + fibonacci(n - 2) # Each call spawns 2 more
63
+ end
64
+ ```
65
+
66
+ ### Analyzing Complexity
67
+ ```ruby
68
+ # Rule 1: Drop constants
69
+ # O(2n) -> O(n)
70
+ # O(n/2) -> O(n)
71
+
72
+ # Rule 2: Drop non-dominant terms
73
+ # O(n² + n) -> O(n²)
74
+ # O(n + log n) -> O(n)
75
+
76
+ # Rule 3: Different inputs = different variables
77
+ def compare_lists(list_a, list_b)
78
+ list_a.each do |a| # O(a)
79
+ list_b.each do |b| # O(b)
80
+ puts a == b
81
+ end
82
+ end
83
+ end
84
+ # Total: O(a * b), not O(n²)
85
+
86
+ # Rule 4: Sequential operations add
87
+ def process(array)
88
+ array.each { |x| step1(x) } # O(n)
89
+ array.each { |x| step2(x) } # O(n)
90
+ end
91
+ # Total: O(n + n) = O(2n) = O(n)
92
+
93
+ # Rule 5: Nested operations multiply
94
+ def process(array)
95
+ array.each do |x| # O(n)
96
+ array.each { |y| work(x, y) } # O(n)
97
+ end
98
+ end
99
+ # Total: O(n * n) = O(n²)
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Arrays vs Hashes
105
+
106
+ ### When to Use Arrays
107
+ ```ruby
108
+ # Arrays are best for:
109
+ # - Ordered collections
110
+ # - Accessing by position
111
+ # - Iterating in sequence
112
+ # - Small collections with simple lookups
113
+
114
+ # Array operations and complexity
115
+ array = [1, 2, 3, 4, 5]
116
+
117
+ array[0] # O(1) - Access by index
118
+ array.push(6) # O(1) - Append
119
+ array.pop # O(1) - Remove last
120
+ array.shift # O(n) - Remove first (shifts all elements)
121
+ array.unshift(0) # O(n) - Add to front (shifts all elements)
122
+ array.include?(3) # O(n) - Search
123
+ array.index(3) # O(n) - Find index
124
+ array.insert(2, x) # O(n) - Insert at position
125
+
126
+ # Good use case: maintaining order
127
+ recent_items = []
128
+ recent_items.push(item)
129
+ recent_items.shift if recent_items.size > 10 # Keep last 10
130
+ ```
131
+
132
+ ### When to Use Hashes
133
+ ```ruby
134
+ # Hashes are best for:
135
+ # - Key-value lookups
136
+ # - Checking membership
137
+ # - Counting occurrences
138
+ # - Caching/memoization
139
+
140
+ # Hash operations and complexity
141
+ hash = { a: 1, b: 2, c: 3 }
142
+
143
+ hash[:a] # O(1) - Lookup
144
+ hash[:d] = 4 # O(1) - Insert
145
+ hash.delete(:a) # O(1) - Delete
146
+ hash.key?(:b) # O(1) - Check key exists
147
+ hash.value?(2) # O(n) - Check value exists (must scan all)
148
+ hash.keys # O(n) - Get all keys
149
+ hash.values # O(n) - Get all values
150
+
151
+ # Good use case: counting
152
+ def count_words(text)
153
+ counts = Hash.new(0)
154
+ text.split.each { |word| counts[word] += 1 }
155
+ counts
156
+ end
157
+
158
+ # Good use case: caching
159
+ def expensive_lookup(id)
160
+ @cache ||= {}
161
+ @cache[id] ||= Database.find(id)
162
+ end
163
+
164
+ # Good use case: checking membership
165
+ allowed_ids = { 1 => true, 2 => true, 3 => true }
166
+ allowed_ids[user_id] # O(1) vs array.include? O(n)
167
+ ```
168
+
169
+ ### Converting Between Them
170
+ ```ruby
171
+ # Array to Hash
172
+ array = [[:a, 1], [:b, 2]]
173
+ hash = array.to_h # => { a: 1, b: 2 }
174
+
175
+ # Array to Hash (for membership checking)
176
+ ids = [1, 2, 3, 4, 5]
177
+ id_set = ids.to_h { |id| [id, true] }
178
+ id_set[3] # O(1) lookup
179
+
180
+ # Hash to Array
181
+ hash = { a: 1, b: 2 }
182
+ hash.to_a # => [[:a, 1], [:b, 2]]
183
+ hash.keys # => [:a, :b]
184
+ hash.values # => [1, 2]
185
+ ```
186
+
187
+ ---
188
+
189
+ ## Sorting
190
+
191
+ ### Built-in Sorting
192
+ ```ruby
193
+ # sort - uses <=> operator
194
+ [3, 1, 4, 1, 5].sort # => [1, 1, 3, 4, 5]
195
+ ["banana", "apple"].sort # => ["apple", "banana"]
196
+
197
+ # sort with custom comparator
198
+ [3, 1, 4].sort { |a, b| b <=> a } # Descending: [4, 3, 1]
199
+
200
+ # sort_by - more efficient for complex keys
201
+ users.sort_by { |u| u.name }
202
+ users.sort_by(&:name) # Shorthand
203
+
204
+ # sort_by with multiple keys
205
+ users.sort_by { |u| [u.last_name, u.first_name] }
206
+
207
+ # Descending sort_by
208
+ users.sort_by { |u| -u.age } # Numeric
209
+ users.sort_by { |u| u.name }.reverse # Any type
210
+
211
+ # In-place sorting (mutates)
212
+ array.sort!
213
+ array.sort_by!(&:name)
214
+ ```
215
+
216
+ ### Custom Comparators
217
+ ```ruby
218
+ # The <=> operator returns:
219
+ # -1 if a < b
220
+ # 0 if a == b
221
+ # 1 if a > b
222
+
223
+ class Person
224
+ include Comparable
225
+
226
+ attr_reader :name, :age
227
+
228
+ def initialize(name, age)
229
+ @name = name
230
+ @age = age
231
+ end
232
+
233
+ def <=>(other)
234
+ age <=> other.age
235
+ end
236
+ end
237
+
238
+ people = [Person.new("Bob", 30), Person.new("Alice", 25)]
239
+ people.sort # Sorted by age
240
+
241
+ # Complex sorting
242
+ products.sort do |a, b|
243
+ # First by category, then by price descending
244
+ comparison = a.category <=> b.category
245
+ comparison = b.price <=> a.price if comparison == 0
246
+ comparison
247
+ end
248
+ ```
249
+
250
+ ### Sorting Stability
251
+ ```ruby
252
+ # Ruby's sort is NOT stable (equal elements may change order)
253
+ # Use sort_by for stable-ish sorting or add a tiebreaker
254
+
255
+ # Stable sort workaround
256
+ users_with_index = users.each_with_index.map { |u, i| [u, i] }
257
+ sorted = users_with_index.sort_by { |u, i| [u.name, i] }
258
+ result = sorted.map(&:first)
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Searching
264
+
265
+ ### Linear Search
266
+ ```ruby
267
+ # O(n) - checks each element
268
+ array = [3, 1, 4, 1, 5, 9, 2, 6]
269
+
270
+ # find - returns first match or nil
271
+ array.find { |x| x > 4 } # => 5
272
+
273
+ # find_index/index - returns index of first match
274
+ array.find_index { |x| x > 4 } # => 4
275
+ array.index(4) # => 2
276
+
277
+ # include? - checks presence
278
+ array.include?(5) # => true
279
+
280
+ # any?/all?/none?
281
+ array.any? { |x| x > 8 } # => true
282
+ array.all? { |x| x > 0 } # => true
283
+ array.none? { |x| x > 10 } # => true
284
+ ```
285
+
286
+ ### Binary Search
287
+ ```ruby
288
+ # O(log n) - requires sorted array
289
+ sorted = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
290
+
291
+ # bsearch - returns element
292
+ sorted.bsearch { |x| x >= 5 } # => 5
293
+ sorted.bsearch { |x| x >= 5.5 } # => 6
294
+
295
+ # bsearch_index - returns index
296
+ sorted.bsearch_index { |x| x >= 5 } # => 4
297
+
298
+ # Find exact match
299
+ sorted.bsearch { |x| x <=> 5 } # => 5 (or nil if not found)
300
+
301
+ # Custom binary search
302
+ def binary_search(array, target)
303
+ low = 0
304
+ high = array.length - 1
305
+
306
+ while low <= high
307
+ mid = (low + high) / 2
308
+ case array[mid] <=> target
309
+ when 0 then return mid
310
+ when -1 then low = mid + 1
311
+ when 1 then high = mid - 1
312
+ end
313
+ end
314
+
315
+ nil # Not found
316
+ end
317
+ ```
318
+
319
+ ### Search in Hashes and Sets
320
+ ```ruby
321
+ # Hash - O(1) average
322
+ users_by_email = users.index_by(&:email)
323
+ user = users_by_email["john@example.com"] # O(1)
324
+
325
+ # Set - O(1) for membership
326
+ require 'set'
327
+ valid_ids = Set.new([1, 2, 3, 4, 5])
328
+ valid_ids.include?(3) # O(1)
329
+
330
+ # vs Array.include? which is O(n)
331
+ ```
332
+
333
+ ---
334
+
335
+ ## Recursion
336
+
337
+ ### Basic Recursion
338
+ ```ruby
339
+ # Every recursive function needs:
340
+ # 1. Base case - when to stop
341
+ # 2. Recursive case - how to break down the problem
342
+
343
+ # Factorial: n! = n * (n-1) * (n-2) * ... * 1
344
+ def factorial(n)
345
+ return 1 if n <= 1 # Base case
346
+ n * factorial(n - 1) # Recursive case
347
+ end
348
+
349
+ factorial(5) # => 120
350
+
351
+ # Fibonacci (naive - O(2^n), don't use!)
352
+ def fibonacci(n)
353
+ return n if n <= 1 # Base case
354
+ fibonacci(n - 1) + fibonacci(n - 2) # Two recursive calls!
355
+ end
356
+
357
+ # Sum of array
358
+ def sum(array)
359
+ return 0 if array.empty? # Base case
360
+ array.first + sum(array[1..]) # Recursive case
361
+ end
362
+ ```
363
+
364
+ ### Tail Recursion
365
+ ```ruby
366
+ # Regular recursion - builds up call stack
367
+ def factorial(n)
368
+ return 1 if n <= 1
369
+ n * factorial(n - 1) # Must wait for recursive call to complete
370
+ end
371
+ # Stack: factorial(5) -> factorial(4) -> factorial(3) -> ...
372
+
373
+ # Tail recursion - last operation is the recursive call
374
+ def factorial_tail(n, accumulator = 1)
375
+ return accumulator if n <= 1
376
+ factorial_tail(n - 1, n * accumulator) # Tail position
377
+ end
378
+ # Can be optimized to O(1) space (Ruby doesn't do this automatically)
379
+
380
+ # Enable tail call optimization (experimental)
381
+ RubyVM::InstructionSequence.compile_option = {
382
+ tailcall_optimization: true,
383
+ trace_instruction: false
384
+ }
385
+ ```
386
+
387
+ ### Converting Recursion to Iteration
388
+ ```ruby
389
+ # Recursive
390
+ def sum_recursive(array)
391
+ return 0 if array.empty?
392
+ array.first + sum_recursive(array[1..])
393
+ end
394
+
395
+ # Iterative (usually more efficient in Ruby)
396
+ def sum_iterative(array)
397
+ total = 0
398
+ array.each { |x| total += x }
399
+ total
400
+ end
401
+
402
+ # Or simply
403
+ array.sum
404
+
405
+ # Recursive tree traversal
406
+ def traverse_recursive(node)
407
+ return if node.nil?
408
+ process(node)
409
+ node.children.each { |child| traverse_recursive(child) }
410
+ end
411
+
412
+ # Iterative with stack
413
+ def traverse_iterative(root)
414
+ stack = [root]
415
+ while stack.any?
416
+ node = stack.pop
417
+ process(node)
418
+ stack.concat(node.children.reverse)
419
+ end
420
+ end
421
+ ```
422
+
423
+ ---
424
+
425
+ ## Memoization
426
+
427
+ ### Using ||= for Simple Memoization
428
+ ```ruby
429
+ class ExpensiveCalculator
430
+ def result
431
+ @result ||= calculate # Only calculates once
432
+ end
433
+
434
+ # Handle nil and false
435
+ def value
436
+ return @value if defined?(@value)
437
+ @value = calculate_value
438
+ end
439
+
440
+ private
441
+
442
+ def calculate
443
+ sleep(2) # Expensive operation
444
+ 42
445
+ end
446
+ end
447
+
448
+ # Memoizing methods with arguments
449
+ class Fibonacci
450
+ def initialize
451
+ @cache = {}
452
+ end
453
+
454
+ def calculate(n)
455
+ @cache[n] ||= begin
456
+ return n if n <= 1
457
+ calculate(n - 1) + calculate(n - 2)
458
+ end
459
+ end
460
+ end
461
+
462
+ fib = Fibonacci.new
463
+ fib.calculate(100) # Fast! O(n) instead of O(2^n)
464
+ ```
465
+
466
+ ### Using Rails.cache
467
+ ```ruby
468
+ # Simple caching
469
+ def expensive_query
470
+ Rails.cache.fetch("expensive_query", expires_in: 1.hour) do
471
+ User.includes(:orders, :subscriptions).where(active: true).to_a
472
+ end
473
+ end
474
+
475
+ # Cache with key based on data
476
+ def user_stats(user)
477
+ Rails.cache.fetch("user_stats/#{user.id}/#{user.updated_at.to_i}") do
478
+ calculate_stats(user)
479
+ end
480
+ end
481
+
482
+ # Russian doll caching in views
483
+ <% cache @product do %>
484
+ <% @product.variants.each do |variant| %>
485
+ <% cache variant do %>
486
+ <%= render variant %>
487
+ <% end %>
488
+ <% end %>
489
+ <% end %>
490
+ ```
491
+
492
+ ### Memoization Patterns
493
+ ```ruby
494
+ # Class-level memoization for constants
495
+ class TaxCalculator
496
+ def self.rates
497
+ @rates ||= TaxRate.all.index_by(&:region).freeze
498
+ end
499
+ end
500
+
501
+ # Thread-safe memoization
502
+ class Configuration
503
+ def self.settings
504
+ @settings_mutex ||= Mutex.new
505
+ @settings ||= @settings_mutex.synchronize do
506
+ @settings || load_settings
507
+ end
508
+ end
509
+ end
510
+
511
+ # Per-request memoization (Rails)
512
+ class ApplicationController
513
+ def current_user
514
+ @current_user ||= User.find(session[:user_id])
515
+ end
516
+ end
517
+ ```
518
+
519
+ ---
520
+
521
+ ## Data Structures
522
+
523
+ ### Stack (LIFO)
524
+ ```ruby
525
+ # Using Array as stack
526
+ stack = []
527
+ stack.push(1) # Add to top
528
+ stack.push(2)
529
+ stack.push(3)
530
+ stack.pop # => 3 (remove from top)
531
+ stack.last # => 2 (peek)
532
+ stack.empty? # => false
533
+
534
+ # Use case: parsing nested structures
535
+ def valid_parentheses?(string)
536
+ stack = []
537
+ pairs = { ")" => "(", "]" => "[", "}" => "{" }
538
+
539
+ string.each_char do |char|
540
+ if pairs.values.include?(char)
541
+ stack.push(char)
542
+ elsif pairs.keys.include?(char)
543
+ return false if stack.pop != pairs[char]
544
+ end
545
+ end
546
+
547
+ stack.empty?
548
+ end
549
+
550
+ valid_parentheses?("([{}])") # => true
551
+ valid_parentheses?("([)]") # => false
552
+ ```
553
+
554
+ ### Queue (FIFO)
555
+ ```ruby
556
+ # Using Array as queue (inefficient for large queues)
557
+ queue = []
558
+ queue.push(1) # Enqueue
559
+ queue.push(2)
560
+ queue.shift # => 1 (dequeue)
561
+
562
+ # Better: Use Queue class for thread safety
563
+ require 'thread'
564
+ queue = Queue.new
565
+ queue << 1 # Enqueue
566
+ queue.pop # Dequeue (blocks if empty)
567
+ queue.pop(true) # Non-blocking (raises if empty)
568
+
569
+ # Use case: BFS traversal
570
+ def breadth_first_search(root, target)
571
+ queue = [root]
572
+
573
+ while queue.any?
574
+ node = queue.shift
575
+ return node if node.value == target
576
+ queue.concat(node.children)
577
+ end
578
+
579
+ nil
580
+ end
581
+ ```
582
+
583
+ ### Linked List
584
+ ```ruby
585
+ # Ruby arrays are dynamic, but linked lists are useful to understand
586
+ class Node
587
+ attr_accessor :value, :next_node
588
+
589
+ def initialize(value)
590
+ @value = value
591
+ @next_node = nil
592
+ end
593
+ end
594
+
595
+ class LinkedList
596
+ def initialize
597
+ @head = nil
598
+ end
599
+
600
+ def append(value)
601
+ new_node = Node.new(value)
602
+ if @head.nil?
603
+ @head = new_node
604
+ else
605
+ current = @head
606
+ current = current.next_node while current.next_node
607
+ current.next_node = new_node
608
+ end
609
+ end
610
+
611
+ def each
612
+ current = @head
613
+ while current
614
+ yield current.value
615
+ current = current.next_node
616
+ end
617
+ end
618
+ end
619
+ ```
620
+
621
+ ### Tree
622
+ ```ruby
623
+ class TreeNode
624
+ attr_accessor :value, :children
625
+
626
+ def initialize(value)
627
+ @value = value
628
+ @children = []
629
+ end
630
+
631
+ def add_child(value)
632
+ child = TreeNode.new(value)
633
+ @children << child
634
+ child
635
+ end
636
+
637
+ # Depth-first traversal
638
+ def each_dfs(&block)
639
+ block.call(self)
640
+ @children.each { |child| child.each_dfs(&block) }
641
+ end
642
+
643
+ # Breadth-first traversal
644
+ def each_bfs
645
+ queue = [self]
646
+ while queue.any?
647
+ node = queue.shift
648
+ yield node
649
+ queue.concat(node.children)
650
+ end
651
+ end
652
+ end
653
+
654
+ # Binary Tree
655
+ class BinaryTreeNode
656
+ attr_accessor :value, :left, :right
657
+
658
+ def initialize(value)
659
+ @value = value
660
+ end
661
+
662
+ # In-order traversal (left, root, right)
663
+ def in_order(&block)
664
+ @left&.in_order(&block)
665
+ block.call(@value)
666
+ @right&.in_order(&block)
667
+ end
668
+
669
+ # Pre-order traversal (root, left, right)
670
+ def pre_order(&block)
671
+ block.call(@value)
672
+ @left&.pre_order(&block)
673
+ @right&.pre_order(&block)
674
+ end
675
+
676
+ # Post-order traversal (left, right, root)
677
+ def post_order(&block)
678
+ @left&.post_order(&block)
679
+ @right&.post_order(&block)
680
+ block.call(@value)
681
+ end
682
+ end
683
+ ```
684
+
685
+ ### Graph
686
+ ```ruby
687
+ class Graph
688
+ def initialize
689
+ @adjacency_list = Hash.new { |h, k| h[k] = [] }
690
+ end
691
+
692
+ def add_edge(from, to, directed: false)
693
+ @adjacency_list[from] << to
694
+ @adjacency_list[to] << from unless directed
695
+ end
696
+
697
+ def neighbors(node)
698
+ @adjacency_list[node]
699
+ end
700
+
701
+ # Breadth-First Search
702
+ def bfs(start)
703
+ visited = Set.new([start])
704
+ queue = [start]
705
+ result = []
706
+
707
+ while queue.any?
708
+ node = queue.shift
709
+ result << node
710
+
711
+ neighbors(node).each do |neighbor|
712
+ unless visited.include?(neighbor)
713
+ visited << neighbor
714
+ queue << neighbor
715
+ end
716
+ end
717
+ end
718
+
719
+ result
720
+ end
721
+
722
+ # Depth-First Search
723
+ def dfs(start, visited = Set.new)
724
+ return [] if visited.include?(start)
725
+
726
+ visited << start
727
+ result = [start]
728
+
729
+ neighbors(start).each do |neighbor|
730
+ result.concat(dfs(neighbor, visited))
731
+ end
732
+
733
+ result
734
+ end
735
+ end
736
+
737
+ # Usage
738
+ graph = Graph.new
739
+ graph.add_edge("A", "B")
740
+ graph.add_edge("A", "C")
741
+ graph.add_edge("B", "D")
742
+ graph.add_edge("C", "D")
743
+
744
+ graph.bfs("A") # => ["A", "B", "C", "D"]
745
+ graph.dfs("A") # => ["A", "B", "D", "C"]
746
+ ```
747
+
748
+ ---
749
+
750
+ ## Ruby Collections
751
+
752
+ ### Set
753
+ ```ruby
754
+ require 'set'
755
+
756
+ # Create a set
757
+ set = Set.new([1, 2, 3, 2, 1]) # => #<Set: {1, 2, 3}>
758
+
759
+ # Operations - all O(1) average
760
+ set.add(4) # Add element
761
+ set.delete(2) # Remove element
762
+ set.include?(3) # Check membership
763
+
764
+ # Set operations
765
+ a = Set.new([1, 2, 3])
766
+ b = Set.new([2, 3, 4])
767
+
768
+ a | b # Union: {1, 2, 3, 4}
769
+ a & b # Intersection: {2, 3}
770
+ a - b # Difference: {1}
771
+ a ^ b # Symmetric difference: {1, 4}
772
+
773
+ # Use case: efficient membership checking
774
+ valid_statuses = Set.new(%w[pending active completed])
775
+ valid_statuses.include?(params[:status])
776
+
777
+ # Use case: removing duplicates while preserving order
778
+ array = [3, 1, 2, 1, 3]
779
+ Set.new(array).to_a # => [3, 1, 2]
780
+ # Or simply:
781
+ array.uniq # => [3, 1, 2]
782
+ ```
783
+
784
+ ### SortedSet (Removed in Ruby 3.0+)
785
+ ```ruby
786
+ # For sorted sets, use a sorted array or gem
787
+ # Or implement with binary search insertion
788
+
789
+ class SortedArray
790
+ def initialize
791
+ @array = []
792
+ end
793
+
794
+ def add(value)
795
+ index = @array.bsearch_index { |x| x >= value } || @array.length
796
+ @array.insert(index, value)
797
+ end
798
+
799
+ def include?(value)
800
+ @array.bsearch { |x| x <=> value }
801
+ end
802
+
803
+ def to_a
804
+ @array.dup
805
+ end
806
+ end
807
+ ```
808
+
809
+ ---
810
+
811
+ ## Rails-Specific Optimizations
812
+
813
+ ### Efficient Queries
814
+ ```ruby
815
+ # Bad: N+1 query
816
+ users.each do |user|
817
+ puts user.orders.count # Query for each user
818
+ end
819
+
820
+ # Good: Eager loading
821
+ users = User.includes(:orders)
822
+ users.each do |user|
823
+ puts user.orders.size # No additional queries
824
+ end
825
+
826
+ # Better: Counter cache
827
+ # In migration
828
+ add_column :users, :orders_count, :integer, default: 0
829
+ User.reset_counters(user.id, :orders)
830
+
831
+ # In model
832
+ class Order < ApplicationRecord
833
+ belongs_to :user, counter_cache: true
834
+ end
835
+
836
+ # Now O(1) to get count
837
+ user.orders_count
838
+ ```
839
+
840
+ ### Batch Processing
841
+ ```ruby
842
+ # Bad: Loads all records into memory
843
+ User.all.each { |user| process(user) }
844
+
845
+ # Good: Process in batches
846
+ User.find_each(batch_size: 1000) do |user|
847
+ process(user)
848
+ end
849
+
850
+ # With conditions
851
+ User.where(active: true).find_each do |user|
852
+ process(user)
853
+ end
854
+
855
+ # Parallel processing with batches
856
+ User.in_batches(of: 1000) do |batch|
857
+ batch.update_all(processed: true)
858
+ end
859
+
860
+ # For large exports
861
+ def export_users_csv
862
+ CSV.generate do |csv|
863
+ csv << %w[id email name]
864
+ User.find_each do |user|
865
+ csv << [user.id, user.email, user.name]
866
+ end
867
+ end
868
+ end
869
+ ```
870
+
871
+ ### Pluck vs Select
872
+ ```ruby
873
+ # select loads ActiveRecord objects
874
+ emails = User.select(:email).map(&:email) # Creates User objects
875
+
876
+ # pluck returns just the values
877
+ emails = User.pluck(:email) # Just array of strings
878
+
879
+ # Multiple columns
880
+ data = User.pluck(:id, :email, :name)
881
+ # => [[1, "a@b.com", "Alice"], [2, "c@d.com", "Bob"]]
882
+
883
+ # For calculations
884
+ User.count # COUNT(*)
885
+ User.sum(:balance) # SUM(balance)
886
+ User.average(:age) # AVG(age)
887
+ User.maximum(:age) # MAX(age)
888
+ User.minimum(:created_at)# MIN(created_at)
889
+ ```
890
+
891
+ ### Index Optimization
892
+ ```ruby
893
+ # Add indexes for:
894
+ # 1. Foreign keys
895
+ add_index :orders, :user_id
896
+
897
+ # 2. Columns used in WHERE clauses
898
+ add_index :users, :email
899
+ add_index :users, :status
900
+
901
+ # 3. Columns used in ORDER BY
902
+ add_index :posts, :created_at
903
+
904
+ # 4. Composite indexes for common query patterns
905
+ add_index :orders, [:user_id, :created_at]
906
+ add_index :products, [:category_id, :price]
907
+
908
+ # 5. Partial indexes for filtered queries
909
+ add_index :users, :email, where: "active = true"
910
+
911
+ # Check if query uses index
912
+ User.where(email: "test@example.com").explain
913
+ ```
914
+
915
+ ### Avoiding Common Performance Issues
916
+ ```ruby
917
+ # Issue: String concatenation in loops
918
+ # Bad
919
+ result = ""
920
+ 1000.times { |i| result += i.to_s }
921
+
922
+ # Good
923
+ result = []
924
+ 1000.times { |i| result << i.to_s }
925
+ result.join
926
+
927
+ # Issue: Repeated calculations
928
+ # Bad
929
+ orders.each do |order|
930
+ tax_rate = TaxService.fetch_rate(order.region) # Called each time
931
+ order.update(tax: order.total * tax_rate)
932
+ end
933
+
934
+ # Good
935
+ rates = TaxService.fetch_all_rates
936
+ orders.each do |order|
937
+ order.update(tax: order.total * rates[order.region])
938
+ end
939
+
940
+ # Issue: Loading unnecessary data
941
+ # Bad
942
+ user = User.find(id) # Loads all columns
943
+ user.email
944
+
945
+ # Good
946
+ email = User.where(id: id).pick(:email) # Just one column, one value
947
+
948
+ # Issue: Serialization in hot paths
949
+ # Bad
950
+ class User < ApplicationRecord
951
+ serialize :preferences, coder: JSON # Parsing on every access
952
+ end
953
+
954
+ # Good: Use jsonb column (PostgreSQL) or separate table
955
+ ```
956
+
957
+ ### Algorithm Selection Guide
958
+
959
+ | Problem | Best Approach | Time |
960
+ |---------|--------------|------|
961
+ | Check if item exists | Hash/Set | O(1) |
962
+ | Find item by key | Hash | O(1) |
963
+ | Find item in sorted list | Binary search | O(log n) |
964
+ | Find item in unsorted list | Linear search | O(n) |
965
+ | Sort data | sort/sort_by | O(n log n) |
966
+ | Process all items | Each/map | O(n) |
967
+ | Find duplicates | Hash/Set | O(n) |
968
+ | Top K items | Partial sort | O(n log k) |
969
+ | Sliding window | Two pointers | O(n) |
970
+ | Tree/graph traversal | BFS/DFS | O(V + E) |