diff --git a/src/AoC_2024/Dazbo's_Advent_of_Code_2024.ipynb b/src/AoC_2024/Dazbo's_Advent_of_Code_2024.ipynb
index 228a06c..79c8170 100644
--- a/src/AoC_2024/Dazbo's_Advent_of_Code_2024.ipynb
+++ b/src/AoC_2024/Dazbo's_Advent_of_Code_2024.ipynb
@@ -9215,7 +9215,20 @@
"- Generates a single _sum_ output.\n",
"- Generates a single carry output (Cout).\n",
"\n",
- "A single adder looks like this:\n",
+ "So we can think of an adder as taking 3 inputs and having two outputs. One output is the sum of binary digits for this _column_, and the other output is the carry-over digit, to be added to the next column.\n",
+ "\n",
+ "For example, if we want to add two 1-bit numbers like this:\n",
+ "\n",
+ "```text\n",
+ "\n",
+ "Carry 1 0\n",
+ "Input x 1\n",
+ "Input y 1\n",
+ " ---\n",
+ "Result 0\n",
+ "```\n",
+ "\n",
+ "A single adder can be depicted like this:\n",
"\n",
"\n",
"\n",
@@ -9223,14 +9236,14 @@
"\n",
"\n",
"\n",
- "Let's turn our input data into single line readable instructions, for each output. We can use this to look for anomalies.\n",
+ "And this is how we can generate a single 5-bit number from the addition of two 4-bit numbers.\n",
"\n",
- "And we can visualise it too.\n"
+ "How do we relate this to the problem? Well, to implement each adder in the ripple carry adder, we need to combine a number of gates. There are a couple of ways this can be done. So let's actually visualise what our instructions are doing, and then we'll know..."
]
},
{
"cell_type": "code",
- "execution_count": 79,
+ "execution_count": null,
"metadata": {},
"outputs": [],
"source": [
@@ -9265,10 +9278,23 @@
" \n",
"def create_vis(wires: dict):\n",
" dot = graphviz.Digraph(format='png', engine='dot')\n",
- "\n",
+ " \n",
+ " # Define gate shapes, colors, and output styles\n",
+ " gate_styles = {\n",
+ " \"AND\": {\"shape\": \"invtrapezium\", \"fillcolor\": \"lightblue\"},\n",
+ " \"OR\": {\"shape\": \"invtriangle\", \"fillcolor\": \"lightgreen\"},\n",
+ " \"XOR\": {\"shape\": \"box\", \"fillcolor\": \"lightyellow\"},\n",
+ " }\n",
+ " output_styles = {\n",
+ " \"z\": {\"fillcolor\": \"black\", \"fontcolor\": \"white\"},\n",
+ " \"x\": {\"fillcolor\": \"blue\", \"fontcolor\": \"white\"},\n",
+ " \"y\": {\"fillcolor\": \"red\", \"fontcolor\": \"white\"},\n",
+ " }\n",
+ " \n",
" # Add operand nodes (inputs/outputs) as circles\n",
" for wire in wires:\n",
- " dot.node(wire, wire, shape='circle') # Circle shape for operands\n",
+ " style = output_styles.get(wire[0], {}) # Get style based on first character\n",
+ " dot.node(wire, wire, shape='circle', style='filled', **style)\n",
"\n",
" # Add operations as nodes (gates as boxes)\n",
" for output in op_by_ouput:\n",
@@ -9277,14 +9303,20 @@
" # Create gate node in a box\n",
" gate_label = f'{gate}'\n",
" gate_name = f'{left}_{right}_{gate}' # Unique gate name\n",
- " dot.node(gate_name, gate_label, shape='box') # Box shape for operators\n",
+ " gate_style = gate_styles.get(gate, {\"shape\": \"box\"})\n",
+ " dot.node(gate_name, gate_label, style='filled', **gate_style) # Box shape for operators\n",
"\n",
" # Connect inputs to gate\n",
+ " left_style = output_styles.get(left[0], {}) \n",
+ " right_style = output_styles.get(right[0], {}) \n",
+ " dot.node(left, left, shape='circle', style='filled', **left_style) \n",
+ " dot.node(right, right, shape='circle', style='filled', **right_style) \n",
" dot.edge(left, gate_name)\n",
" dot.edge(right, gate_name)\n",
"\n",
" # Connect gate to output\n",
- " dot.node(output, output, shape='circle') # Output node as circle\n",
+ " output_style = output_styles.get(output[0], {}) \n",
+ " dot.node(output, output, shape='circle', style='filled', **output_style) # Output node as circle\n",
" dot.edge(gate_name, output)\n",
"\n",
" # Render the graph to a file\n",