@tomaszjarosz/react-visualizers 0.1.4 → 0.2.1

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.
package/dist/index.cjs CHANGED
@@ -3512,7 +3512,7 @@ const DPVisualizerComponent = ({
3512
3512
  showCode = true,
3513
3513
  className = ""
3514
3514
  }) => {
3515
- var _a;
3515
+ var _a, _b, _c;
3516
3516
  const [items] = React.useState(DEFAULT_ITEMS);
3517
3517
  const [capacity] = React.useState(DEFAULT_CAPACITY);
3518
3518
  const [speed, setSpeed] = React.useState(25);
@@ -3636,33 +3636,83 @@ const DPVisualizerComponent = ({
3636
3636
  ] })
3637
3637
  ] }) }) }),
3638
3638
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
3639
- /* @__PURE__ */ jsxRuntime.jsxs(VisualizationArea, { minHeight: 400, children: [
3639
+ /* @__PURE__ */ jsxRuntime.jsxs(VisualizationArea, { minHeight: 450, className: "flex-1 min-w-0", children: [
3640
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 p-4 bg-gradient-to-r from-teal-50 to-cyan-50 rounded-xl border-2 border-teal-200", children: [
3641
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-semibold text-teal-800 mb-3", children: "DP Recurrence Formula" }),
3642
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-sm bg-white rounded-lg p-3 border border-teal-200", children: [
3643
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-gray-600 mb-2", children: [
3644
+ "dp[i][w] = max(",
3645
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-yellow-600 font-bold", children: " skip" }),
3646
+ ",",
3647
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-green-600 font-bold", children: " take" }),
3648
+ ")"
3649
+ ] }),
3650
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4 text-xs mt-3", children: [
3651
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-yellow-50 p-2 rounded border border-yellow-200", children: [
3652
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-yellow-700 font-bold", children: "skip" }),
3653
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-600", children: " = dp[i-1][w]" }),
3654
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-500 mt-1", children: "Don't take item i" })
3655
+ ] }),
3656
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-green-50 p-2 rounded border border-green-200", children: [
3657
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-green-700 font-bold", children: "take" }),
3658
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-600", children: " = dp[i-1][w-weight] + value" }),
3659
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-500 mt-1", children: "Take item i" })
3660
+ ] })
3661
+ ] })
3662
+ ] }),
3663
+ currentI > 0 && currentW > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 p-3 bg-white rounded-lg border-2 border-purple-300", children: [
3664
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-semibold text-purple-800 mb-2", children: [
3665
+ "Current: dp[",
3666
+ currentI,
3667
+ "][",
3668
+ currentW,
3669
+ "]"
3670
+ ] }),
3671
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-sm", children: [
3672
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-gray-600", children: [
3673
+ "Item ",
3674
+ currentI,
3675
+ ": ",
3676
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
3677
+ "w=",
3678
+ (_b = items[currentI - 1]) == null ? void 0 : _b.weight,
3679
+ ", v=",
3680
+ (_c = items[currentI - 1]) == null ? void 0 : _c.value
3681
+ ] })
3682
+ ] }),
3683
+ decision && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `px-3 py-1 rounded-full font-bold ${decision === "take" ? "bg-green-100 text-green-700" : "bg-yellow-100 text-yellow-700"}`, children: decision === "take" ? "✓ TAKE" : "✗ SKIP" })
3684
+ ] })
3685
+ ] })
3686
+ ] }),
3640
3687
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-6", children: [
3641
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-36", children: [
3642
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Items:" }),
3688
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-40", children: [
3689
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Items (i = item index):" }),
3643
3690
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-1", children: items.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
3644
3691
  "div",
3645
3692
  {
3646
- className: `px-2 py-1 rounded text-xs ${idx + 1 === currentI ? "bg-purple-100 text-purple-800 font-medium" : idx + 1 < currentI ? "bg-blue-50 text-blue-600" : "bg-gray-100 text-gray-500"}`,
3693
+ className: `px-2 py-1.5 rounded text-xs transition-colors ${idx + 1 === currentI ? "bg-purple-200 text-purple-900 font-bold ring-2 ring-purple-400" : idx + 1 < currentI ? "bg-blue-50 text-blue-600" : "bg-gray-100 text-gray-500"}`,
3647
3694
  children: [
3648
- "Item ",
3649
- idx + 1,
3695
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono", children: [
3696
+ "i=",
3697
+ idx + 1
3698
+ ] }),
3650
3699
  ": w=",
3651
3700
  item.weight,
3652
3701
  ", v=",
3653
- item.value
3702
+ item.value,
3703
+ idx + 1 === currentI && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1", children: "← CURRENT" })
3654
3704
  ]
3655
3705
  },
3656
3706
  idx
