dnd 5e – How much damage do you take when traversing an area filled with Burning oil in multiple squares?

Bear in mind that oil in this context is generally slow-burning lamp oil, not any kind of modern refined petroleum product. From a game balance perspective, a flask available for one silver piece shouldn’t compete in power with magic spells that do fire damage.

Here are the rules for oil flasks from the Player’s Handbook:

Oil usually comes in a clay flask that holds 1 pint. As an action, you can splash the oil in this flask onto a creature within 5 feet of you or throw it up to 20 feet, shattering it on impact. Make a ranged attack against a target creature or object, treating the oil as an improvised weapon. On a hit, the target is covered in oil. If the target takes any fire damage before the oil dries (after 1 minute), the target takes an additional 5 fire damage from the burning oil. You can also pour a flask of oil on the ground to cover a 5-foot-square area, provided that the surface is level. If lit, the oil burns for 2 rounds and deals 5 fire damage to any creature that enters the area or ends its turn in the area. A creature can take this damage only once per turn.

The last, bolded sentence is the one we really care about, but the rest of the rules are important for context. Of course, since there’s some ambiguity in this critical sentence, it’s up to each individual DM to determine how they will resolve that ambiguity in their own game. What follows is my reasoning about how to interpret this language and how I would rule in my own games.

First, it should be noted that covering a creature with oil from one flask and setting them on fire only does 5 fire damage.

Second, if a creature stands in a square of ignited oil for their entire turn, they also take only 5 fire damage.

We can infer from these two points that in general, being exposed to burning oil for a whole turn will do 5 fire damage.

Let’s then consider a slightly more involved scenario: a doorway whose space is filled with ignited oil. If a character’s turn consists of running through the doorway, grabbing an object on the floor, and then running back out, it’s clear from the rules that the character will take only 5 points of fire damage, since “A creature can take this damage only once per turn”.

This is also consistent with the idea that a single turn’s exposure to burning oil will do 5 fire damage.

In all of the above cases, the scope of “this damage” is clearly confined to meaning “the damage caused by one specific flask of oil”. But it’s not clear that that’s the limit of what “this damage” might mean. “This damage” could be taken to mean “damage from all burning oil sources”.

Let’s revisit our burning doorway scenario, but have the character exit the room through a second doorway, also filled with ignited oil. How much damage should the character take?

An argument can be made for either 5 fire damage or 10 fire damage. In the latter case, “this damage” is interpreted to mean “fire damage from this specific flask of oil”.

Given that there’s no other language present to disambiguate “this damage”, we can see which interpretation is more consistent with other information we have about how burning oil is intended to behave.

We know that the cases where a creature has the maximum amount of time possible exposed to burning oil in a turn results in 5 fire damage. These are the first two examples considered above, where a creature is either doused in oil and ignited, or where they stand immobile in burning oil for a whole turn.

So what interpretation of the meaning of “a creature can take this damage only once per turn” is most consistent with the other rules that limit whole-turn damage from burning oil to 5 points? To my mind, it seems most consistent to cap the damage to a creature from all burning oil sources to 5 fire damage per turn.

In the other interpretation, where fire damage is limited per oil source, characters are incentivized to act in ways that don’t make much sense in context. For example, if a whole corridor is full of burning oil, a character will take less damage if they stand immobile in one square than if they sprint across several squares.

Finally, given the relative ease that characters can obtain burnable oil, limiting the total per-creature per-turn damage seems more in keeping with the intended power level.

godot – Traversing an acyclic binary tree to construct paths from a given starting node, but the paths come out wrong

The tree is an acyclic binary tree. It’s composed of node objects that have a list of connections to link objects (at most 3), and link objects that have a list of connections to node objects (always 2). I am trying to construct a list of possible paths to other nodes that can be reached given a fuel budget and a fuel cost on each link. What it is supposed to do is go through each non-backtracking connection of a node, and spawn a new route and thread to investigate that, leaving the current one to end at that node and thus create a list of routes to every node in the reachable area. When executed, the list of end destinations are valid but many of the paths that are constructed to get to them are wrong, going down other branches in the tree that are extraneous or entirely outside of the reachable area bounded by the fuel budget as well as jumping between nodes that aren’t directly connected. There seems to be some pattern in the errors, when going down from the root of some branches of the tree the path goes down every offshoot in order first instead of going in a straight line, and when going up the tree the path tends to go further out and make triangle shapes, often landing somewhere other than the listed destination. I have already checked the link and node connections themselves to see if they are assigned properly, and they are. What am I getting wrong?

