<?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: Gyver Tc</title>
    <description>The latest articles on Forem by Gyver Tc (@tcgyver).</description>
    <link>https://forem.com/tcgyver</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%2F2914877%2F507014f4-2173-4bfe-87ba-adc7282d30d3.jpg</url>
      <title>Forem: Gyver Tc</title>
      <link>https://forem.com/tcgyver</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tcgyver"/>
    <language>en</language>
    <item>
      <title>AI agent</title>
      <dc:creator>Gyver Tc</dc:creator>
      <pubDate>Wed, 05 Mar 2025 19:50:21 +0000</pubDate>
      <link>https://forem.com/tcgyver/ai-agent-4fcf</link>
      <guid>https://forem.com/tcgyver/ai-agent-4fcf</guid>
      <description>&lt;p&gt;*&lt;em&gt;What exactly makes something an AI agent in the first place?  How agents relate to large language models, use tools, and adapt their behavior based on context?&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s unpack what makes something an &lt;strong&gt;AI agent&lt;/strong&gt;, how it relates to &lt;strong&gt;large language models (LLMs)&lt;/strong&gt;, and how agents use tools and adapt to context. I’ll keep it clear, grounded in examples (like our EHR system), and structured to address each part of your question.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Makes Something an AI Agent?
&lt;/h3&gt;

&lt;p&gt;An &lt;strong&gt;AI agent&lt;/strong&gt; is a system that perceives its environment, makes decisions, and takes actions to achieve specific goals—autonomously or semi-autonomously. It’s not just a passive tool; it’s an active entity with some degree of &lt;strong&gt;agency&lt;/strong&gt;. Here’s what defines it:&lt;/p&gt;

&lt;h4&gt;
  
  
  Core Characteristics
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Perception&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It senses its environment (e.g., data inputs, user queries, system states).&lt;/li&gt;
&lt;li&gt;Example: An EHR agent reads patient records or doctor inputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reasoning/Decision-Making&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It processes inputs to decide what to do, often using rules, models, or learning.&lt;/li&gt;
&lt;li&gt;Example: Decides to draft a patient summary based on visit data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Action&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It performs tasks or outputs results to affect the environment.&lt;/li&gt;
&lt;li&gt;Example: Generates a documentation draft and sends it to a doctor.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Goal-Directed Behavior&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It works toward an objective (e.g., efficiency, accuracy).&lt;/li&gt;
&lt;li&gt;Example: Minimize documentation time while maintaining quality.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Autonomy (to a Degree)&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It operates without constant human intervention, though it may need oversight.&lt;/li&gt;
&lt;li&gt;Example: Automatically processes EHR data overnight.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Contrast with Non-Agents
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;A calculator isn’t an AI agent—it computes but lacks perception or autonomy.&lt;/li&gt;
&lt;li&gt;A script that extracts EHR data isn’t an agent unless it decides what to extract based on context and acts on it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Simple Definition&lt;/strong&gt;: An AI agent is a system that observes, thinks (processes), and acts to achieve a goal, often adapting to its surroundings.&lt;/p&gt;




&lt;h3&gt;
  
  
  How Do Agents Relate to Large Language Models (LLMs)?
&lt;/h3&gt;

&lt;p&gt;LLMs, like me (Grok), are a key component of many modern AI agents, but they’re not agents by themselves—they’re &lt;strong&gt;models&lt;/strong&gt;. Here’s the relationship:&lt;/p&gt;

&lt;h4&gt;
  
  
  LLMs as a Brain
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Role&lt;/strong&gt;: LLMs provide the reasoning and language understanding/generation capability for agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: In our EHR system, an LLM interprets visit notes and generates summaries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limitation&lt;/strong&gt;: Alone, an LLM is reactive—it responds to prompts but doesn’t initiate actions or pursue goals.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Agents Built on LLMs
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;LLM-based agent&lt;/strong&gt; wraps the model with additional logic:

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Input Handling&lt;/strong&gt;: Takes environment data (e.g., EHR records) and crafts prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action Layer&lt;/strong&gt;: Executes tasks based on LLM outputs (e.g., saves a summary).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goal Loop&lt;/strong&gt;: Iterates to refine results (e.g., adjusts based on doctor feedback).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example&lt;/strong&gt;: Our AIDocumentationSystem (from earlier) uses an LLM to draft notes, but the agent decides which patient data to process and when.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Key Difference
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LLM&lt;/strong&gt;: “Write a summary of this: [EHR data].”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: “Monitor EHR updates, select urgent cases, summarize them using an LLM, and notify doctors—all without being asked.”&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  How Do Agents Use Tools?
&lt;/h3&gt;

&lt;p&gt;Agents extend their capabilities by integrating &lt;strong&gt;tools&lt;/strong&gt;—external systems or functions they call to perform tasks beyond their core abilities.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tool Usage Mechanics
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tool Identification&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent recognizes when it needs external help (e.g., “I can’t query a database directly”).&lt;/li&gt;
&lt;li&gt;Example: I (Grok) can analyze X posts if given data, but I’d need a tool to fetch them.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tool Invocation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It calls APIs, scripts, or libraries to execute actions.&lt;/li&gt;
&lt;li&gt;Example: Our EHR agent uses SQLAlchemy to query the database.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Result Integration&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It processes tool outputs and incorporates them into its workflow.&lt;/li&gt;
&lt;li&gt;Example: Feeds SQL results into an LLM to generate documentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  EHR Example
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: EHR Documentation Agent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database Query Tool&lt;/strong&gt;: Retrieves patient visit data (SQL).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Search Tool&lt;/strong&gt;: Looks up treatment guidelines (if I were to use my search capability).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File Parser&lt;/strong&gt;: Analyzes uploaded PDFs (e.g., lab reports).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Workflow&lt;/strong&gt;: Queries the database → parses results → generates a summary → emails it to a doctor.&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  Why Tools Matter
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Tools make agents versatile, turning a language-focused LLM into a multi-functional system (e.g., data retrieval + text generation).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  How Do Agents Adapt Their Behavior Based on Context?
&lt;/h3&gt;

