Finding Substring of Number with certain property - string

I am given a string consisting of only numbers from 0 to 9. I want to calculate how many sub strings of them are power of 2.
For example for substring 2560616 substring 256 and 16 are power of 2. I need to calculate how many such substrings are there in any given substring.
Note that the substring is very large so brute force can't work. So I mainly want to address 2 issues
How to efficiently count all substrings that are power of 2
How to efficiently calculate whether a substring is power of 2
I think there might be a DP approach, but I am not sure about it.

Create a tree from the digits of the powers of 2 with the following algorithm:
Start with a root representing the empty character.
Get the next power of 2, get its digits in reverse order.
Select the root. Select the last digit of the current number.
Go to the child node of the selected node corresponding to the selected digit. If it does not exists yet, create it.
Select the previous digit of the current number. Repeat from (2.) until there are no more digits.
Mark the current node as a valid endpoint.
Repeat from (2.) until number of digits > 10^5
This tree might take a couple GBs in the memory.
Now you have your tree. To count the number of substrings that are power of 2, do the following:
Start from the end of the string.
Get the previous character.
Select the root of the tree.
Select the previous character (starting with the one selected in the outer (2.)).
Select the child node of the selected node corresponding to the selected digit.
If the selected child node is marked as valid endpoint, increment count by 1.
Repeat from (2.) until selected node is null or reached first character of the string.
Go back to character selected in outer (2.)
Select previous character. Repeat from (2.) until reached beginning of string.
The description of the algorithm is not "exam-ready", but i hope its understandable enough.

Related

Check if string contains consecutive repeated substring

I got an interview problem which asks to determine whether or not a given string contains substring repeated right after it. For example:
ATAYTAYUV contains TAY after TAY
AABCD contains A after A
ABCAB contains two AB, but they are not consecutive, so the answer is negative
My idea was to look at the first letter, find its second occurrence then check letter by letter if the letters after the first occurrence match the letters after the second occurrence. If they all do, the answer is positive. If not, once I get a mismatch, I can repeat the process but starting with the last letter I checked, since I would not be able to get a repeated sequence up to that point.
I am not sure if the approach is correct or if it is the mos efficient.
Assume that you are looking for a repeating pattern of length 3. If you write the string shifted right by three positions in front of itself (and trimmed), you can detect runs of 3 identical characters.
ATAYTAYUV
ATAYTA
Repeat this for all lengths up to N/2.

Counting a number of keywords in Excel within a range of specific keywords

I know how to count a series of keywords in Excel. I use this formula:
=SUMPRODUCT(--ISNUMBER(SEARCH($CE$2:$CE$43,(G2:AP2))))
However, what would be the Excel formula if I want to count the number of keywords that exist only within +/-3 words around "risk" in the selected rows?
Consider this sentence: "Political uncertainty generates economic risk which stagnates economic activities." If my keywords are political, uncertainty, stagnates, and economic, the total count of keywords within +/- 3 words around "risk" will be 4, i.e., uncertainty, stagnates, and economic. "economic" appears twice in the sentence. political will be excluded since it is out of range.
You could try:
Formula in E1:
=SUM(--ISNUMBER(MATCH(FILTERXML("<t><s>"&SUBSTITUTE("a a a "&A1," ","</s><s>")&"</s></t>","//s[following::s[4]='risk']/following::*[position()<8]")&"*",C1:C4,0)))
This would in order:
"<t><s>"&SUBSTITUTE("a a a "&A1," ","</s><s>")&"</s></t>" - Create a valid xml-string to process with xpath;
"//s[following::s[4]='risk']/following::*[position()<8]" - A valid xpath 1.0 expression to retrieve only upto seven nodes with risk in the middle. In more detail: //s[following::s[4]='risk'] will get the node where the following sibling on 4 indices to it's right will equal risk (case-sensitive), we then take all following siblings from that position with /following::* where we limit the returned nodes to a max of seven with [position()<8]. Now it would also make sense why we concatenate a a a with the string from A1 since risk could appear at the start of the string or less then three words in;
MATCH() - Will then check if any of the returned nodes start with any of the words in C1:C4 using a wildcard. This is to prevent possible punctuation to avoid matching;
SUM() and ISNUMBER() prepended with double unary will lastly make a summation of hits.
Note: The answer is not 3 but 4! Since 'economic' is to be counted twice.
You may try the following formula if you have Microsoft-365 with most recent release.
=LET(x,TOCOL(TEXTSPLIT(A1," ")),y,MATCH("risk",x,0),z,INDEX(x,SEQUENCE(y+2,1,y-3)),COUNT(XMATCH(D1:D4,z,0)))