Route class definition

var origin:Node
var destination:Node
var totaldV:float
var totalt:float
var dVBudget:float
var tBudget:float
var tdVRatio:float
var links:Array
var nodes:Array

func duplicate_values(originator:Route):
    origin = originator.origin
    destination = originator.destination
    totaldV = originator.totaldV
    totalt = originator.totalt
    dVBudget = originator.dVBudget
    tBudget = originator.tBudget
    tdVRatio = originator.tdVRatio
    nodes = originator.nodes
    links = originator.links


func _init(originator_route):
    if originator_route != null:
        duplicate_values(originator_route)

Tree traversal algorithm

var routes:Array
onready var root = get_node("..")

func traverse(current_node:Node, previous_route:Route):
    if previous_route == null:                             # Starts off the recursion by providing an initial node
        previous_route = Route.new(null)
        previous_route.origin = current_node
        previous_route.nodes.append(previous_route.origin)
        previous_route.dVBudget = 2000
        previous_route.totaldV = 0
    for link in current_node.connections:
        if (previous_route.totaldV + link.dV < previous_route.dVBudget && 
        !IsBacktracking(previous_route, LinkDestination(link, current_node))):   # If there is enough fuel and the link isn't backtracking, go through it.
            var working_route:Route = Route.new(previous_route)    # Copy the previous route to make the new route
            routes.append(working_route)
            working_route.destination = LinkDestination(link, current_node)
            working_route.totaldV += link.dV
            working_route.totalt += link.t
            working_route.links.append(link)
            working_route.nodes.append(working_route.destination)
            traverse(working_route.destination, working_route)
    DisplayRoutes()
    root.get_parent().pathSelectionFlag = true   # UI control boolean


func IsBacktracking(route:Route, destinationNode:Node) -> bool:
    for nodeI in route.nodes:
        if (destinationNode == nodeI):
            return true
    return false


func LinkDestination(link:Node, originNode:Node) -> Node:    # Finds the node on the other side of a link
    for nodeI in link.connections:
        if (nodeI != originNode):
            return nodeI
    return originNode

c++ – Octree LOD without traversing the entire tree

I am working on a voxel engine that uses a huge Hashed Linear Octree that reconfigures when you move. Each octree leaf is a voxel. The world is procedurally generated using 2D Perlin noise.

The octree utilizes face culling and instancing to accomplish pretty good performance in OpenGL. I have implemented LODs in order to allow for much bigger scenes and my bottleneck has quickly shifted from rendering faces to generating the Octree.

Each time the camera moves I need to reconfigure the Octree’s LOD in order to ensure the viewer sees high detail near him and low detail in the distance. The system works great for small Octrees (256^3) but as soon as I go to a 1024^3 Octree, the generation of the Octree LOD takes 1-2 minutes. Even done on a separate thread it isn’t enough.

I am sure there is a way to generate the Octree world without traversing the whole Octree but I could not find it.

The basic outline of how I do the Octree LOD generation when the camera moves:

  1. Start traversing the Octree at the root node

  2. For each node, check the distance of the node’s center from the camera

    2.a. If the node is a leaf and the distance is smaller than the node size * CONSTANT, divide it. If it is not a leaf, traverse its children and go back to (2).

    2.b. If the node is not a leaf, and the distance is larger than the node size * CONSTANT, collapse the node if needed.

That’s basically it. Because the world is procedurally generated, dividing each node means iterating its entire volume (x+1,z,x+2,z…x,z+1,x,z+2…x+1,z+1….) to determine if the 2D Perlin noise passes through the node volume, above it, or below it (This has to be part of the problem as for 256^3 nodes it takes 65536 iterations).

I know that I can improve this by parallelizing the entire algorithm, but I still feel like there has to be 1) a way to calculate LODs without entire tree traversal, and 2) figuring out if to divide the node without iterating through its whole volume 1 by 1.

Would love to get some pointers, I could not find many resources about this online.

Intercepting Query String Changes in Web Parts -Error when traversing between items in Left nav (SPFx Webparts)

I am working in Sharepoint online 2019 with SPFx Webaparts. We had a requirement to change query string (added filter)

in application spfx webpart with kendo grid. It got changed in URL but the grid not reloaded. So we used Intercepting query logic by referring https://docs.microsoft.com/en-us/sharepoint/dev/spfx/web-parts/guidance/intercepting-query-changes-i…