&lt;p&gt;Adaptability is what makes agents “smart”—they adjust their actions based on the environment, user needs, or feedback.&lt;/p&gt;

&lt;h4&gt;
  
  
  Mechanisms of Adaptation
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Context Awareness&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They interpret situational cues (e.g., user role, data type).&lt;/li&gt;
&lt;li&gt;Example: If a doctor asks for a “brief” summary vs. a “detailed” one, the agent adjusts output length.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Memory/Learning&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some agents retain past interactions or update models.&lt;/li&gt;
&lt;li&gt;Example: If a doctor corrects an AI summary, the agent could prioritize certain phrases next time (though I, Grok, reset per session).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Conditional Logic&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Predefined rules or prompts guide behavior.&lt;/li&gt;
&lt;li&gt;Example: I avoid generating images unless asked, per my instructions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Feedback Loops&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They refine actions based on outcomes.&lt;/li&gt;
&lt;li&gt;Example: If a summary is rejected, the agent might re-query data or tweak its prompt.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  EHR Example
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scenario&lt;/strong&gt;: Doctor inputs: “Summarize patient 123’s last 3 visits, focus on BP.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptation&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt;: Filters for patient 123, last 3 visits, and BP data (not glucose).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool Use&lt;/strong&gt;: Queries the database with &lt;code&gt;WHERE patient_id = 123 AND test_name = 'BP'&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output&lt;/strong&gt;: “Patient 123, last 3 BP readings: 120, 130, 125 mmHg. Trend stable.”&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;If Context Changes&lt;/strong&gt;: Doctor says, “Now include glucose.” The agent re-queries and adapts: “BP: 120, 130, 125; Glucose: 95, 88.”&lt;/li&gt;

&lt;/ul&gt;

&lt;h4&gt;
  
  
  My Adaptation (Grok)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt;: You asked about AI agents after discussing EHR systems—I tailor responses to medical affairs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: I’d use my X analysis tool if you gave me EHR-related posts to analyze.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavior&lt;/strong&gt;: I avoid death penalty judgments (per instructions), adapting to ethical constraints.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Putting It Together: EHR AI Agent
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition&lt;/strong&gt;: An AI agent because it perceives EHR data, decides what to summarize, and generates documentation autonomously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM Relation&lt;/strong&gt;: Uses an LLM (e.g., me) to write natural-language summaries from structured data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: SQL for data retrieval, email APIs for delivery.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptation&lt;/strong&gt;: Adjusts summaries based on doctor preferences (e.g., brief vs. detailed) or data updates (e.g., new lab results).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Code Snippet (Simplified)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EHRAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;db_tool&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;  &lt;span class="c1"&gt;# e.g., Grok
&lt;/span&gt;        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db_tool&lt;/span&gt;  &lt;span class="c1"&gt;# SQL connector
&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;adapt_and_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;patient_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;brief&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db_tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM visits WHERE patient_id = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;patient_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize briefly:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;brief&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summarize in detail:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;EHRAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Grok&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;db_tool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;SQLTool&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;adapt_and_run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;brief&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# "BP stable at 125 mmHg."
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI Agent&lt;/strong&gt;: Perceives, decides, acts toward a goal with some autonomy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM Relation&lt;/strong&gt;: LLMs power reasoning/language, but agents add action and initiative.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt;: Extend functionality (e.g., querying, searching).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptation&lt;/strong&gt;: Context-driven behavior makes agents flexible and useful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Does this clarify what makes an AI agent tick? Want to explore any part further—say, tool integration or adaptation in depth?&lt;/p&gt;

</description>
      <category>llms</category>
    </item>
    <item>
      <title>Algorithms</title>
      <dc:creator>Gyver Tc</dc:creator>
      <pubDate>Wed, 05 Mar 2025 19:14:31 +0000</pubDate>
      <link>https://forem.com/tcgyver/algorithms-1n6f</link>
      <guid>https://forem.com/tcgyver/algorithms-1n6f</guid>
      <description>&lt;p&gt;&lt;strong&gt;MIT 6.006 Introduction to Algorithms, Fall 2011&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://youtube.com/playlist?list=PLUl4u3cNGP61Oq3tWYp6V_F-5jb5L2iHb" rel="noopener noreferrer"&gt;https://youtube.com/playlist?list=PLUl4u3cNGP61Oq3tWYp6V_F-5jb5L2iHb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Algorithm design:  &lt;a href="https://youtu.be/2P-yW7LQr08" rel="noopener noreferrer"&gt;https://youtu.be/2P-yW7LQr08&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q2blzn8bhhvfz9192y0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q2blzn8bhhvfz9192y0.jpg" alt="Image description" width="800" height="898"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://atekihcan.github.io/CLRS/" rel="noopener noreferrer"&gt;https://atekihcan.github.io/CLRS/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://icefox-saber.github.io/CLRS/Chap01/1.1/" rel="noopener noreferrer"&gt;https://icefox-saber.github.io/CLRS/Chap01/1.1/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part I Foundations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1 The Role of Algorithms in Computing&lt;/p&gt;

&lt;p&gt;1.1-2&lt;br&gt;
Other than speed, what other measures of efficiency might you need to consider in a real-world setting?&lt;br&gt;
⇒ Computer memory usage, network bandwidth, power consumption&lt;/p&gt;

&lt;p&gt;1.1-4&lt;br&gt;
How are the shortest-path and traveling-salesperson problems given above similar? How are they different?&lt;/p&gt;