3657
3707
  )) }),
3658
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 text-sm", children: [
3659
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-700", children: "Capacity:" }),
3708
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 text-sm p-2 bg-gray-100 rounded", children: [
3709
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-gray-700", children: "Max Capacity:" }),
3660
3710
  " ",
3661
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-900", children: capacity })
3711
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-900 font-mono", children: capacity })
3662
3712
  ] })
3663
3713
  ] }),
3664
3714
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-x-auto", children: [
3665
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "DP Table:" }),
3715
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "DP Table (w = current capacity):" }),
3666
3716
  /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "text-xs border-collapse", children: [
3667
3717
  /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
3668
3718
  /* @__PURE__ */ jsxRuntime.jsx("th", { className: "w-8 p-1 text-gray-500 font-normal", children: "i\\w" }),
@@ -4782,20 +4832,6 @@ const HashTableVisualizerComponent = ({
4782
4832
  key: ""
4783
4833
  };
4784
4834
  const { operation, buckets, bucketIndex, key } = currentStepData;
4785
- const getBucketStyle = (index) => {
4786
- if (index === bucketIndex) {
4787
- if (operation === "collision") return "border-red-400 bg-red-50";
4788
- if (operation === "placed") return "border-green-400 bg-green-50";
4789
- if (operation === "insert") return "border-yellow-400 bg-yellow-50";
4790
- }
4791
- return "border-gray-300 bg-gray-50";
4792
- };
4793
- const getKeyStyle = (bucketKey) => {
4794
- if (bucketKey === key && (operation === "placed" || operation === "insert")) {
4795
- return "bg-yellow-200 text-yellow-900 border-yellow-400";
4796
- }
4797
- return "bg-blue-100 text-blue-800 border-blue-300";
4798
- };
4799
4835
  const currentDescription = ((_a = steps[currentStep]) == null ? void 0 : _a.description) || "";
4800
4836
  return /* @__PURE__ */ jsxRuntime.jsxs(
4801
4837
  "div",
@@ -4810,60 +4846,109 @@ const HashTableVisualizerComponent = ({
4810
4846
  ] })
4811
4847
  ] }) }) }),