Everything works fine inside the webpart. Query changed in URL reflected in grid and data loaded based on query string.

Now the issue is when we traverse between items in left navigation (between the applications)

“Cannot read property ‘web’ of undefined”

“Cannot read property ‘wrapper’ of undefined”

error is coming.(kindly see attachment).

Before implementing Query intercepting it was working fine.

Couldn’t find the solution to fix this issue. Please help!!!

Is there anything to deal with Webpart rendering?!! Any help!

enter image description here
Thanks

Annamsoft

Algorithms – traversing the depth of the directional acyclic graph in a specific order

I want to visit the outgoing edges of each vertex in a specific order.

However, it is difficult for me to specify an algorithm for calculating this order.

Here are my considerations:

  1. Define order
  2. Minimum failing example
  3. More problematic examples

To let $ v in V $ be a vertex of a graph $ G (V, E) $ and $ a $ and $ b $ Be vertices connected by outgoing edges $ (v, a) $ and $ (v, b) $ from $ v $.

Then the order relative to $ v $ gives one of $ a <_vb $, $ a> _vb $, $ a = _vb $.

Equality is a valid result, e.g. for the following two graphics:

  v       v
 /      / 
a   b   a   b
          /
          *

There is a function $ t: V rightarrow mathbb {N} $ with the property $ t (w) = Sigma_ {u in V: (w, u) in E} t (u) + 1 $.

To let $ A (V_a, E_a) $ be the spanning tree in which is rooted $ a $ and $ B (V_b, E_b) $ be the spanning tree in which is rooted $ b $. If $ V_a cap V_b = Emptyset $ for all couples of $ (v, a), (v, b) in E $ then $ t (a) <t (b) iff a <b $.

problem: the value $ t (w) $ gives the wrong order for some $ (v, w) in E $ if $ V_a cap V_b neq Emptyset $ for some $ (v, a), (v, b) in E $.

To let $ C (V_c, E_c) $ be the spanning tree for another vertex $ c in V $ With $ (v, c) in E $ so that $ V_a cap V_c neq Emptyset $.

It looks like this (with $ A & # 39 ;, C & # 39 ;, B & # 39; $ are subgraphs of zero or more nodes):

    __v__
   /  |  
  a   c   b
 /  /    
A'  k   C'  B'

Then $ t (b) = t (B &) + 1 $, $ t (a) = t (A)) + 2 $ and $ t (c) = t (C)) + 2 $.

because $ a $ and $ c $ Share the subgraph $ K $ They should be visited one after the other:

  • $ a leq c <b $
  • $ c leq a <b $
  • $ b <a leq c $
  • $ b <c leq a $

What can Not but it happened $ b $ is visited in between:

  • $ a leq b leq c $
  • $ c leq b leq a $

But $ A & # 39 ;, B & # 39 ;, C & # 39; $ can be chosen so that $ t (a) leq t (b) leq t (c) $. That's why $ t $ doesn't work for $ V_a cap V_c neq Emptyset $.

I tried to solve this by definition $ t_1 $ With $ t_1 (a) = max (t (a), t (b)) $ (or $ min $equivalent to). That doesn't work if $ t_1 (a) = t (b) $However, the order is indefinite.

I was thinking of using pairs $ t_2 (a) = (k, t (a)) $ so that $ t_2 (b) = ( epsilon, t (b)) $ is not comparable in the first term, so the nodes can be grouped according to the node they connect with each other.

However, there may be another node $ k_2 $ This is a common descendant of $ k $ and $ b $ – or worse from $ c $ and $ b $.

So there should be another ranking function $ r (w) $ With $ t ^ + (w) = (r (w), t (w)) $. However, it would have to be ensured $ r (w) = r (u) Rightarrow w = u $ or the same problem occurs again.

Example 1: common descendant of $ c $, $ b $

    __v__
   /  |  
  a   c   b
 /  /  / 
A'  k1  k2  B'

Since $ c $ Is connected in the middle with both siblings, it should consider the desired ordering function $ t & # 39; $ The

  • $ t (A & # 39;) <t (B & # 39;) Rightarrow t & # 39; (a) leq t & # 39; (c) leq t ((b) $
  • $ t (B & # 39;) <t (A & # 39;) Rightarrow t & # 39; (b) leq t & # 39; (c) leq t ((b) $
  • $ t (A)) = t (A)) $ could go either way.

If $ A & # 39; $ and $ B & # 39; $ were the same subtree (closing the circle) that would imply $ t ((b) = t # (c) = t ((c) $