&lt;p&gt;Definitions&lt;br&gt;
● Shortest-Path Problem: Given a graph (a set of nodes connected by edges with weights, like distances or costs), find the path between two specific nodes (a source and a destination) that minimizes the total weight. A well-known algorithm for this is Dijkstra’s algorithm for single-source shortest paths in graphs with non-negative weights.&lt;br&gt;
● Traveling-Salesperson Problem (TSP): Given a set of nodes and the distances between each pair, find the shortest possible route that visits every node exactly once and returns to the starting node (a Hamiltonian cycle with minimal total weight). This is an optimization problem with no simple, efficient solution for large instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Similarities&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Graph-Based Problems:
○ Both problems are defined on graphs, where nodes represent locations (e.g., cities, points) and edges represent connections (e.g., roads, distances).
○ The weights on edges typically represent costs, distances, or times to be minimized.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Optimization Goals:&lt;br&gt;
○ Each seeks to minimize a total cost: the shortest-path problem minimizes the cost between two points, while TSP minimizes the cost of a complete tour.&lt;br&gt;
○ Both involve finding an optimal solution among many possible paths or routes.&lt;/p&gt;

&lt;p&gt;Real-World Applications:&lt;br&gt;
○ They apply to navigation, logistics, and network design. For example, shortest-path is used in GPS routing, while TSP models delivery truck routes or circuit board drilling.&lt;/p&gt;

&lt;p&gt;Dynamic Programming and Greedy Approaches:&lt;br&gt;
○ Algorithms for both can use optimization techniques. For instance, Dijkstra’s algorithm (shortest-path) is greedy, and some TSP approximations use greedy heuristics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Differences&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scope of the Problem:
○ Shortest-Path: Focuses on a single pair of nodes (source to destination). You’re finding one path, not necessarily visiting all nodes.
○ TSP: Requires visiting all nodes exactly once and returning to the start, forming a complete cycle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Path vs. Cycle:&lt;br&gt;
○ Shortest-Path: The solution is an open path (e.g., A → B → C) with a start and end, which may not revisit nodes.&lt;br&gt;
○ TSP: The solution is a closed loop (e.g., A → B → C → A), a Hamiltonian cycle that covers every node.&lt;/p&gt;

&lt;p&gt;Complexity:&lt;br&gt;
○ Shortest-Path: Polynomial-time solvable. Dijkstra’s algorithm runs in O(V2) O(V^2) O(V2) or O(E+Vlog⁡V) O(E + V \log V) O(E+VlogV) with a priority queue, where V V V is the number of vertices and E E E is the number of edges.&lt;br&gt;
○ TSP: NP-hard. No known polynomial-time algorithm exists for the general case; exact solutions rely on exponential-time methods like dynamic programming (O(n22n) O(n^2 2^n) O(n22n)), and practical solutions often use approximations.&lt;/p&gt;

&lt;p&gt;Constraints:&lt;br&gt;
○ Shortest-Path: No requirement to visit all nodes—nodes can be skipped if they’re not on the optimal path.&lt;br&gt;
○ TSP: Must visit every node exactly once, which adds significant combinatorial complexity.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Output:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;○ Shortest-Path: A sequence of nodes from start to end (e.g., A → D → F).&lt;br&gt;
○ TSP: A tour that cycles back (e.g., A → B → C → A).&lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
Imagine a graph with nodes A, B, C, and edge weights:&lt;br&gt;
● A → B: 4&lt;br&gt;
● B → C: 3&lt;br&gt;
● A → C: 2&lt;br&gt;
● Shortest-Path (A to C): The solution is A → B → C (weight 7), skipping a direct A → C path (weight 2).&lt;br&gt;
● TSP (visit all and return): The solution might be A → B → C → A (weight 4 + 3 + 10 = 17), assuming a return edge C → A exists. TSP must include all nodes and close the loop, even if it’s less efficient between specific pairs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br&gt;
The shortest-path problem and TSP are similar in their use of graphs and focus on minimizing costs, but they differ fundamentally in scope and complexity. Shortest-path finds a single efficient route between two points, while TSP demands a full tour of all points, making it far more computationally challenging. The former is about efficiency between endpoints; the latter is about comprehensive coverage.&lt;/p&gt;

&lt;p&gt;1.1-5&lt;br&gt;
Suggest a real-world problem in which only the best solution will do.&lt;br&gt;
Then come up with one in which “approximately” the best solution is&lt;br&gt;
good enough.&lt;br&gt;
⇒ Computer memory usage&lt;/p&gt;

&lt;p&gt;Here are two real-world problems, one requiring the absolute best solution and another where an approximate solution suffices:&lt;br&gt;
Problem Requiring the Best Solution: Airline Crew Scheduling&lt;/p&gt;

&lt;p&gt;● Description: Airlines need to assign pilots and flight attendants to flights in a way that minimizes costs (e.g., salaries, overtime, travel expenses) while adhering to strict regulations (e.g., maximum working hours, rest requirements) and ensuring every flight is covered. The schedule must also account for crew qualifications, base locations, and unexpected disruptions like delays.&lt;/p&gt;

&lt;p&gt;● Why Only the Best Solution Will Do:&lt;/p&gt;

&lt;p&gt;○ Safety is non-negotiable—crew must be rested and qualified, with no room for error in compliance with aviation laws.&lt;br&gt;
○ Costs are massive, and even a 1% improvement in efficiency can save millions annually for a large airline.&lt;br&gt;
○ Suboptimal schedules could lead to flight cancellations or legal violations, which are unacceptable.&lt;/p&gt;