4812
4848
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex gap-4 ${showCode ? "flex-col lg:flex-row" : ""}`, children: [
4813
- /* @__PURE__ */ jsxRuntime.jsxs(VisualizationArea, { minHeight: 350, className: "flex-1 min-w-0", children: [
4814
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
4849
+ /* @__PURE__ */ jsxRuntime.jsxs(VisualizationArea, { minHeight: 400, className: "flex-1 min-w-0", children: [
4850
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
4815
4851
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-2", children: "Keys to insert:" }),
4816
4852
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: keys.map((k, idx) => {
4817
4853
  const isInserted = steps.slice(0, currentStep + 1).some((s) => s.key === k && s.operation === "placed");
4818
4854
  return /* @__PURE__ */ jsxRuntime.jsx(
4819
4855
  "span",
4820
4856
  {
4821
- className: `px-2 py-1 text-xs rounded border ${isInserted ? "bg-green-100 text-green-700 border-green-300" : k === key ? "bg-yellow-100 text-yellow-700 border-yellow-300" : "bg-gray-100 text-gray-600 border-gray-300"}`,
4857
+ className: `px-3 py-1.5 text-sm font-medium rounded-lg border-2 transition-colors ${isInserted ? "bg-green-100 text-green-700 border-green-400" : k === key ? "bg-yellow-100 text-yellow-700 border-yellow-400 ring-2 ring-yellow-300" : "bg-gray-50 text-gray-600 border-gray-300"}`,
4822
4858
  children: k
4823
4859
  },
4824
4860
  idx
4825
4861
  );
4826
4862
  }) })
4827
4863
  ] }),
4828
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4", children: [
4829
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-medium text-gray-700 mb-2", children: [
4864
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6 p-4 bg-gradient-to-r from-violet-50 to-purple-50 rounded-xl border-2 border-violet-200 min-h-[80px]", children: [
4865
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-semibold text-violet-800 mb-2", children: "Hash Calculation" }),
4866
+ operation === "insert" && key ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
4867
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-lg text-gray-800", children: [
4868
+ "hash(",
4869
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-violet-600 font-bold", children: [
4870
+ '"',
4871
+ key,
4872
+ '"'
4873
+ ] }),
4874
+ ") % ",
4875
+ buckets.length,
4876
+ " = ",
4877
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-violet-600 font-bold text-xl", children: bucketIndex })
4878
+ ] }),
4879
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-violet-600 text-2xl animate-bounce", children: "↓" })
4880
+ ] }) : operation === "collision" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
4881
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-lg text-red-700", children: [
4882
+ "Collision at bucket ",
4883
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold", children: [
4884
+ "[",
4885
+ bucketIndex,
4886
+ "]"
4887
+ ] }),
4888
+ "! Adding to chain..."
4889
+ ] }),
4890
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-red-500 text-2xl", children: "⚠️" })
4891
+ ] }) : operation === "placed" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
4892
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-mono text-lg text-green-700", children: [
4893
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold", children: [
4894
+ '"',
4895
+ key,
4896
+ '"'
4897
+ ] }),
4898
+ " placed in bucket ",
4899
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-bold", children: [
4900
+ "[",
4901
+ bucketIndex,
4902
+ "]"
4903
+ ] })
4904
+ ] }),
4905
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-green-500 text-2xl", children: "✓" })
4906
+ ] }) : operation === "rehash" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
4907
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-lg text-orange-700", children: "Rehashing: expanding table..." }),
4908
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-orange-500 text-2xl", children: "🔄" })
4909
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-400 text-center", children: "Click Play to start visualization" })
4910
+ ] }),
4911
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
4912
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-medium text-gray-700 mb-3", children: [
4830
4913
  "Hash Table (",
4831
4914
  buckets.length,
4832
4915
  " buckets):"
4833
4916
  ] }),
4834
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-4 gap-2", children: buckets.map((bucket, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
4917
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-x-auto pb-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1", style: { minWidth: "max-content" }, children: buckets.map((bucket, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
4835
4918
  "div",
4836
4919
  {
4837
- className: `p-2 rounded border-2 min-h-[60px] transition-colors ${getBucketStyle(idx)}`,
4920
+ className: "flex flex-col items-center",
4921
+ style: { minWidth: "70px" },
4838
4922
  children: [
4839
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs font-mono text-gray-500 mb-1", children: [
4840
- "[",
4841
- idx,
4842
- "]"
4843
- ] }),
4844
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: bucket.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400 italic", children: "empty" }) : bucket.map((bucketKey, keyIdx) => /* @__PURE__ */ jsxRuntime.jsx(
4845
- "span",
4923
+ /* @__PURE__ */ jsxRuntime.jsxs(
4924
+ "div",
4846
4925
  {
4847
- className: `px-1.5 py-0.5 text-xs rounded border ${getKeyStyle(bucketKey)}`,
4848
- children: bucketKey
4849
- },
4850
- keyIdx
4851
- )) })
4926
+ className: `w-full text-center py-1 px-2 rounded-t-lg font-mono text-sm font-bold transition-colors ${idx === bucketIndex ? operation === "collision" ? "bg-red-500 text-white" : operation === "placed" ? "bg-green-500 text-white" : "bg-yellow-400 text-yellow-900" : "bg-gray-200 text-gray-600"}`,
4927
+ children: [
4928
+ "[",
4929
+ idx,
4930
+ "]"
4931
+ ]
4932
+ }
4933
+ ),
4934
+ /* @__PURE__ */ jsxRuntime.jsx(
4935
+ "div",
4936
+ {
4937
+ className: `w-full border-2 rounded-b-lg min-h-[100px] p-1 transition-colors ${idx === bucketIndex ? operation === "collision" ? "border-red-400 bg-red-50" : operation === "placed" ? "border-green-400 bg-green-50" : "border-yellow-400 bg-yellow-50" : "border-gray-300 bg-gray-50"}`,
4938
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-1", children: bucket.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-400 italic text-center py-2", children: "empty" }) : bucket.map((bucketKey, keyIdx) => /* @__PURE__ */ jsxRuntime.jsx(
4939
+ "div",
4940
+ {
4941
+ className: `px-2 py-1 text-xs font-medium rounded border text-center transition-colors ${bucketKey === key && (operation === "placed" || operation === "insert") ? "bg-yellow-200 text-yellow-900 border-yellow-400" : "bg-blue-100 text-blue-800 border-blue-300"}`,
4942
+ children: bucketKey
4943
+ },
4944
+ keyIdx
4945
+ )) })
4946
+ }
4947
+ )
4852
4948
  ]
4853
4949
  },
4854
4950
  idx
4855
- )) })
4856
- ] }),
4857
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 p-3 bg-gray-100 rounded-lg min-h-[52px]", children: [
4858
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-700 mb-1", children: "Hash Calculation:" }),
4859
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-mono text-sm", children: operation === "insert" && key ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
4860
- 'hash("',
4861
- key,
4862
- '") mod ',
4863
- buckets.length,
4864
- " = ",
4865
- bucketIndex
4866
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-400", children: "—" }) })
4951
+ )) }) })
4867
4952
  ] }),
4868
4953
  /* @__PURE__ */ jsxRuntime.jsx(
4869
4954
  StatusPanel,