Optimization – Intuition behind this specific algorithm for time series

I go through the EPI book and need help to understand this part.

There is one problem 5.7, which is to buy and sell twice in a single time series to maximize profits. The entry is made as a list of ints. The example they give is:

(12, 11, 13, 9, 12, 8, 14, 13, 15)

Here, the maximum profit of a single buy-sell event is 7; buy at 8 and sell at 15. At two buy-sell events, there are 10; buy at 9, sell at 12 and buy at 8, sell at 15.

The intuition for a single buy-sell is simple if we just track the minimal item in the list and the difference between the minimum and the current item is the profit.

What I do not understand is how the double buy-sell formula works. The book proposes a solution in which two passes through the data, one forward and one backward pass. The forward pass uses the same formula as above (single buy-sell), but the backward pass starts at the bottom of the list and tracks the maximum instead. The winnings of the reverse pass are stored in an array and added to the winnings of the forward pass $ M (i) = F (i-1) + B (i) $, and where $ F (-1) = 0 $,

Why does the backward pass follow the maximum and how does the formula ensure that we do not buy before the second sale?

Here is the solution code:

def buy_and_sell_stock_twice(prices: List(float)) -> float:
    max_total_profit, min_price_so_far = 0.0, float('inf')
    first_buy_sell_profits = (0.0) * len(prices)
    for i, price in enumerate(prices):
        min_price_so_far = min(min_price_so_far, price)
        max_total_profit = max(max_total_profit, price - min_price_so_far)
        first_buy_sell_profits(i) = max_total_profit
    # Now for the backwards pass.
    max_price_so_far = float('-inf')
    for i, price in reversed(list(enumerate(prices(1:), 1))):
        max_price_so_far = max(max_price_so_far, price)
        max_total_profit = max(
            max_price_so_far - price + first_buy_sell_profits(i - 1))
    return max_total_profit

For some reason, the code highlighting does not appear in the design even though I've specified the language.

I have broken down the iterator in reverse, resulting in:

((8, 15), (7, 13), (6, 14), (5, 8), (4, 12), (3, 9), (2, 13), (1, 11))

The expected result of the backward pass is also provided for the sample data:

B = (7, 7, 7, 7, 7, 7, 2, 2, 0)

Through the code I can see how the algorithm can be used to fill B. What makes no sense is why this backward pass guarantees the maximum profit, how it guarantees sensible purchases and sales, and what the intuition is for the way.

I looked at similar questions, but they provide different solutions that work well but do not give insight into the book's solution. The book is not readily available online, so there is less content about the material.

Can there be an algorithm faster than the fast Fourier transform to square a polynomial?

FFT is a fast algorithm for multiplying two polynomials, but if it is a square (ie, the polynomial multiplied by itself), can we find something better? (I have reached a paper by Jaewook Chung and M. Anwar Hussain and then something known as the Toom-Cook algorithm, but can no longer find any claims.)

What is the temporal and spatial complexity of the 3Sum problem with the following algorithm?

There was this problem where all unique triplets of elements of an array that added to zero had to be returned (swapping the digits of two elements in the triplet does not count as unique).