Example 2: common descendants of all through $ k_1 $

    __v__
   /  |  
  a   c   b
 /  /    
A'  k1  C'  B'
     _____/
        k3

If there was another offspring $ d $ it should respect both, so the relationship leads to another graph: $ { { {a, c }, b }, d } $.

It could therefore be useful to insert additional virtual nodes to determine the order of the evaluation:

      v
     / 
    *   
   /    
  a   c   b
 /  /    
A'  k1  C'  B'
     _____/
        k3

In this way, the order of the subordinate elements of each node can still be made accordingly $ t $ as previously.

But I don't know if this works for all of the examples, and I'm also drawing a void in how to determine where to insert nodes. I would think someone would have done that before, but I couldn't find anything.

Example 3: common descendants of all without $ k_1 $

    __v__
   /  |  
  a   c   b
 /  /    
A'  k1  C'  B'
 ______|___/
        k4

Solving equations – traversing 2 variables in one function

Well, I have the following problem: I have a function $ f (a, b) $ and I want to check if this function returns a perfect square for a certain value of $ a $ and $ b $. Now I want to search in certain areas:

$$ n_1 le a le n_2 space space space text {and} space space space m_1 le b le m_2 tag1 $$

If I now only want to do this for one variable, I use the following code:

a = n1;
ParallelTable(
  If(TrueQ(Sqrt(f(a, b)) (Element) Integers), b, Nothing), {b, m1, 
   m2}) //. {} -> Nothing

Question: but how do I edit the code like this $ n_1 $ is inserted into the equation and the code runs through $ m_1 le b le m_2 $ to check if a value of $ n_1 $ and $ b $ are a perfect square and after checking that it works $ n_1 + 1 $ and runs again $ m_1 le b le m_2 $ and so on until it hits $ n_2 $?

Algorithm – traversing a tree with two types of nodes while keeping all ancestors

I wrote code that stores an AWS organization tree in a tree data structure in Rust. In the tree structure, I use a slightly modified pre-order pass algorithm to print all accounts in the organization in a table, keeping track of all ancestors for each account.

AWS organizations consist of a master organizational unit (OU) that can contain other organizational units or accounts. Organizational units can contain organizational units or accounts. In the tree language, accounts are necessarily leaf nodes, while organizational units can be branches or leaves. No order is defined in the tree.

In my code, I represent an AWS organization as a tree structure. I want to be able to output the names and OU membership of all accounts in the organization. Suppose we had the following tree:

  • root
  • Root: OU1
  • Root: OU1: OU11
  • Root: OU1: OU11: A1
  • Root: OU1: OU11: A2
  • Root: OU1: A3
  • Root: A4

The algorithm would print something like this:

A4
OU1:OU11:A3
OU1:OU11:A2
OU1:OU11:A1

To do this, I use a slightly modified iterative pre-order traverse with an additional variable that I called height_stack. This stack keeps track of the number of children that still need to be displayed in this branch. When we move a branch into the stack, we move the number of children the branch has to the height_stack. We decrement the last element of this height stack every time we burst the stack. At the end of each iteration, we check whether the last element of the height stack is zero. In this case, all zero elements of the height stack are shown.

Below is the code I came up with. I show both the recursive construction of the tree (recursively_build_account_tree) and the crossing (list_accounts_per_ou) because the algorithm assumes that organizational units appear before accounts in the subordinate elements Vec.