&lt;p&gt;● Approach: This is often modeled as an integer programming problem or a variant of the set-covering problem, solved with exact optimization techniques like branch-and-bound or constraint programming to guarantee the optimal solution.&lt;/p&gt;

&lt;p&gt;Problem Where “Approximately” the Best Solution is Good Enough: Delivery Route Planning for a Local Bakery&lt;br&gt;
● Description: A small bakery delivers fresh bread to 20 local cafes each morning. The goal is to find a route for the delivery van that minimizes travel time, starting and ending at the bakery, while ensuring all cafes receive their orders within a reasonable window (e.g., before 8 AM).&lt;/p&gt;

&lt;p&gt;● Why an Approximate Solution is Good Enough:&lt;br&gt;
○ Time constraints are flexible as long as deliveries are reasonably prompt—slight delays don’t ruin the business.&lt;br&gt;
○ Fuel costs are a factor, but for a small operation, the difference between the absolute shortest route and a near-optimal one might be negligible (e.g., a few dollars daily).&lt;br&gt;
○ Real-world variables like traffic or road closures change daily, so chasing the exact optimum might be overkill when conditions are unpredictable.&lt;/p&gt;

&lt;p&gt;● Approach: This resembles the Traveling Salesperson Problem (TSP). A heuristic like the nearest-neighbor algorithm or a metaheuristic like simulated annealing can quickly provide a route that’s close to optimal (e.g., within 5-10% of the best), which is practical and sufficient for the bakery’s needs.&lt;/p&gt;

&lt;p&gt;Contrast&lt;br&gt;
● Precision vs. Practicality: Airline scheduling demands precision due to high stakes (safety, cost, reliability), while the bakery can tolerate minor inefficiencies for simplicity and speed.&lt;br&gt;
● Scale and Complexity: The airline problem involves hundreds of crew and flights with rigid constraints, necessitating exactness. The bakery’s smaller scope (20 stops) and looser requirements make approximation viable.&lt;br&gt;
● Consequences: A suboptimal airline schedule could ground planes or violate laws; a slightly longer bakery route just means a bit more gas or a few extra minutes.&lt;br&gt;
These examples highlight when perfection is critical versus when “good enough” keeps the world turning without undue effort.&lt;/p&gt;

&lt;p&gt;1.1-6&lt;br&gt;
Describe a real-world problem in which sometimes the entire input is&lt;br&gt;
available before you need to solve the problem, but other times the&lt;br&gt;
input is not entirely available in advance and arrives over time.&lt;br&gt;
⇒ offline: convert an epub file to pdf&lt;br&gt;
online: ChatGPT, Google, any ecommerce sites like Amazon&lt;/p&gt;

&lt;p&gt;1.2-1&lt;br&gt;
Give an example of an application that requires algorithmic content at&lt;br&gt;
the application level, and discuss the function of the algorithms&lt;br&gt;
involved.&lt;br&gt;
⇒ Check out process in an ecommerce site&lt;/p&gt;

&lt;p&gt;1.2-2&lt;br&gt;
Suppose that for inputs of size n on a particular computer, insertion&lt;br&gt;
sort runs in 8n^2 steps and merge sort runs in 64 n lg n steps. For which&lt;br&gt;
values of n does insertion sort beat merge sort?&lt;br&gt;
⇒ 8n^2 = 64 n lg n ⇒ n = 8 lg n&lt;br&gt;
n = 43.xxx, so merge sort starts beating at n=44&lt;br&gt;
844^2 &amp;gt; 64 44 * lg 44&lt;/p&gt;

&lt;p&gt;1.2-3&lt;br&gt;
What is the smallest value of n such that an algorithm whose running&lt;br&gt;
time is 100n^2 runs faster than an algorithm whose running time is 2^n on&lt;br&gt;
the same machine?&lt;br&gt;
⇒ 15&lt;/p&gt;

&lt;p&gt;n 100n^2 2^n&lt;br&gt;
14 19,600 16,384&lt;br&gt;
15 22,500 32,768&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 1: Illustration of Insertion Sort&lt;/strong&gt;&lt;br&gt;
Let's illustrate the operation of Insertion Sort on the array initially containing the sequence:&lt;br&gt;
⟨31, 41, 59, 26, 41, 58⟩.&lt;/p&gt;

&lt;p&gt;Insertion Sort Algorithm&lt;br&gt;
Insertion Sort works by iteratively inserting each element into its correct position in the sorted portion of the array.&lt;/p&gt;

&lt;p&gt;Step-by-Step Execution&lt;br&gt;
Initial Array:&lt;br&gt;
[31, 41, 59, 26, 41, 58]&lt;/p&gt;

&lt;p&gt;After 1st Iteration (i = 1):&lt;/p&gt;

&lt;p&gt;The first element 31 is already in the sorted portion.&lt;br&gt;
Sorted portion: [31]&lt;br&gt;
Array: [31, 41, 59, 26, 41, 58]&lt;br&gt;
After 2nd Iteration (i = 2):&lt;/p&gt;

&lt;p&gt;Insert 41 into the sorted portion [31].&lt;br&gt;
41 is greater than 31, so it stays in place.&lt;br&gt;
Sorted portion: [31, 41]&lt;br&gt;
Array: [31, 41, 59, 26, 41, 58]&lt;br&gt;
After 3rd Iteration (i = 3):&lt;/p&gt;

&lt;p&gt;Insert 59 into the sorted portion [31, 41].&lt;br&gt;
59 is greater than 41, so it stays in place.&lt;br&gt;
Sorted portion: [31, 41, 59]&lt;br&gt;
Array: [31, 41, 59, 26, 41, 58]&lt;br&gt;
After 4th Iteration (i = 4):&lt;/p&gt;