I found the following code:

    function threeSum(nums) {
      nums.sort((a, b) => a - b);
      const result = ();
      for (let i = 0; i < nums.length; i++) {
        // skipping duplicates
        if (i !== 0 && nums(i) === nums(i - 1)) continue;
        let left = i + 1;
        let right = nums.length - 1;
        while (left < right) {
          const s = nums(i) + nums(left) + nums(right);
          // too small; move to the right
          if (s < 0) left++;
          // too big; move to the left
          else if (s > 0) right--;
          // bingo
          else {
            result.push((nums(i), nums(left), nums(right)));
            while (left + 1 < right && nums(left) === nums(left + 1)) left++;
            while (right - 1 > left && nums(right) === nums(right - 1)) right--;
      return result;
    // expected output: ((-4,-2,6),(-4,0,4),(-4,1,3),(-4,2,2),(-2,-2,4),(-2,0,2))

I think the temporal complexity is O (n ^ 2), We assume that there is sorting at the beginning O (n log n) and the nested loop works approximately (n 2) / 2 translated something O (n ^ 2), In the end we stay with you O (n log n + n ^ 2) and since n log n is removed to a lesser extent and leaves with us O (n ^ 2),

I'm not sure about the complexity of the room, but intuitively I think that's one On),

Can you please correct / confirm my thoughts / conjectures on temporal and spatial complexity?

Substrings – Is there an algorithm for splitting parts of strings?

Let's say we have the strings Hello, World. Hello and World, The algorithm I think of would produce a steady buffer containing Hello, World and the previous three would then become references or slices of that one buf[0,11], buf[0,4], buf[7,11],

One way to implement this algorithm is to compare all new strings with the existing buffer and reuse it if possible, or append the new string if it does not. This would be very slow, but it should work. However, a case is treated as not efficient Hey, Hello because it would either attach it to the buffer, add it Hello again, or add Hey, to the beginning and update all indices.

If space saving is the optimal solution, this is the final buffer Hey, Hello, World,

Is there an algorithm that does something similar?

I've read about ropes and read this article, but I do not see how these would help.

Algorithm – How can I calculate the distance between the parent and the neighboring node if there is a line of sight between two points?

I've finished my Astar algorithm in Python and now I need to turn it into a theta-star algorithm. I have created my line of sight algorithm below by sighting the distance and how could I make it to jump the points that have line of sight. After I run my code, I see that there is no effect. I see that it works as an Astar algorithm. Help please?

The clipping with which I have a problem:

sight = lineOfsight(grid, y, x, y2, x2)
if sight == True:

        g2 = g + delta(i)(2) + math.sqrt((x2 - x)**2 + (y2 - y)**2)

         h2 = math.sqrt((x2 - goal(0))**2 + (y2 - goal(1))**2)

         f2 = g2 + h2

         g2 = g + delta(i)(2)             
         h2 = math.sqrt((x2 - goal(0))**2 + (y2 - goal(1))**2)

         f2 = g2 + h2


My line of sight code:

def lineOfsight(grid, y1, x1, y2, x2):
    y_size = len(grid)
    x_size = len(grid)


    if dy < 0:
        dy = -dy
        sy = -1
        sy = 1

    if dx < 0:
        dx = -dx
        sx = -1
        sx = 1

    f = 0

    if dx >= dy:
        while x1 != x2:
            f = f + dy
            if f >= dx and 0 < y1+(sy-1)/2 and y1+(sy-1)/2 < y_size and 0 < x1+(sx-1)/2 and x1+(sx-1)/2 < x_size:
                if grid(x1+int((sx-1)/2))(y1+int((sy-1)/2)):

                    return False
                y1 = y1 + sy
                f  = f  - dx

            elif 0 < y1+(sy-1)/2 and y1+(sy-1)/2 < y_size and 0 < x1+(sx-1)/2 and x1+(sx-1)/2 < x_size:
                if f != 0 and grid(x1+(sx-1)/2)(y1+(sy-1)/2):

                    return False

            elif 1= dy and 0 < y1+(sy-1)/2 and y1+(sy-1)/2 < y_size and 0< x1+(sx-1)/2 and x1+(sx-1)/2 < x_size:
                if grid(x1+int((sx-1)/2))(y1+int((sy-1)/2)):

                    return False
                x1 = x1 + sx
                f = f - dy
            elif 0 < y1+(sy-1)/2 and y1+(sy-1)/2 < y_size and 0 < x1+(sx-1)/2 and x1+(sx-1)/2 < x_size:
                if f !=0 and grid(x1+int((sx-1)/2))(y1+int((sy-1)/2)):

                    return False

            elif 0 < y1+(sy-1)/2 and y1+(sy-1)/2 < y_size and 1 < x1 and x1 < x_size:       
                if dx == 0 and grid(x1)(y1+ int((sy-1)/2)) and grid(x1-1)(y1+int((sy-1)/2)):

                    return False


    return True

My theta star code:

import matplotlib.pyplot as plt
from lineofsightss import *
#grid format
# 0 = navigable space
# 1 = occupied space

import random
import math

grid = ((0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0),
        (0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
        (0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0),
        (0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0),
        (0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0),
        (0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0),
        (0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0),
        (0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0),
        (0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0),
        (0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0))

init = (0,0)                            #Start location is (5,5) which we put it in open list.
goal = (len(grid)-1,len(grid(0))-1)     

heuristic = ((0 for row in range(len(grid(0)))) for col in range(len(grid)))
for i in range(len(grid)):    
    for j in range(len(grid(0))):            
        heuristic(i)(j) = abs(i - goal(0)) + abs(j - goal(1))


plt.plot((-1, len(grid(0))),((-x/2 for x in range(-1,len(grid)*2+1)), (-y/2 for y in range(-1,len(grid)*2+1))), ".k")
plt.plot(((x/2 for x in range(-2,len(grid(0))*2+1)),(x/2 for x in range(-2,len(grid(-1))*2+1))),(1, -len(grid)),".k")


#Below the four potential actions to the single field

delta =      ((1, 0, 1),
              (0, 1, 1),
              (-1, 0, 1),
              (0, -1, 1),
              (-1, -1, math.sqrt(2)),
              (-1, 1, math.sqrt(2)),
              (1, -1, math.sqrt(2)),
              (1, 1, math.sqrt(2)))

delta_name = ('V','>','<','^','//','\','\','//')

def search():

    #open list elements are of the type (g,x,y)

    closed = ((0 for row in range(len(grid(0)))) for col in range(len(grid)))
    action = ((-1 for row in range(len(grid(0)))) for col in range(len(grid)))
    #We initialize the starting location as checked
    closed(init(0))(init(1)) = 1
    expand=((-1 for row in range(len(grid(0)))) for col in range(len(grid)))

    # we assigned the cordinates and g value
    x = init(0)
    y = init(1)
    g = 0

    h = math.sqrt((x - goal(0))**2 + (y - goal(1))**2)

    f = g + h

    #our open list will contain our initial value
    open = ((f, g, h, x, y))

    found  = False   #flag that is set when search complete
    resign = False   #Flag set if we can't find expand
    count = 0

    #print('initial open list:')
    #for i in range(len(open)):
            #print('  ', open(i))

    while found is False and resign is False:

        #Check if we still have elements in the open list
        if len(open) == 0:    #If our open list is empty, there is nothing to expand.
            resign = True
            print('############# Search terminated without success')
            #if there is still elements on our list
            #remove node from list
            open.sort()             #sort elements in an increasing order from the smallest g value up
            open.reverse()          #reverse the list
            next = open.pop()       #remove the element with the smallest g value from the list
            #print('list item')

            #Then we assign the three values to x,y and g. Which is our expantion.
            x = next(3)
            y = next(4)
            g = next(1)
            #elvation(x)(y) = np.random.randint(100, size=(5,6))
            expand(x)(y) = count

            #Check if we are done
            if x == goal(0) and y == goal(1):
                found = True
                print(next) #The three elements above this "if".
                print('############## Search is success')

                #expand winning element and add to new open list
                for i in range(len(delta)):       #going through all our actions the four actions
                    #We apply the actions to x and y with additional delta to construct x2 and y2
                    x2 = x + delta(i)(0)
                    y2 = y + delta(i)(1)

                    #if x2 and y2 falls into the grid
                    if x2 >= 0 and x2 < len(grid) and y2 >=0 and y2 <= len(grid(0))-1:

                        #if x2 and y2 not checked yet and there is not obstacles
                        if closed(x2)(y2) == 0 and grid(x2)(y2)==0:

                            sight = lineOfsight(grid, y, x, y2, x2)
                            if sight == True:

                                g2 = g + delta(i)(2) + math.sqrt((x2 - x)**2 + (y2 - y)**2)

                                h2 = math.sqrt((x2 - goal(0))**2 + (y2 - goal(1))**2)

                                f2 = g2 + h2

                                g2 = g + delta(i)(2)             
                                h2 = math.sqrt((x2 - goal(0))**2 + (y2 - goal(1))**2)

                                f2 = g2 + h2

                            #we add them to our open list
                            #print('append list item')
                            #Then we check them to never expand again
                            closed(x2)(y2) = 1
                            action(x2)(y2) = i

    for i in range(len(expand)):
    policy=((' ' for row in range(len(grid(0)))) for col in range(len(grid)))
    visx = (y)
    visy = (-x)
    while x !=init(0) or y !=init(1):
        policy(x2)(y2)= delta_name(action(x)(y))
    for i in range(len(policy)):

    plt.plot(visx,visy, "-r")



Here is my issue:


Time Complexity – Which complexity does this algorithm have for the number of ascending paths?

I have a solution to the following problem:

There is a staircase with n steps, which can be climbed from 1 to m by the stairs
Time (1 <= m <= n), return all the ways where you can climb the stairs.

For example, for n = 3, m = 2, the possible ascending paths are: (2,1), (1,2), (1,1,1)

// outputs all the ways to react total using steps from 1 to max;
// returns the count of iterations
function permut(total, max, out) {
  // start with an initial track
  let iter = ({ val: (), sum: 0 });
  let count = 0;

  // take the next track until there are none
  for (let i of iter) {
    for (let s = 1; s <= max; s++) {
      let val = (...i.val, s);
      let sum = i.sum + s;


      if (sum === total) {
        // we've reached the top;
        // do not expand current track further

      // add an unfinished track and start over
      iter.push({ val, sum });

  return count;

Codesandbox: https://codesandbox.io/s/busy-cdn-7idu9

However, I can not figure out the temporal complexity relative to m and n. For m = 1, the number of iterations is n, for m = n it is n ^ 2 - 1.

Is there a canonical solution to this problem?

Optimization – Optimization of the scheduling algorithm

I'm looking for an algorithm that can help me solve an appointment / time window optimization problem.

Starting from a series of appointments with the following parameters:

  1. Dollar amount
  2. start time
  3. duration
  4. providers

In most cases, the provider can be replaced in the same time window for another appointment. In some cases, a provider can not be changed. These dates are marked as such.

I am looking for an algorithm that adjusts the sum of the dollar amount for the dates of each provider.

My original naive approach is to perform a series of cycles by randomly selecting an appointment and replacing the provider who calculates the grand totals.

Are there any pointers in the right direction for the selection of algorithms or similarities to other problems that I can investigate?

Java – Would the combination of A * with a flock algorithm be too powerful?

This sounds like a use case for flow fields.

In this technique, you make a single pathfinder query from your player objects to the outside and mark each cell you encounter with the cell from which you reached them.

If all of your tiles / edges have the same traversal cost, you can do a simple breadth first search. Otherwise the Dijkstra algorithm works (like A * without destination / heuristic).

This creates a flow field: a table that maps each cell to the next step to the next player object.

Now your enemies can retrieve their current position in the flow field to find the next step on their shortest path to the next player object without having to do their own pathfinding query.

This scales better and better the more enemies are in your herd. It's more expensive for a single opponent than A * because it searches the entire map. However, as you add more enemies, they can become more and more involved in the cost of scouting by calculating shared path segments once and not over and over again. They also benefit from the fact that BFS / Dijkdtra are easier to evaluate than A * and, as a rule, cheaper for each cell studied.

Where exactly the break even point is reached, from single A *, which are cheaper, to A *, where the storage is cheaper, to flow fields, depends on your implementation and the size of your card. However, if you ever plan a large swarm of enemies in a confined space, a flow field is almost certainly cheaper than the iterated A *.

Algorithm for finding repeated patterns in a large string

For optimization purposes, I will try to parse a large list of executed program instructions to find parts of commands that will be executed over and over again. This problem is similar to finding repeated substrings in a string. In my case, I'm not looking for the longest substrings, but for smaller substrings, which are very common.

Assuming each command is represented by a letter, then a program might look like this xabca yabca xabca yabca, When we search for the longest repeated substrings, the best result is xabca yabca, A "better" result would be abcaeven though. While it's shorter, it's more common in the string. a Occurs even more often alone, but would be considered too short game. An algorithm should therefore be configurable by a minimum and maximum block length.

Things that I have tried so far:

  • I played with suffix trees to find the longest repeated substrings that occur at least k times. While this is easy to implement, it does not work well in my case because overlapping substrings are also found. The attempt to remove them was also not very successful. The approach mentioned in this post either gave wrong or incomplete results (or I misunderstood the approach) and does not seem to be customizable either. Suffix trees still seem to me the most promising approach. Maybe someone has an idea how to include the minimum / maximum chunk lengths here in the search?
  • Another attempt was to use the substring table created for the LZW compression algorithm. The problem with this approach is that it does not find repeated sections that occur early, and the further input is processed, the longer it takes to create a table entry (which makes sense for compression, but not in my use case).
  • My best solution so far is the brute-force approach. H. Creating a dictionary for each possible substring and counting how often it occurs in the input. However, this is slow for large inputs and has a huge memory drain.
  • Another idea was to look for individual commands that are most common and then examine the local environment of these commands for repeated patterns. However, I did not come up with a good algorithm here.

What other algorithms might be helpful in this scenario? What I am looking for is not necessarily the best match, but a good heuristic. My input data is quite large and can reach up to a length of about 100 MB. The piece sizes are usually in the range of 10 to 50.

Algorithm – How can I match my line of sight to the theta star? How could I fix my below problem?

I'm trying to implement my theta star algorithm, but first I have to implement the line of sight algorithm. I have implemented in my lineOFsight algorithm in Python, I do not know how accurate it is. But when I call this line of sight feature in my program, I get the following error:

    sight = lineOfsight(elevation1,drone_height,y1,x1,y2,x2)
NameError: name 'lineOfsight' is not defined

How could I fix this error? … and is it correct what I coded?

My Python code below for the line of sight algorithm:

from Thetastar import *
def lineOfsight(elevation1,drone_height,y1,x1,y2,x2):
    y_size = len(elevation1)
    x_size = len(elevation1(0))


    if dy < 0:

    if dx < 0:

    if dy >= dx:
        while y1 != y2:
            f = f + dx
            if f>=dy and 0 drone_height:

                    sight = 0
                    return sight
                x1 = x1 + sx
                f = f - dy
                if 0 drone_height:
                        sight = 0
                        return sight

                if 0h and E(y1+(sy-1)/2,x1-1) > drone_height:
                        return sight


        while x1 != x2:         
            if f>=dx and 0 drone_height:
                    return sight

            if 0 drone_height:
                    return sight

            if 1h and E(y1-1,x1+(sx-1)/2)> drone_height:
                    return sight
    sight = 1
    return sight