feat(viz): interactive algorithm viz system
This commit is contained in:
33
backend/alembic/versions/005_add_visualization_examples.py
Normal file
33
backend/alembic/versions/005_add_visualization_examples.py
Normal file
@@ -0,0 +1,33 @@
|
||||
"""add visualization examples to patterns
|
||||
|
||||
Revision ID: 005
|
||||
Revises: 004
|
||||
Create Date: 2025-05-10
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
revision: str = "005"
|
||||
down_revision: str | None = "004"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column(
|
||||
"patterns",
|
||||
sa.Column(
|
||||
"visualization_examples",
|
||||
postgresql.JSONB(astext_type=sa.Text()),
|
||||
nullable=True,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_column("patterns", "visualization_examples")
|
||||
@@ -164,3 +164,116 @@ related_patterns:
|
||||
- binary-search
|
||||
|
||||
prerequisite_patterns: []
|
||||
|
||||
visualization_examples:
|
||||
- id: "find-pair-sum"
|
||||
title: "Find pair with sum = 10"
|
||||
input:
|
||||
array: [1, 2, 4, 6, 8, 10]
|
||||
target: 10
|
||||
code: |
|
||||
left, right = 0, len(arr) - 1
|
||||
while left < right:
|
||||
curr = arr[left] + arr[right]
|
||||
if curr == target:
|
||||
return [left, right]
|
||||
elif curr < target:
|
||||
left += 1
|
||||
else:
|
||||
right -= 1
|
||||
steps:
|
||||
- id: "1"
|
||||
description: "Initialize pointers at both ends of the sorted array. Left starts at index 0 (value 1), right starts at index 5 (value 10)."
|
||||
structures:
|
||||
array:
|
||||
type: array
|
||||
values:
|
||||
- { value: 1, state: active, annotations: ["L"] }
|
||||
- { value: 2, state: default }
|
||||
- { value: 4, state: default }
|
||||
- { value: 6, state: default }
|
||||
- { value: 8, state: default }
|
||||
- { value: 10, state: active, annotations: ["R"] }
|
||||
pointers: { left: 0, right: 5 }
|
||||
variables: { left: 0, right: 5, target: 10 }
|
||||
codeHighlight: { startLine: 1, endLine: 1 }
|
||||
|
||||
- id: "2"
|
||||
description: "Calculate current sum: 1 + 10 = 11. This is greater than target (10), so we need a smaller sum. Move right pointer left."
|
||||
structures:
|
||||
array:
|
||||
type: array
|
||||
values:
|
||||
- { value: 1, state: comparing, annotations: ["L"] }
|
||||
- { value: 2, state: default }
|
||||
- { value: 4, state: default }
|
||||
- { value: 6, state: default }
|
||||
- { value: 8, state: default }
|
||||
- { value: 10, state: comparing, annotations: ["R"] }
|
||||
pointers: { left: 0, right: 5 }
|
||||
variables: { left: 0, right: 5, curr: 11, target: 10 }
|
||||
codeHighlight: { startLine: 3, endLine: 8 }
|
||||
|
||||
- id: "3"
|
||||
description: "Right pointer moved to index 4 (value 8). Now checking new sum."
|
||||
structures:
|
||||
array:
|
||||
type: array
|
||||
values:
|
||||
- { value: 1, state: active, annotations: ["L"] }
|
||||
- { value: 2, state: default }
|
||||
- { value: 4, state: default }
|
||||
- { value: 6, state: default }
|
||||
- { value: 8, state: active, annotations: ["R"] }
|
||||
- { value: 10, state: visited }
|
||||
pointers: { left: 0, right: 4 }
|
||||
variables: { left: 0, right: 4, target: 10 }
|
||||
codeHighlight: { startLine: 8, endLine: 8 }
|
||||
|
||||
- id: "4"
|
||||
description: "Calculate current sum: 1 + 8 = 9. This is less than target (10), so we need a larger sum. Move left pointer right."
|
||||
structures:
|
||||
array:
|
||||
type: array
|
||||
values:
|
||||
- { value: 1, state: comparing, annotations: ["L"] }
|
||||
- { value: 2, state: default }
|
||||
- { value: 4, state: default }
|
||||
- { value: 6, state: default }
|
||||
- { value: 8, state: comparing, annotations: ["R"] }
|
||||
- { value: 10, state: visited }
|
||||
pointers: { left: 0, right: 4 }
|
||||
variables: { left: 0, right: 4, curr: 9, target: 10 }
|
||||
codeHighlight: { startLine: 3, endLine: 7 }
|
||||
|
||||
- id: "5"
|
||||
description: "Left pointer moved to index 1 (value 2). Now checking new sum."
|
||||
structures:
|
||||
array:
|
||||
type: array
|
||||
values:
|
||||
- { value: 1, state: visited }
|
||||
- { value: 2, state: active, annotations: ["L"] }
|
||||
- { value: 4, state: default }
|
||||
- { value: 6, state: default }
|
||||
- { value: 8, state: active, annotations: ["R"] }
|
||||
- { value: 10, state: visited }
|
||||
pointers: { left: 1, right: 4 }
|
||||
variables: { left: 1, right: 4, target: 10 }
|
||||
codeHighlight: { startLine: 7, endLine: 7 }
|
||||
|
||||
- id: "6"
|
||||
description: "Calculate current sum: 2 + 8 = 10. This equals the target! We found our pair at indices [1, 4]."
|
||||
structures:
|
||||
array:
|
||||
type: array
|
||||
values:
|
||||
- { value: 1, state: visited }
|
||||
- { value: 2, state: found, annotations: ["L"] }
|
||||
- { value: 4, state: default }
|
||||
- { value: 6, state: default }
|
||||
- { value: 8, state: found, annotations: ["R"] }
|
||||
- { value: 10, state: visited }
|
||||
pointers: { left: 1, right: 4 }
|
||||
variables: { left: 1, right: 4, curr: 10, target: 10 }
|
||||
codeHighlight: { startLine: 4, endLine: 5 }
|
||||
|
||||
@@ -130,6 +130,9 @@ async def _upsert_pattern(session: AsyncSession, item: dict[str, Any]) -> Patter
|
||||
# Difficulty level
|
||||
pattern.difficulty_level = item.get("difficulty_level")
|
||||
|
||||
# Interactive visualization examples
|
||||
pattern.visualization_examples = item.get("visualization_examples")
|
||||
|
||||
return pattern
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user