&lt;p&gt;Insert 26 into the sorted portion [31, 41, 59].&lt;br&gt;
26 is smaller than 59, 41, and 31, so it moves to the front.&lt;br&gt;
Sorted portion: [26, 31, 41, 59]&lt;br&gt;
Array: [26, 31, 41, 59, 41, 58]&lt;br&gt;
After 5th Iteration (i = 5):&lt;/p&gt;

&lt;p&gt;Insert 41 into the sorted portion [26, 31, 41, 59].&lt;br&gt;
41 is equal to the last 41, so it stays in place.&lt;br&gt;
Sorted portion: [26, 31, 41, 41, 59]&lt;br&gt;
Array: [26, 31, 41, 41, 59, 58]&lt;br&gt;
After 6th Iteration (i = 6):&lt;/p&gt;

&lt;p&gt;Insert 58 into the sorted portion [26, 31, 41, 41, 59].&lt;br&gt;
58 is smaller than 59, so it moves before 59.&lt;br&gt;
Sorted portion: [26, 31, 41, 41, 58, 59]&lt;br&gt;
Array: [26, 31, 41, 41, 58, 59]&lt;br&gt;
Final Sorted Array:&lt;br&gt;
[26, 31, 41, 41, 58, 59]&lt;/p&gt;

&lt;p&gt;Slightly less efficient version of ascending insertion sort:&lt;br&gt;
`def insertion_sort_ascending(numbers):&lt;br&gt;
for i in range(1, len(numbers)):&lt;br&gt;
if (i &amp;gt; 1):&lt;br&gt;
for j in range(i, 0, -1):&lt;br&gt;
if (numbers[j-1] &amp;gt; numbers[j]):&lt;br&gt;
swap(numbers, j-1, j)&lt;/p&gt;

&lt;p&gt;def swap(array, idx_a, idx_b):&lt;br&gt;
tmp = array[idx_a]&lt;br&gt;
array[idx_a] = array[idx_b]&lt;br&gt;
array[idx_b] = tmp`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 2: Loop Invariant for SUM-ARRAY&lt;/strong&gt;&lt;br&gt;
The SUM-ARRAY procedure computes the sum of the numbers in the array A[1 : n]. Here is the procedure:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SUM-ARRAY(A, n)&lt;br&gt;
sum = 0&lt;br&gt;
for i = 1 to n&lt;br&gt;
sum = sum + A[i]&lt;br&gt;
return sum&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Loop Invariant&lt;br&gt;
A loop invariant is a condition that is true before and after each iteration of the loop. For the SUM-ARRAY procedure, the loop invariant is:&lt;/p&gt;

&lt;p&gt;At the start of each iteration of the for loop, the variable sum contains the sum of the elements in the subarray A[1 : i-1].&lt;/p&gt;

&lt;p&gt;Proof of Correctness Using Loop Invariant&lt;/p&gt;

&lt;p&gt;Initialization:&lt;/p&gt;

&lt;p&gt;Before the first iteration (i = 1), the subarray A[1 : 0] is empty.&lt;br&gt;
The variable sum is initialized to 0, which is the sum of an empty array.&lt;br&gt;
Thus, the loop invariant holds before the first iteration.&lt;/p&gt;

&lt;p&gt;Maintenance:&lt;/p&gt;

&lt;p&gt;Assume the loop invariant holds at the start of the i-th iteration, i.e., sum contains the sum of A[1 : i-1].&lt;br&gt;
During the i-th iteration, sum is updated to sum + A[i].&lt;br&gt;
After the update, sum contains the sum of A[1 : i].&lt;br&gt;
Thus, the loop invariant holds at the start of the next iteration.&lt;/p&gt;

&lt;p&gt;Termination:&lt;/p&gt;

&lt;p&gt;The loop terminates when i = n + 1.&lt;br&gt;
At this point, the loop invariant states that sum contains the sum of A[1 : n].&lt;br&gt;
The procedure returns sum, which is the correct sum of all elements in the array.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
The loop invariant ensures that the SUM-ARRAY procedure correctly computes the sum of the numbers in the array A[1 : n]. By the properties of initialization, maintenance, and termination, the procedure is proven to be correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 1: Insertion Sort for Monotonically Decreasing Order&lt;/strong&gt;&lt;br&gt;
To modify the Insertion Sort algorithm to sort in monotonically decreasing order, we need to change the comparison condition. Instead of inserting elements into the correct position in an increasing sequence, we insert them into the correct position in a decreasing sequence.&lt;/p&gt;

&lt;p&gt;Pseudocode for Decreasing Insertion Sort&lt;br&gt;
&lt;code&gt;&lt;br&gt;
INSERTION-SORT-DECREASING(A)&lt;br&gt;
for j = 2 to A.length&lt;br&gt;
key = A[j]&lt;br&gt;
i = j - 1&lt;br&gt;
// Insert A[j] into the sorted sequence A[1 : j-1] in decreasing order&lt;br&gt;
while i &amp;gt; 0 and A[i] &amp;lt; key&lt;br&gt;
A[i + 1] = A[i]&lt;br&gt;
i = i - 1&lt;br&gt;
A[i + 1] = key&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Slightly less efficient version of ascending insertion sort:&lt;br&gt;
`def insertion_sort_descending(numbers):&lt;br&gt;
for i in range(1, len(numbers)):&lt;br&gt;
if (i &amp;gt; 1):&lt;br&gt;
for j in range(i, 0, -1):&lt;br&gt;
if (numbers[j-1] &amp;lt; numbers[j]):&lt;br&gt;
swap(numbers, j-1, j)&lt;/p&gt;

&lt;p&gt;def swap(array, idx_a, idx_b):&lt;br&gt;
tmp = array[idx_a]&lt;br&gt;
array[idx_a] = array[idx_b]&lt;br&gt;
array[idx_b] = tmp`&lt;/p&gt;