Alteryx separate the first integer of a number and put it in a new column

I only have one column that has an 8-digit number. No dots, commas or any conjugation. Only integers.
I simply want to extract the first integer from the number and put it to a new column named "First integer". I want the rest of the integers, untouched, to either go to a new column as they are, or stay in the existing column but without the first integer
for example now I have: columnA: 23456789
I want First Integer:2 columnA: 3456789
I am pretty new to Alteryx so that might even be a ridiculous question to some :P
But any help is greatly appreciated :)
Suppose [i] is the relevant numeric field in your Alteryx workflow.
Then using a Formula tool, this expression will give the first digit:
[i]/POW(10,FLOOR(LOG10([i])))
And this will give the remaining digits:
MOD([i],POW(10,FLOOR(LOG10([i]))))
Explanation: working inside-out: Log10([i]) tells you how many powers of 10 you're working with, FLOOR just rounds that off, POW(10,...) multiplies it back out... so basically for an 8 digit number, this gives 10,000,000. Then you simply divide to get the first digit, or take the MOD (modulus) to get the remaining digits.
PS, your question mentions an 8-digit integer... if you are absolutely certain that your integers always have 8 digits (and the first digit is not a zero), then you can shortcut this: firstDigit=[i]/10000000 and remainingDigits=MOD([i],10000000).

Maximum number of consecutive 1's in a string

A string of length N (can be upto 10^5) is given which consists of only 0 and 1. We have to remove two substrings of length exactly K from the original string to maximize the number of consecutive 1's.
For example suppose the string is 1100110001and K=1.
So we can remove two substrings of length 1. The best possible option here is to remove the 0's at 3rd place and 4th place and get the output as 4 (as the new string will be 11110001)
If I try brute force it'll timeout for sure. I don't know if sliding window will work or not. Can anyone give me any hint on how to proceed? I am not demanding the full answer obviously, just some hints will work for me. Thanks in advance :)
This has a pretty straightforward dynamic programming solution.
For each index i, calculate:
The length of the sequence of 1s that immediately precedes it, if nothing has been removed;
The longest sequence of 1s that could immediately precede it, if exactly one substring is removed before it; and
The longest sequence of 1s that could immediately precede it, if exactly two substrings are removed before it.
For each index, these three values are easily calculated in constant time from the values for earlier indexes, so you can do this in a single pass in O(N) time.
For example, let BEST(i,r) be the best length immediately preceding position i after removing r substrings. If i >= K, then you can remove a substring ending at i and have BEST(i,r) = BEST(i-K,r-1) for r > 0. If string[i-1] = '1' then you could extend the sequence from the previous position and have BEST(i,r) = BEST(i-1,r)+1. Choose the best possibility for each i,r.
The largest value you find in step (3) is the answer.

Sharepoint calculated field get number only

I have a SharePoint list with a field, Field A, holding values such as "Text-11" or "DifferentText-150" and I want a new calculated field, Field B, that only shows the numeric part of Field A (i.e. "11", "150").
The number can be between 1 and 9999 so I canĀ“t take always the last 2 digits.
Does anyone have an idea how to realize that with the calculated field function of SharePoint?
You will need to use several different functions to accomplish this. Your primary function will be MID which will allow you to grab a part of the original text but then you will also need to use SEARCH for your starting point and LEN to get the correct number of characters. Here are the steps for making your formula:
You will need the index of the first character in the number. This can be achieved by finding the first character after the dash ('-'). Remember that indexes in SharePoint calculated fields start at 1 and not 0.
SEARCH("-",[Title],1)
Next you need to get the length of the number part of your string. This can be achieved by getting the length of the whole string and subtracting the index of the dash ('-').
LEN([Title]) - SEARCH("-",[Title],1)
Finally you can get the number part of the string by using the MID function and passing in the index of the first character in the number (Part 1) and the length of the number part (Part 2).
MID([Title],SEARCH("-",[Title],1) + 1,LEN([Title]) - SEARCH("-",[Title],1))
Note: Title is just the name of the test column that I used.

Resources