<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: DHEERAJ KUMAR</title>
    <description>The latest articles on Forem by DHEERAJ KUMAR (@dheeraj_kumar_99ad161d4e8).</description>
    <link>https://forem.com/dheeraj_kumar_99ad161d4e8</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3595362%2Fcbc3934c-e090-43b8-a0be-1eb9f3a812b7.jpg</url>
      <title>Forem: DHEERAJ KUMAR</title>
      <link>https://forem.com/dheeraj_kumar_99ad161d4e8</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dheeraj_kumar_99ad161d4e8"/>
    <language>en</language>
    <item>
      <title>Adaptive Sorting Visualizer</title>
      <dc:creator>DHEERAJ KUMAR</dc:creator>
      <pubDate>Tue, 04 Nov 2025 08:21:31 +0000</pubDate>
      <link>https://forem.com/dheeraj_kumar_99ad161d4e8/adaptive-sorting-visualizer-5b95</link>
      <guid>https://forem.com/dheeraj_kumar_99ad161d4e8/adaptive-sorting-visualizer-5b95</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask import Flask, render_template_string, request, jsonify
import csv, io, time

app = Flask(__name__)

# ================= SORTING LOGIC =====================

def bubble_sort(a):
    arr = a[:]; ops = []; comps = swaps = 0
    n = len(arr)
    for i in range(n-1):
        for j in range(n-i-1):
            ops.append({"type":"compare","i":j,"j":j+1}); comps += 1
            if arr[j] &amp;gt; arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
                ops.append({"type":"swap","i":j,"j":j+1}); swaps += 1
    return arr, ops, comps, swaps

def insertion_sort(a):
    arr = a[:]; ops = []; comps = swaps = 0
    for i in range(1,len(arr)):
        key = arr[i]; j = i-1
        while j &amp;gt;= 0:
            ops.append({"type":"compare","i":j,"j":i}); comps += 1
            if arr[j] &amp;gt; key:
                arr[j+1] = arr[j]
                ops.append({"type":"overwrite","i":j+1,"value":arr[j]})
                swaps += 1; j -= 1
            else: break
        arr[j+1] = key
        ops.append({"type":"overwrite","i":j+1,"value":key})
    return arr, ops, comps, swaps

def quick_sort(a):
    arr=a[:]; ops=[]; comps=swaps=0
    def partition(l,h):
        nonlocal comps,swaps
        pivot=arr[h]; i=l-1
        for j in range(l,h):
            ops.append({"type":"compare","i":j,"j":h}); comps+=1
            if arr[j]&amp;lt;pivot:
                i+=1; arr[i],arr[j]=arr[j],arr[i]
                ops.append({"type":"swap","i":i,"j":j}); swaps+=1
        arr[i+1],arr[h]=arr[h],arr[i+1]
        ops.append({"type":"swap","i":i+1,"j":h}); swaps+=1
        return i+1
    def q(l,h):
        if l&amp;lt;h:
            p=partition(l,h); q(l,p-1); q(p+1,h)
    if len(arr)&amp;gt;0:q(0,len(arr)-1)
    return arr,ops,comps,swaps

def merge_sort(a):
    arr=a[:]; ops=[]; comps=swaps=0
    def merge(l,m,r):
        nonlocal comps,swaps
        L,R=arr[l:m+1],arr[m+1:r+1]; i=j=0; k=l
        while i&amp;lt;len(L) and j&amp;lt;len(R):
            ops.append({"type":"compare","i":l+i,"j":m+1+j}); comps+=1
            if L[i]&amp;lt;=R[j]:
                arr[k]=L[i]; ops.append({"type":"overwrite","i":k,"value":L[i]}); i+=1
            else:
                arr[k]=R[j]; ops.append({"type":"overwrite","i":k,"value":R[j]}); j+=1
            swaps+=1; k+=1
        while i&amp;lt;len(L):
            arr[k]=L[i]; ops.append({"type":"overwrite","i":k,"value":L[i]})
            i+=1; k+=1; swaps+=1
        while j&amp;lt;len(R):
            arr[k]=R[j]; ops.append({"type":"overwrite","i":k,"value":R[j]})
            j+=1; k+=1; swaps+=1
    def m(l,r):
        if l&amp;lt;r:
            mid=(l+r)//2; m(l,mid); m(mid+1,r); merge(l,mid,r)
    if len(arr)&amp;gt;0:m(0,len(arr)-1)
    return arr,ops,comps,swaps