&lt;p&gt;Explanation&lt;br&gt;
The outer loop iterates over each element in the array.&lt;br&gt;
The inner loop shifts elements to the right until the correct position for key is found in the decreasing sequence.&lt;br&gt;
The condition A[i] &amp;lt; key ensures that the sequence remains monotonically decreasing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Part 2: Linear Search Pseudocode and Correctness Proof&lt;/strong&gt;&lt;br&gt;
Pseudocode for Linear Search&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LINEAR-SEARCH(A, x)&lt;br&gt;
for i = 1 to A.length&lt;br&gt;
if A[i] == x&lt;br&gt;
return i&lt;br&gt;
return NIL&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Slightly more explicit linear search:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;def linear_search(numbers, value):&lt;br&gt;
ret = None&lt;br&gt;
for i in range(1, len(numbers)):&lt;br&gt;
if (numbers[i] == value):&lt;br&gt;
ret = i&lt;br&gt;
return ret&lt;br&gt;
return ret&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Loop Invariant&lt;br&gt;
The loop invariant for the LINEAR-SEARCH algorithm is:&lt;/p&gt;

&lt;p&gt;At the start of each iteration of the for loop, the element x does not appear in the subarray A[1 : i-1].&lt;/p&gt;

&lt;p&gt;Proof of Correctness Using Loop Invariant&lt;/p&gt;

&lt;p&gt;Initialization:&lt;/p&gt;

&lt;p&gt;Before the first iteration (i = 1), the subarray A[1 : 0] is empty.&lt;br&gt;
By definition, x does not appear in an empty array.&lt;br&gt;
Thus, the loop invariant holds before the first iteration.&lt;/p&gt;

&lt;p&gt;Maintenance:&lt;/p&gt;

&lt;p&gt;Assume the loop invariant holds at the start of the i-th iteration, i.e., x does not appear in A[1 : i-1].&lt;br&gt;
During the i-th iteration, the algorithm checks if A[i] == x.&lt;br&gt;
If A[i] == x, the algorithm returns i, and the loop terminates.&lt;br&gt;
If A[i] != x, the loop invariant holds for the next iteration (i + 1).&lt;br&gt;
Thus, the loop invariant is maintained.&lt;/p&gt;

&lt;p&gt;Termination:&lt;/p&gt;

&lt;p&gt;The loop terminates when either x is found or i exceeds A.length.&lt;br&gt;
If x is found, the algorithm returns the correct index.&lt;br&gt;
If x is not found, the algorithm returns NIL, which is correct because the loop invariant ensures that x does not appear in A[1 : A.length].&lt;br&gt;
Part 3: Adding Two n-Bit Binary Integers&lt;br&gt;
The problem involves adding two n-bit binary integers stored in arrays A and B and storing the result in an (n + 1)-bit array C.&lt;/p&gt;

&lt;p&gt;Pseudocode for ADD-BINARY-INTEGERS&lt;br&gt;
&lt;code&gt;ADD-BINARY-INTEGERS(A, B, n)&lt;br&gt;
let C[0 : n] be a new array&lt;br&gt;
carry = 0&lt;br&gt;
for i = n - 1 downto 0&lt;br&gt;
sum = A[i] + B[i] + carry&lt;br&gt;
C[i + 1] = sum % 2 // Store the least significant bit&lt;br&gt;
carry = sum // 2 // Update the carry&lt;br&gt;
C[0] = carry&lt;br&gt;
return C&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Explanation&lt;br&gt;
Initialization:&lt;/p&gt;

&lt;p&gt;Create a new array C of size n + 1 to store the result.&lt;br&gt;
Initialize carry to 0.&lt;br&gt;
Loop:&lt;/p&gt;

&lt;p&gt;Iterate from the least significant bit (LSB) to the most significant bit (MSB).&lt;br&gt;
Compute the sum of A[i], B[i], and carry.&lt;br&gt;
Store the LSB of the sum in C[i + 1].&lt;br&gt;
Update the carry for the next iteration.&lt;br&gt;
Final Carry:&lt;/p&gt;

&lt;p&gt;After the loop, store the final carry in C[0].&lt;br&gt;
Return:&lt;/p&gt;

&lt;p&gt;Return the array C containing the sum.&lt;br&gt;
`def add_two_bin_numbers(array_a, array_b, size):&lt;br&gt;
ret = []&lt;br&gt;
carry_over = 0&lt;br&gt;
for i in range(size-1, -1, -1):&lt;br&gt;
bit_sum = array_a[i] + array_b[i] + carry_over&lt;br&gt;
if (bit_sum &amp;gt; 1):&lt;br&gt;
carry_over = 1&lt;br&gt;
ret.insert(0, bit_sum % 2)&lt;br&gt;
else:&lt;br&gt;
carry_over = 0&lt;br&gt;
ret.insert(0, bit_sum)&lt;/p&gt;

&lt;p&gt;ret.insert(0, carry_over)&lt;br&gt;
return ret&lt;/p&gt;

&lt;p&gt;bin_number_a = [1, 0, 1, 0]&lt;br&gt;
bin_number_b = [1, 1, 1, 0]&lt;br&gt;
print ("sum = ", add_two_bin_numbers(bin_number_a, bin_number_b, len(bin_number_b)))&lt;br&gt;
`&lt;br&gt;
sum = [1, 1, 0, 0, 0]&lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
Input:&lt;br&gt;
A = &lt;a href="https://dev.tobinary%20number%201011,%20decimal%2011"&gt;1, 0, 1, 1&lt;/a&gt;&lt;br&gt;
B = &lt;a href="https://dev.tobinary%20number%201101,%20decimal%2013"&gt;1, 1, 0, 1&lt;/a&gt;&lt;br&gt;
n = 4&lt;/p&gt;