Is there a better algorithm to do this for a tree with an unknown number of children per node? (I know that there is a lot of Rusoto boilerplate, hopefully it won't make the code too difficult to read.)

use comfy_table::{Attribute, Cell, ContentArrangement, Row, Table, TableComponent};
use rusoto_organizations::{
    Account, DescribeAccountRequest, DescribeOrganizationalUnitRequest, ListChildrenRequest,
    ListRootsRequest, OrganizationalUnit, Organizations, OrganizationsClient, Root,
};
use std::{thread, time};

/// In an AWS Organizations, each node of the account tree can either be an OU or an account.
#(derive(Debug))
enum OrgNode {
    Ou(OrganizationalUnit),
    Account(Account),
}

/// m-ary tree to represent the AWS organization.
#(derive(Debug))
struct OrgTree {
    root: OrgNode,
    children: Option>>,
}

impl OrgTree {
    pub fn new(root: OrgNode) -> OrgTree {
        OrgTree {
            root: root,
            children: None,
        }
    }
}

/// Starting from a root of the AWS Organization, we first request all of its child OUs, and then
/// all of its child accounts. This ensures that preorder traversal list all accounts that belong
/// to an OU before listing accounts that belong to nested OUs.
///
/// The `thread::sleep` in the loops are necessary to not hit AWS Organizations' API limits.
///
/// # Example
///
/// Say we had the following tree:
/// ```ascii
///
///                            R
///                           / 
///                          /   
///                         OU    A
///                        / | 
///                       /  |  
///                      /   |   
///                     OU  A1    A2
/// ```
/// Preorder traversal would print nodes in this order:
///  * R:A
///  * R:OU:A2
///  * R:OU:A1
fn recursively_build_account_tree(client: &OrganizationsClient, node: &mut OrgTree) {
    match &node.root {
        OrgNode::Ou(v) => {
            let list_children_request = ListChildrenRequest {
                parent_id: v.id.as_ref().unwrap().to_string(),
                child_type: "ORGANIZATIONAL_UNIT".to_string(),
                max_results: None,
                next_token: None,
            };

            let list_children_response = client
                .list_children(list_children_request)
                .sync()
                .unwrap()
                .children
                .unwrap();

            if list_children_response.len() > 0 {
                node.children = Some(Vec::new());

                for element in list_children_response.iter() {
                    // Describe the OU.
                    let describe_org_unit_request = DescribeOrganizationalUnitRequest {
                        organizational_unit_id: element.id.as_ref().unwrap().to_string(),
                    };

                    let describe_org_unit_response = client
                        .describe_organizational_unit(describe_org_unit_request)
                        .sync()
                        .unwrap()
                        .organizational_unit
                        .unwrap();
                    if let Some(v) = &mut node.children {
                        v.push(Box::new(OrgTree::new(OrgNode::Ou(
                            describe_org_unit_response,
                        ))));

                        thread::sleep(time::Duration::from_millis(200));
                    }
                }
            }

            // Request accounts in this OU.
            let list_children_request = ListChildrenRequest {
                parent_id: v.id.as_ref().unwrap().to_string(),
                child_type: "ACCOUNT".to_string(),
                max_results: None,
                next_token: None,
            };

            let list_children_response = client
                .list_children(list_children_request)
                .sync()
                .unwrap()
                .children
                .unwrap();

            if list_children_response.len() > 0 {
                match &mut node.children {
                    Some(_) => (),
                    None => {
                        node.children = Some(Vec::new());
                    }
                }

                for element in list_children_response {
                    let describe_account_request = DescribeAccountRequest {
                        account_id: element.id.unwrap(),
                    };

                    let describe_account_response = client
                        .describe_account(describe_account_request)
                        .sync()
                        .unwrap()
                        .account
                        .unwrap();

                    node.children
                        .as_mut()
                        .unwrap()
                        .push(Box::new(OrgTree::new(OrgNode::Account(
                            describe_account_response,
                        ))));

                    thread::sleep(time::Duration::from_millis(200));
                }
            }

            // Recursively build the tree.
            match &mut node.children {
                Some(v) => {
                    for element in v {
                        recursively_build_account_tree(client, &mut *element);
                    }
                }

                None => (),
            };
        }

        OrgNode::Account(_) => (),
    }
}

/// Fetches all of the accounts in the AWS Organizations and outputs
/// them in a Markdown-compatible table.
pub fn list_accounts_per_ou(client: &OrganizationsClient) -> Table {
    let root_request = ListRootsRequest {
        max_results: None,
        next_token: None,
    };

    let root: Root = client
        .list_roots(root_request)
        .sync()
        .unwrap()
        .roots
        .unwrap()(0)
        .clone();

    // Coerce the root into an OU (kinda cheating).
    let root_as_ou = OrganizationalUnit {
        arn: root.arn,
        id: root.id,
        name: root.name,
    };

    let mut org_tree = OrgTree::new(OrgNode::Ou(root_as_ou));

    // Recursively build the account tree.
    match &org_tree.root {
        OrgNode::Ou(_) => {
            recursively_build_account_tree(&client, &mut org_tree);
        }

        _ => panic!(
            "The root node should be an OU, no whathever it is: {:?}",
            org_tree
        ),
    }

    let mut table = Table::new();
    const MARKDOWN: &str = "||  |-|||           ";
    table.load_preset(MARKDOWN).set_header(vec!(
        Cell::new("Account name").add_attribute(Attribute::Bold),
        Cell::new("Account ID").add_attribute(Attribute::Bold),
        Cell::new("OU name").add_attribute(Attribute::Bold),
        Cell::new("Email").add_attribute(Attribute::Bold),
    ));

    // When printin the accounts, I print the account's parent OUs' names.
    // To do that, I need to keep of how deep I am in the tree struture, and
    // what the parent OUs are.
    //
    // I use the a typical stack-based preorder traversal algorithm.
    // To keep track of the OUs,, I define what I can an height stack that is vec that stores
    // the degree of the node that we pop from the stack. Each time we push an OU, we push
    // degree of that OU to the height stack. When we pop any node, we decrement the
    // degree counter in the vec until it reaches 0, then we pop the stack. We pop
    // until there are no non-zero counters.
    let mut stack: Vec<&OrgTree> = Vec::new();
    let mut height_stack: Vec = Vec::new();
    let mut res: Vec<&OrgTree> = Vec::new();
    let mut ou_prefix: Vec = Vec::new();

    stack.push(&org_tree);
    height_stack.push(1);
    while !stack.is_empty() {
        let node = stack.pop().unwrap();
        res.push(node);

        println!("{:#?}", ou_prefix);
        println!("{:#?}", height_stack);

        if let Some(last) = height_stack.last_mut() {
            *last -= 1;
        }

        match &node.root {
            OrgNode::Ou(ou) => {
                if let Some(ref children) = node.children {
                    ou_prefix.push(ou.name.as_ref().unwrap().to_string());
                    height_stack.push(children.len());
                    for elem in children {
                        stack.push(elem);
                    }
                }
            }
            OrgNode::Account(account) => {
                table.add_row(Row::from(vec!(
                    account.name.as_ref().unwrap().to_string(),
                    account.id.as_ref().unwrap().to_string(),
                    build_ou_prefix(&ou_prefix),
                    account.email.as_ref().unwrap().to_string(),
                )));
            }
        }

        while let Some(0) = height_stack.last() {
            height_stack.pop();
            ou_prefix.pop();
        }
    }

    table
}
```

Interview questions – carrying out traversing from the left or from the right

I saw Professor Sheep's Leetcode 140: Word Break II

Youtube video here:
https://www.youtube.com/watch?v=pu9z4qxp76c

CPP code here:
https://github.com/jzysheep/LeetCode/blob/master/140.%20Word%20Break%20II.cpp

My own Python translation codes below. I think in this case the code can be optimized by crossing from right to left, since the code only starts with the last word. I passed both implementations to leetcode and executed the procedure from the left with 40 ms and the procedure from the right with 36 ms.

I don't think the left and right are the same. Just like functional programming, where foldLeft has advantages over foldRight in general (no language optimization or special cases). In this case, I think the right-to-left approach is an advantage.

Please help me to check my thinking or to prove myself convincingly.

From the left (like Professor Sheep)

class Solution:
    def wordBreak(self, s: str, wordDict: List(str)) -> List(str):
        dic = set(wordDict)
        memo = {}

        def internal(sc):
            if not sc:
                return ()
            if sc in memo:
                return memo(sc)
            res = ()
            if sc in dic:
                res.append(sc)

            for pos in range(1, len(sc)):
                right = sc(pos:)
                if right not in dic:
                    continue
                left = sc(:pos)
                lfls = internal(left)
                for lf in lfls:
                    res.append(lf + " " + right)
            memo(sc) = res
            return res
        return internal(s)

From the right

    def wordBreak(self, s: str, wordDict):
        dic = set(wordDict)
        memo = {}

        def internal(sc):
            if not sc:
                return ()
            if sc in memo:
                return memo(sc)
            res = ()
            if sc in dic:
                res.append(sc)

            for pos in range(len(sc), -1, -1):
                right = sc(pos:)
                if right not in dic:
                    continue
                left = sc(:pos)
                lfls = internal(left)
                for lf in lfls:
                    res.append(lf + " " + right)
            memo(sc) = res
            return res
        return internal(s)
```

Algorithms – traversing a graph based on edges

To let $ G $ be a $ k $-regular graphics where $ k $ is a constant number. Each edge of the graph is labeled either 0 or 1. Provided such a graph and a staring vertex $ u $ and $ l $ Length string of 0 and 1, we must follow the edges of the graph $ G $ based on given string. What is the best algorithm for such a problem? I can solve this problem $ O (l) $ Time. I'm looking for an algorithm with better runtime response.