THEORY = {
    "bubble":{"time":"O(n²)","space":"O(1)","stable":"Yes"},
    "insertion":{"time":"O(n)","space":"O(1)","stable":"Yes"},
    "quick":{"time":"O(n log n)","space":"O(log n)","stable":"No"},
    "merge":{"time":"O(n log n)","space":"O(n)","stable":"Yes"}
}

# ================= FLASK ROUTES =====================
@app.route("/")
def index():
    return render_template_string("""
&amp;lt;!DOCTYPE html&amp;gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;meta charset="utf-8"&amp;gt;
&amp;lt;title&amp;gt;Adaptive Sorting Visualizer (CSV Upload)&amp;lt;/title&amp;gt;
&amp;lt;style&amp;gt;
body{background:#0f172a;color:#f8fafc;text-align:center;font-family:Arial}
#bars{display:flex;align-items:flex-end;justify-content:center;height:400px;margin:20px;gap:4px}
.bar-container{display:flex;flex-direction:column;align-items:center;justify-content:flex-end}
.bar{background:#38bdf8;width:12px;transition:all .1s}
.bar-value{color:#f8fafc;font-size:10px;margin-top:2px}
.bar.comp{background:#facc15}
.bar.swap{background:#ef4444}
input,button{padding:8px;margin:5px;border:none;border-radius:6px}
button{background:#38bdf8;font-weight:bold;cursor:pointer}
.stats{margin-top:10px;font-size:14px}
#addForm{margin-top:20px}
&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;
&amp;lt;h2&amp;gt;🧩 Adaptive Sorting Visualizer (Upload CSV)&amp;lt;/h2&amp;gt;
&amp;lt;form id="uploadForm" enctype="multipart/form-data"&amp;gt;
  &amp;lt;input type="file" name="file" accept=".csv" required&amp;gt;
  &amp;lt;label&amp;gt;&amp;lt;input type="checkbox" id="stable"&amp;gt; Prefer Stable Sort &amp;lt;/label&amp;gt;
  &amp;lt;button type="submit"&amp;gt;Upload &amp;amp; Analyze&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;div id="bars"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;div class="stats" id="stats"&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;div id="addForm" style="display:none;"&amp;gt;
  &amp;lt;h3&amp;gt;➕ Add New Data Point&amp;lt;/h3&amp;gt;
  &amp;lt;input type="number" id="newVal" placeholder="Enter number"&amp;gt;
  &amp;lt;button onclick="addData()"&amp;gt;Add &amp;amp; Re-sort&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
let arr=[],ops=[],index=0,maxVal=1,lastAlgo="insertion";

document.getElementById("uploadForm").addEventListener("submit",async e=&amp;gt;{
 e.preventDefault();
 const f=new FormData(e.target);
 f.set("stable",document.getElementById("stable").checked?'true':'false');
 const res=await fetch("/upload",{method:"POST",body:f});
 const data=await res.json();
 arr=data.original_array;ops=data.operations;maxVal=Math.max(...arr);
 lastAlgo=data.algorithm;
 draw();index=0;animate();
 showStats(data);
 document.getElementById("addForm").style.display='block';
});

function draw(){
 const bars=document.getElementById("bars");bars.innerHTML='';
 arr.forEach(v=&amp;gt;{
   const cont=document.createElement('div');
   cont.className='bar-container';
   const b=document.createElement('div');
   b.className='bar';
   b.style.height=(v/maxVal*380)+'px';
   b.style.width=(600/arr.length)+'px';
   const val=document.createElement('div');
   val.className='bar-value';
   val.textContent=v;
   cont.appendChild(b);
   cont.appendChild(val);
   bars.appendChild(cont);
 });
}

function animate(){
 if(index&amp;gt;=ops.length)return;
 const o=ops[index++];const bars=document.querySelectorAll('.bar');
 const values=document.querySelectorAll('.bar-value');
 bars.forEach(x=&amp;gt;x.classList.remove('comp','swap'));
 if(o.type==='compare'){bars[o.i].classList.add('comp');bars[o.j].classList.add('comp');}
 if(o.type==='swap'){
   let h=bars[o.i].style.height;bars[o.i].style.height=bars[o.j].style.height;bars[o.j].style.height=h;
   let tmpVal=values[o.i].textContent;values[o.i].textContent=values[o.j].textContent;values[o.j].textContent=tmpVal;
   bars[o.i].classList.add('swap');bars[o.j].classList.add('swap');
 }
 if(o.type==='overwrite'){
   bars[o.i].style.height=(o.value/maxVal*380)+'px';
   values[o.i].textContent=o.value;
   bars[o.i].classList.add('swap');
 }
 setTimeout(animate,20);
}

function showStats(d){
 document.getElementById("stats").innerHTML=
 `Algorithm: &amp;lt;b&amp;gt;${d.algorithm.toUpperCase()}&amp;lt;/b&amp;gt; | Size: ${d.size} | Comparisons: ${d.comparisons} | Swaps/Writes: ${d.swaps_writes} | Time: ${d.time_taken.toFixed(4)}s&amp;lt;br&amp;gt;
 Stable: ${d.theoretical.stable} | Time Complexity: ${d.theoretical.time} | Space: ${d.theoretical.space}`;
}

async function addData(){
 const val=parseFloat(document.getElementById("newVal").value);
 if(isNaN(val))return alert("Enter valid number!");
 arr.push(val);
 const res=await fetch("/add_data",{method:"POST",headers:{'Content-Type':'application/json'},body:JSON.stringify({data:arr})});
 const data=await res.json();
 arr=data.original_array;ops=data.operations;maxVal=Math.max(...arr);
 draw();index=0;animate();showStats(data);
}
&amp;lt;/script&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;
""")

