8
n8n 한국어amn8n.com

하노이 탑

고급

이것은Engineering, Multimodal AI분야의자동화 워크플로우로, 21개의 노드를 포함합니다.주로 If, Set, Code, ManualTrigger, ExecuteWorkflow 등의 노드를 사용하며. 서브 워크플로우를 사용하여 재귀 알고리즘: 하노타 데모

사전 요구사항
  • 특별한 사전 요구사항 없이 가져와 바로 사용 가능합니다
워크플로우 미리보기
노드 연결 관계를 시각적으로 표시하며, 확대/축소 및 이동을 지원합니다
워크플로우 내보내기
다음 JSON 구성을 복사하여 n8n에 가져오면 이 워크플로우를 사용할 수 있습니다
{
  "id": "VPnclcR3gHg85eOV",
  "meta": {
    "instanceId": "1ee7910f98ee64be6f03d5c49b072eda83992583a161149dc94314ed0b0a2fe0"
  },
  "name": "Towers of Hanoi",
  "tags": [],
  "nodes": [
    {
      "id": "d0112e92-b3e0-4d97-b06d-382470864364",
      "name": "원반 개수 설정",
      "type": "n8n-nodes-base.set",
      "position": [
        912,
        1664
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "c775d359-9599-494b-918c-3e46aae9274c",
              "name": "numberOfDiscs",
              "type": "number",
              "value": 4
            }
          ]
        }
      },
      "notesInFlow": true,
      "typeVersion": 3.4
    },
    {
      "id": "b76775a3-9cf4-4cb5-9945-4cb7d2df7436",
      "name": "최대 1개 원반",
      "type": "n8n-nodes-base.if",
      "position": [
        752,
        1984
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "26c868df-4677-4ded-9ba5-7a69fc3cfd06",
              "operator": {
                "type": "number",
                "operation": "lte"
              },
              "leftValue": "={{ $json.numberOfDiscs }}",
              "rightValue": 1
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a4ce4e6c-cc21-43f3-b1ae-04768a1abee3",
      "name": "A B C",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        1328,
        1664
      ],
      "parameters": {
        "options": {
          "waitForSubWorkflow": true
        },
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "VPnclcR3gHg85eOV",
          "cachedResultName": "Towers of Hanoi"
        },
        "workflowInputs": {
          "value": {
            "logs": "={{ $json.logs }}",
            "stackX": "={{ $json.stackA }}",
            "stackY": "={{ $json.stackB }}",
            "stackZ": "={{ $json.stackC }}",
            "numberOfDiscs": "={{ $json.numberOfDiscs }}"
          },
          "schema": [
            {
              "id": "numberOfDiscs",
              "type": "number",
              "display": true,
              "required": false,
              "displayName": "numberOfDiscs",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackX",
              "type": "object",
              "display": true,
              "required": false,
              "displayName": "stackX",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackY",
              "type": "object",
              "display": true,
              "required": false,
              "displayName": "stackY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackZ",
              "type": "object",
              "display": true,
              "required": false,
              "displayName": "stackZ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "logs",
              "type": "array",
              "display": true,
              "required": false,
              "displayName": "logs",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "notesInFlow": true,
      "typeVersion": 1.2
    },
    {
      "id": "5ef7690f-7554-47f5-8124-562edbba5a86",
      "name": "X Y Z",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        640,
        1984
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "numberOfDiscs",
              "type": "number"
            },
            {
              "name": "stackX",
              "type": "object"
            },
            {
              "name": "stackY",
              "type": "object"
            },
            {
              "name": "stackZ",
              "type": "object"
            },
            {
              "name": "logs",
              "type": "array"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "be89d88c-9814-440b-8d49-99fe49e65a4b",
      "name": "X to Z",
      "type": "n8n-nodes-base.code",
      "position": [
        1232,
        1968
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Move disc\nconst disc = $json.stackX.items.pop();\n$json.stackZ.items.push(disc);\n\n// Log\n$json.logs.push($json.stackX.name + \" \" + $json.stackZ.name + \" \" + disc);\n\nreturn $input.item;"
      },
      "typeVersion": 2
    },
    {
      "id": "81ad6f90-0689-43e9-b67b-911c91dade6a",
      "name": "X to Z",
      "type": "n8n-nodes-base.code",
      "position": [
        1232,
        2112
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Move disc\nconst disc = $json.stackX.items.pop();\n$json.stackZ.items.push(disc);\n\n// Log\n$json.logs.push($json.stackX.name + \" \" + $json.stackZ.name + \" \" + disc);\n\nreturn $input.item;"
      },
      "typeVersion": 2
    },
    {
      "id": "e9430884-2810-475f-90d2-9cffcfbaf9c8",
      "name": "업데이트",
      "type": "n8n-nodes-base.code",
      "position": [
        1072,
        2112
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Reset number of discs\n$json.numberOfDiscs += 1;\n\n// Reset stacks (XZY to XYZ)\nconst stack = $json.stackY;\n$json.stackY = $json.stackZ;\n$json.stackZ = stack;\n\nreturn $input.item;"
      },
      "typeVersion": 2
    },
    {
      "id": "ef117924-272e-4eb6-b098-f1a909ae0334",
      "name": "업데이트",
      "type": "n8n-nodes-base.code",
      "position": [
        1520,
        2112
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Reset number of discs\n$json.numberOfDiscs += 1;\n\n// Reset stacks (YXZ to XYZ)\nconst stack = $json.stackY;\n$json.stackY = $json.stackX;\n$json.stackX = stack;\n\nreturn $input.item;"
      },
      "typeVersion": 2
    },
    {
      "id": "a3f48f91-44f9-41c2-963d-51c4d2f4e21d",
      "name": "스택 생성",
      "type": "n8n-nodes-base.code",
      "position": [
        1120,
        1664
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Really check, if you want to waste computing energy. Recursion errors are hard enough. Best regards, Adrian\nconst min = 1;\nconst max = 5;\nif ($json.numberOfDiscs < min) {\n  $json.numberOfDiscs = min;\n}\nif ($json.numberOfDiscs > max) {\n  $json.numberOfDiscs = max;\n}\n\n// Create stack items\nlet items = [];\nfor (let i=$json.numberOfDiscs; i>0; i--) {\n  items.push(i);\n}\n\n// Set data\n$json.stackA = {};\n$json.stackA.name = \"A\";\n$json.stackA.items = items;\n$json.stackB = {};\n$json.stackB.name = \"B\";\n$json.stackB.items = [];\n$json.stackC = {};\n$json.stackC.name = \"C\";\n$json.stackC.items = [];\n$json.logs = [];\n\n// Return this n8n item\nreturn $input.item;"
      },
      "typeVersion": 2
    },
    {
      "id": "ade72738-15aa-4bcf-b98c-d4804eeb949e",
      "name": "X Z Y",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        944,
        2112
      ],
      "parameters": {
        "options": {},
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "VPnclcR3gHg85eOV",
          "cachedResultName": "Towers of Hanoi"
        },
        "workflowInputs": {
          "value": {
            "logs": "={{ $json.logs }}",
            "stackX": "={{ $json.stackX }}",
            "stackY": "={{ $json.stackZ }}",
            "stackZ": "={{ $json.stackY }}",
            "numberOfDiscs": "={{ $json.numberOfDiscs - 1 }}"
          },
          "schema": [
            {
              "id": "numberOfDiscs",
              "type": "number",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "numberOfDiscs",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackX",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "stackX",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackY",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "stackY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackZ",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "stackZ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "logs",
              "type": "array",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "logs",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "notesInFlow": true,
      "typeVersion": 1.2
    },
    {
      "id": "69fe66b5-2244-4ba8-a22f-507613f53f0b",
      "name": "Y X Z",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        1392,
        2112
      ],
      "parameters": {
        "options": {
          "waitForSubWorkflow": true
        },
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "VPnclcR3gHg85eOV",
          "cachedResultName": "Towers of Hanoi"
        },
        "workflowInputs": {
          "value": {
            "logs": "={{ $json.logs }}",
            "stackX": "={{ $json.stackY }}",
            "stackY": "={{ $json.stackX }}",
            "stackZ": "={{ $json.stackZ }}",
            "numberOfDiscs": "={{ $json.numberOfDiscs - 1 }}"
          },
          "schema": [
            {
              "id": "numberOfDiscs",
              "type": "number",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "numberOfDiscs",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackX",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "stackX",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackY",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "stackY",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stackZ",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "stackZ",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "logs",
              "type": "array",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "logs",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "notesInFlow": true,
      "typeVersion": 1.2
    },
    {
      "id": "01a8c211-6e7f-4ef2-a651-84ed77de8390",
      "name": "솔루션",
      "type": "n8n-nodes-base.code",
      "position": [
        1536,
        1664
      ],
      "parameters": {
        "jsCode": "function logsToSentence(logs) {\n  return logs.map((entry, index) => {\n    const [from, to, disc] = entry.split(\" \");\n    let text;\n\n    if (index === 0) {\n      text = `Move disc ${disc} from ${from} to ${to}`;\n    } else if (index === 1) {\n      text = `then ${from} ${disc}→ ${to}`;\n    } else {\n      text = `${from} ${disc}→ ${to}`;\n    }\n\n    text += \",\";\n\n    if (index === 0 || index % 2 === 1) {\n      text += \"\\n\";\n    } else {\n      text += \" \";\n    }\n\n    return text;\n  }).join(\"\").slice(0, -2) + \".\";\n}\n\nreturn { \"solution\" : logsToSentence($input.first().json.logs) };"
      },
      "typeVersion": 2
    },
    {
      "id": "4f5aeb9a-37e0-4a02-9c0d-35dfe57cf70b",
      "name": "사용자 입력",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        1360
      ],
      "parameters": {
        "color": 7,
        "width": 192,
        "height": 448,
        "content": "### Input\n- **numberOfDiscs:** 4 "
      },
      "typeVersion": 1
    },
    {
      "id": "1633c56d-628c-4976-b00a-f2322bffc46f",
      "name": "설정",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1072,
        1360
      ],
      "parameters": {
        "color": 7,
        "width": 192,
        "height": 448,
        "content": "### Setup\n- **numberOfDiscs:** 4  \n- **stackA**\n  - **name:** A  \n  - **items:** 4, 3, 2, 1  \n- **stackB**\n  - **name:** B  \n  - **items:** -  \n- **stackC**\n  - **name:** C  \n  - **items:** -  \n"
      },
      "typeVersion": 1
    },
    {
      "id": "187388ec-ec1c-4ee9-acf2-cad916f301b6",
      "name": "결과",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        1360
      ],
      "parameters": {
        "color": 7,
        "width": 192,
        "height": 448,
        "content": "### Result\n- **numberOfDiscs:** 4  \n- **stackX**\n  - **name:** A  \n  - **items:** -  \n- **stackY**\n  - **name:** B  \n  - **items:** -  \n- **stackZ**\n  - **name:** C  \n  - **items:** 4, 3, 2, 1"
      },
      "typeVersion": 1
    },
    {
      "id": "3a038abe-5ee2-4875-898a-d92910fc343a",
      "name": "해답",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1488,
        1360
      ],
      "parameters": {
        "color": 7,
        "width": 208,
        "height": 448,
        "content": "### Solution\nMove disc 1 from A to B,\nthen A 2→ C,\nB 1→ C, A 3→ B,\nC 1→ A, C 2→ B,\nA 1→ B, A 4→ C,\nB 1→ C, B 2→ A,\nC 1→ A, B 3→ C,\nA 1→ B, A 2→ C,\nB 1→ C."
      },
      "typeVersion": 1
    },
    {
      "id": "2cdfe45e-3284-46b9-933c-c399ed0abfdc",
      "name": "교환",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        1840
      ],
      "parameters": {
        "color": 7,
        "width": 198,
        "height": 416,
        "content": "### Node input\n- **numberOfDiscs** -1 \n- stackX = **stackX** \n- stackY = **stackZ** \n- stackZ = **stackY** "
      },
      "typeVersion": 1
    },
    {
      "id": "f4cef2e4-e803-4b61-b197-56b8ef90685a",
      "name": "이동",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1184,
        1840
      ],
      "parameters": {
        "color": 7,
        "width": 192,
        "height": 416,
        "content": "### Node steps\n- disc = **stackX**.pop()\n- **stackZ**.push(disc)"
      },
      "typeVersion": 1
    },
    {
      "id": "b4ad8c17-ff19-4cd6-a848-207ec67918e1",
      "name": "갱신",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1504,
        1840
      ],
      "parameters": {
        "color": 7,
        "width": 192,
        "height": 416,
        "content": "### Node steps\n- **numberOfDiscs** += 1\n- YXZ to XYZ\n  - stack = **stackY**\n  - **stackY** = **stackX**\n  - **stackX** = stack"
      },
      "typeVersion": 1
    },
    {
      "id": "89a9c41f-42c4-48c1-a187-a90a795f7bdd",
      "name": "시작",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        640,
        1664
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "9baa2d1d-6d3b-4d8f-9d95-db479479a4e2",
      "name": "하노이의 탑",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        1360
      ],
      "parameters": {
        "color": 5,
        "width": 576,
        "height": 1024,
        "content": "## Towers of Hanoi\nThis is an **example of using sub-workflow nodes** and a proof of concept showing that it’s possible to **solve and explain recursive problems with n8n**.\n\n### Task\nMove a stack of n disks from rod A to rod C, using rod B as auxiliary. Only one disk can be moved at a time, and no disk may be placed on a smaller disk.\n\n### Example\n```\nn=4\n     |          |          |\n     =          |          |\n    ===         |          |\n   =====        |          |\n  =======       |          |\n ---------  ---------  ---------\n     A          B          C\n```\n### Algorithm\n```\nprocedure Hanoi(n, X, Y, Z):\n  if n == 1:\n    move disk from X to Z\n  else:\n    Hanoi(n-1, X, Z, Y)\n    move disk from X to Z\n    Hanoi(n-1, Y, X, Z)\n```\nAnother variant, with better readability and no redundant code, but it includes empty n8n executions (when n is 0):\n```\nprocedure Hanoi(n, X, Y, Z):\n    if n > 0:\n        Hanoi(n-1, X, Z, Y)\n        move disk from X to Z\n        Hanoi(n-1, Y, X, Z)\n```\n### Notes\n- This is a learning example. In a real scenario, you would probably use an iterative approach with only a single code node.\n- The workflow variables X, Y, and Z represent the positions of the rods. E.g., if rods A and B are swapped, A is at position Y and B is at position X.\n- As the modified number of discs and positions are returned when a sub-workflow finishes, the \"Update\" nodes reset these values.\n- When experimenting with recursion, make sure to define a termination condition first. Also, be aware of the \"Restart workspace\" link in the [n8n Dashboard](https://app.n8n.cloud/manage).\n- Check Towers of Hanoi on [GitHub](https://github.com/adibaba/n8n.workflows)\n- Learn more about [Recursion on Wikipedia](https://en.wikipedia.org/w/index.php?title=Recursion_(computer_science)&oldid=1301600240#Towers_of_Hanoi)."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "50e00ac4-9c41-4e49-9390-4f196d97ad1a",
  "connections": {
    "a4ce4e6c-cc21-43f3-b1ae-04768a1abee3": {
      "main": [
        [
          {
            "node": "01a8c211-6e7f-4ef2-a651-84ed77de8390",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "89a9c41f-42c4-48c1-a187-a90a795f7bdd": {
      "main": [
        [
          {
            "node": "d0112e92-b3e0-4d97-b06d-382470864364",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5ef7690f-7554-47f5-8124-562edbba5a86": {
      "main": [
        [
          {
            "node": "b76775a3-9cf4-4cb5-9945-4cb7d2df7436",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ade72738-15aa-4bcf-b98c-d4804eeb949e": {
      "main": [
        [
          {
            "node": "ef117924-272e-4eb6-b098-f1a909ae0334",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "69fe66b5-2244-4ba8-a22f-507613f53f0b": {
      "main": [
        [
          {
            "node": "ef117924-272e-4eb6-b098-f1a909ae0334",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ef117924-272e-4eb6-b098-f1a909ae0334": {
      "main": [
        [
          {
            "node": "81ad6f90-0689-43e9-b67b-911c91dade6a",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "81ad6f90-0689-43e9-b67b-911c91dade6a": {
      "main": [
        [
          {
            "node": "69fe66b5-2244-4ba8-a22f-507613f53f0b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "b76775a3-9cf4-4cb5-9945-4cb7d2df7436": {
      "main": [
        [
          {
            "node": "81ad6f90-0689-43e9-b67b-911c91dade6a",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ade72738-15aa-4bcf-b98c-d4804eeb949e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a3f48f91-44f9-41c2-963d-51c4d2f4e21d": {
      "main": [
        [
          {
            "node": "a4ce4e6c-cc21-43f3-b1ae-04768a1abee3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d0112e92-b3e0-4d97-b06d-382470864364": {
      "main": [
        [
          {
            "node": "a3f48f91-44f9-41c2-963d-51c4d2f4e21d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
자주 묻는 질문

이 워크플로우를 어떻게 사용하나요?

위의 JSON 구성 코드를 복사하여 n8n 인스턴스에서 새 워크플로우를 생성하고 "JSON에서 가져오기"를 선택한 후, 구성을 붙여넣고 필요에 따라 인증 설정을 수정하세요.

이 워크플로우는 어떤 시나리오에 적합한가요?

고급 - 엔지니어링, 멀티모달 AI

유료인가요?

이 워크플로우는 완전히 무료이며 직접 가져와 사용할 수 있습니다. 다만, 워크플로우에서 사용하는 타사 서비스(예: OpenAI API)는 사용자 직접 비용을 지불해야 할 수 있습니다.

워크플로우 정보
난이도
고급
노드 수21
카테고리2
노드 유형7
난이도 설명

고급 사용자를 위한 16+개 노드의 복잡한 워크플로우

저자
Adrian

Adrian

@adrian

AI Software & Platform Engineer. Senior Technical Consultant, Associate Researcher (Data Science & Computer Science Education), Project Engineer, Master of Computer Science (M.Sc.)

외부 링크
n8n.io에서 보기

이 워크플로우 공유

카테고리

카테고리: 34