&lt;p&gt;Execution:&lt;/p&gt;

&lt;p&gt;Iteration 1: sum = 1 + 1 + 0 = 2, C[4] = 0, carry = 1&lt;br&gt;
Iteration 2: sum = 1 + 0 + 1 = 2, C[3] = 0, carry = 1&lt;br&gt;
Iteration 3: sum = 0 + 1 + 1 = 2, C[2] = 0, carry = 1&lt;br&gt;
Iteration 4: sum = 1 + 1 + 1 = 3, C[1] = 1, carry = 1&lt;br&gt;
Final Carry: C[0] = 1&lt;br&gt;
Output:&lt;br&gt;
C = &lt;a href="https://dev.tobinary%20number%2011000,%20decimal%2024"&gt;1, 1, 0, 0, 0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br&gt;
Insertion Sort for Decreasing Order: Modify the comparison condition to sort in decreasing order.&lt;br&gt;
Linear Search: Use a loop invariant to prove correctness.&lt;br&gt;
Binary Addition: Implement a procedure to add two n-bit binary integers and store the result in an (n + 1)-bit array.&lt;br&gt;
2.2 Analyzing algorithms&lt;/p&gt;

&lt;p&gt;In some particular cases, we’ll be interested in the average-case&lt;br&gt;
running time of an algorithm. We’ll see the technique of probabilistic&lt;br&gt;
analysis applied to various algorithms throughout this book.&lt;br&gt;
⇒ I’ve seen one such case in matrix manipulation where most common inputs are sporadic matrices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exercises&lt;/strong&gt;&lt;br&gt;
2.2-1&lt;br&gt;
Express the function n3/1000 + 100n2 – 100n + 3 in terms of Θ-notation.&lt;br&gt;
⇒ Θ(n^3)&lt;/p&gt;

&lt;p&gt;2.2-2&lt;br&gt;
Consider sorting n numbers stored in array A[1 : n]&lt;br&gt;
⇒&lt;br&gt;
def selection_sort_ascending(numbers):&lt;br&gt;
size = len(numbers)&lt;br&gt;
for i in range(0, size):&lt;br&gt;
local_min_index = size-1&lt;br&gt;
for j in range(size-1, i, -1):&lt;br&gt;
if (numbers[j] &amp;lt; numbers[local_min_index]):&lt;br&gt;
local_min_index = j&lt;br&gt;
if (numbers[local_min_index] &amp;lt; numbers[i]):&lt;br&gt;
swap(numbers, local_min_index, i)&lt;/p&gt;

&lt;p&gt;2.2-3&lt;br&gt;
Consider linear search again (see Exercise 2.1-4). How many elements&lt;br&gt;
of the input array need to be checked on the average, assuming that the&lt;br&gt;
element being searched for is equally likely to be any element in the&lt;br&gt;
array? How about in the worst case?&lt;br&gt;
⇒ Average: n/2 (Θ(n)), worst case: n (Θ(n))&lt;/p&gt;

&lt;p&gt;2.3 Designing algorithms&lt;/p&gt;

&lt;p&gt;Merge-Sort&lt;br&gt;
`def merge_sort_ascending(numbers, start, end):&lt;br&gt;
if (start+1 &amp;gt;= end):&lt;br&gt;
return&lt;br&gt;
merged = []&lt;br&gt;
mid = (start + end) // 2&lt;br&gt;
merge_sort_ascending(numbers, start, mid)&lt;br&gt;
merge_sort_ascending(numbers, mid, end)&lt;br&gt;
left = 0&lt;br&gt;
right = 0&lt;br&gt;
while left &amp;lt; mid-start or right &amp;lt; end-mid:&lt;br&gt;
if(left &amp;lt; mid-start and right &amp;lt; end-mid):&lt;br&gt;
if (numbers[start+left] &amp;lt;= numbers[mid+right]):&lt;br&gt;
merged.append(numbers[start+left])&lt;br&gt;
left = left+1&lt;br&gt;
else:&lt;br&gt;
merged.append(numbers[mid+right])&lt;br&gt;
right = right+1&lt;br&gt;
elif(left &amp;lt; mid-start):&lt;br&gt;
merged.append(numbers[start+left])&lt;br&gt;
left = left+1&lt;br&gt;
elif(right &amp;lt; end-mid):&lt;br&gt;
merged.append(numbers[mid+right])&lt;br&gt;
right = right+1&lt;br&gt;
else:&lt;br&gt;
break&lt;/p&gt;

&lt;p&gt;numbers[start:end] = merged&lt;br&gt;
`&lt;br&gt;
Exercises&lt;br&gt;
2.3-1&lt;br&gt;
2.3-2&lt;/p&gt;

&lt;p&gt;2.3-3&lt;br&gt;
State a loop invariant for the while loop of lines 12–18 of the MERGE&lt;br&gt;
procedure. Show how to use it, along with the while loops of lines 20–23&lt;br&gt;
and 24–27, to prove that the MERGE procedure is correct.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;11// As long as each of the arrays L and R contains an unmerged&lt;br&gt;
element,&lt;br&gt;
// copy the smallest unmerged element back into A[p : r].&lt;br&gt;
12while i &amp;lt; nL and j &amp;lt; nR&lt;br&gt;
13 if L[i] ≤ R[j]&lt;br&gt;
14 A[k] = L[i]&lt;br&gt;
15 i = i + 1&lt;br&gt;
16 else A[k] = R[j]&lt;br&gt;
17 j = j + 1&lt;br&gt;
18 k = k + 1&lt;br&gt;
19// Having gone through one of L and R entirely, copy the&lt;br&gt;
// remainder of the other to the end of A[p : r].&lt;br&gt;
20while i &amp;lt; nL&lt;br&gt;
21 A[k] = L[i]&lt;br&gt;
22 i = i + 1&lt;br&gt;
23 k = k + 1&lt;br&gt;
24while j &amp;lt; nR&lt;br&gt;
25 A[k] = R[j]&lt;br&gt;
26 j = j + 1&lt;br&gt;
27 k = k + 1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Loop invariants help us understand why an algorithm is correct.&lt;br&gt;
When you’re using a loop invariant, you need to show three things:&lt;br&gt;
Initialization: It is true prior to the first iteration of the loop.&lt;br&gt;
Maintenance: If it is true before an iteration of the loop, it remains true&lt;br&gt;
before the next iteration.&lt;br&gt;
Termination: The loop terminates, and when it terminates, the invariant&lt;br&gt;
—usually along with the reason that the loop terminated—gives us a&lt;br&gt;
useful property that helps show that the algorithm is correct.&lt;/p&gt;