# ================= API ROUTES =====================

@app.route("/upload", methods=["POST"])
def upload():
    file = request.files.get("file")
    prefer_stable = request.form.get("stable") == "true"
    if not file: return jsonify({"error": "No file uploaded"}), 400
    stream = io.StringIO(file.stream.read().decode("utf-8"))
    reader = csv.reader(stream)
    arr=[]
    for row in reader:
        for val in row:
            try: arr.append(float(val))
            except: pass
    n=len(arr)
    if n==0: return jsonify({"error": "No valid numbers"}),400
    if n &amp;lt;= 30:
        algo = "bubble"
    elif prefer_stable:
        algo = "merge"
    else:
        algo = "quick"
    start=time.time()
    if algo=="bubble": sorted_arr,ops,comps,swaps=bubble_sort(arr)
    elif algo=="merge": sorted_arr,ops,comps,swaps=merge_sort(arr)
    elif algo=="insertion": sorted_arr,ops,comps,swaps=insertion_sort(arr)
    else: sorted_arr,ops,comps,swaps=quick_sort(arr)
    elapsed=time.time()-start
    return jsonify({
        "algorithm":algo,
        "size":n,
        "original_array":arr,
        "operations":ops,
        "comparisons":comps,
        "swaps_writes":swaps,
        "time_taken":elapsed,
        "theoretical":THEORY[algo]
    })

@app.route("/add_data", methods=["POST"])
def add_data():
    data = request.get_json().get("data", [])
    if not data: return jsonify({"error":"No data"}),400
    start=time.time()
    sorted_arr,ops,comps,swaps=insertion_sort(data)
    elapsed=time.time()-start
    return jsonify({
        "algorithm":"insertion",
        "size":len(sorted_arr),
        "original_array":sorted_arr,
        "operations":ops,
        "comparisons":comps,
        "swaps_writes":swaps,
        "time_taken":elapsed,
        "theoretical":THEORY["insertion"]
    })

if __name__=="__main__":
    app.run(debug=True)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>daa</category>
      <category>algorithms</category>
      <category>python</category>
      <category>vscode</category>
    </item>
  </channel>
</rss>