&lt;p&gt;loop invariant: at the start of each iteration A[p:k-1] consists of the smallest elements of union of L and R at sort order.&lt;br&gt;
when the while loop of lines 12-18 finish, A[p:k-1] consists of the smallest elements of union of L and R at sort order, either while loop of lines 20–23 or 24–27 will be run, L and R has the biggest rest elements in sort order.when the second while loop finish, they are added to the end of A, and A consist of all elements at sort order.&lt;/p&gt;

&lt;p&gt;2.3-4&lt;br&gt;
Use mathematical induction to show that when n ≥ 2 is an exact power&lt;br&gt;
of 2, the solution of the recurrence&lt;/p&gt;

&lt;p&gt;Is T(n) = n lg n.&lt;/p&gt;

&lt;p&gt;When n = 2, T(2) = 2 = 2 * ln 2 = 2 ⇒ so it’s true&lt;br&gt;
When n &amp;gt; 2, let n = 2^(t+1), then T(n) = 2^(t+1) lg 2^(t+1) = 2 2^t (lg 2^t + lg 2)&lt;br&gt;
= 2 2^t lg 2^t + 2 2^t lg 2&lt;br&gt;
= 2 2^t lg 2^t + 2^(t+1)&lt;br&gt;
= 2 T(n/2) + 2^(t+1)&lt;/p&gt;

&lt;p&gt;2.3-5&lt;br&gt;
You can also think of insertion sort as a recursive algorithm. In order&lt;br&gt;
to sort A[1 : n], recursively sort the subarray A[1 : n – 1] and then insert&lt;br&gt;
A[n] into the sorted subarray A[1 : n – 1]. Write pseudocode for this&lt;br&gt;
recursive version of insertion sort. Give a recurrence for its worst-case&lt;br&gt;
running time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;INSERTION-RECURSIVE-SORT(A, n)&lt;br&gt;
if 2 = n&lt;br&gt;
if A[1] &amp;gt; A[2]&lt;br&gt;
swap A[1], A[2]&lt;br&gt;
otherwise&lt;br&gt;
INSERTION-RECURSIVE-SORT(A, n-1)&lt;br&gt;
for i = n to 2&lt;br&gt;
if A[i-1] &amp;gt; A[i]&lt;br&gt;
exchange A[i] with A[i – 1]&lt;br&gt;
otherwise&lt;br&gt;
break&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  The worst-case running time when the input is in the reverse order
&lt;/h1&gt;

&lt;p&gt;= ((n-1)(n-2) / 2 ) * = Θ(n^2)&lt;/p&gt;

&lt;p&gt;2.3-6&lt;br&gt;
⇒ If the item is not found at the end of binary search, it’s Θ(lg n).&lt;/p&gt;

&lt;p&gt;2.3-7&lt;br&gt;
The while loop of lines 5–7 of the INSERTION-SORT procedure in&lt;br&gt;
Section 2.1 uses a linear search to scan (backward) through the sorted&lt;br&gt;
subarray A[1 : j – 1]. What if insertion sort used a binary search (see&lt;br&gt;
Exercise 2.3-6) instead of a linear search? Would that improve the&lt;br&gt;
overall worst-case running time of insertion sort to Θ(n lg n)?&lt;/p&gt;

&lt;p&gt;⇒ No, binary search wouldn’t work here since binary search works on an already-sorted list..&lt;/p&gt;

&lt;p&gt;2.3-8&lt;br&gt;
Describe an algorithm that, given a set S of n integers and another&lt;br&gt;
integer x, determines whether S contains two elements that sum to&lt;br&gt;
exactly x. Your algorithm should take Θ(n lg n) time in the worst case.&lt;/p&gt;

&lt;p&gt;⇒ First sort the set with the merge sort which takes Θ(n lg n) time and do a linear search for pairs which amount to x, which takes Θ(n) time. Since the highest Θ determines the entire process time, the overall is still Θ(n lg n) time.&lt;br&gt;
For example, let’s suppose we have a sorted integer set [ -30, -12, 0, 1, 2, 9, 23, 28, 92, 192 ]&lt;br&gt;
and we look for pairs whose sum is 30.&lt;br&gt;
Then we start searching with the first number i.e. -30 from the left.&lt;br&gt;
Since its counterpart should be 30 - (-30) = 60, we look for 60 from the right.&lt;br&gt;
However, 60 is not in the set.&lt;br&gt;
So with the “left” pointer, we move on to the next number which is -12, and with the “right” pointer, we look for 30-(-12) = 42.&lt;br&gt;
We keep doing this until the left pointer reaches 2. With that we find a matching pair of (2, 28).&lt;br&gt;
We move on. However, this time, the left pointer and the right point cross each other, so we stop searching.&lt;/p&gt;

</description>
      <category>clrs</category>
    </item>
  </channel>
</rss>
