Is there a way to change range of cells in an array? - system-verilog

Given a matrix
logic [0:3] [0:3] matrix =
{4'b 1111,
4'b 1111,
4'b 1111,
4'b 1111
}
During run time, I get input (x,y) as index.
I would like to reach indexes (x,y+1), (x,y), (x,y-1) and change them.
for example, if I get (x,y)=(1,2), then I would get
{4'b 1111,
4'b 1011,
4'b 1011,
4'b 1011
}
I tried doing it in an always_ff block:
always_ff#(posedge clk or negedge resetN)
begin
matrix[y-1:y+1][x] <= 0;
end
but it says range must be final index.
Thanks.

The range you are asking for is called a slice or part-select in SystemVerilog. There are two problems with what you are trying to do.
You can only slice the last the last dimension of a select. In other words, select must represent a contiguous set of bits. You are trying to do the reverse.
Selects must have constant widths. Assuming you fixed the first issue, you would have to do something like [y-1 +:3]. See What is `+:` and `-:`?
But it might be better just using a for loop.
always_ff#(posedge clk)
for(yy=y-1;yy<y+2;y++) matrix[yy][x] <= 0;

Related

randcase weight behaviour unexpected

class test1;
function test_randcase();
for (int idx=0; idx < 10; idx++) begin
randcase
50: begin
$display("displaying from first cases");
end
50: begin
$display("displaying from second case");
end
endcase
end
endfunction
endclass
program main;
initial begin
test1 t1=new();
t1.test_randcase();
end
endprogram
Since each case is equally weighed here (50/100=0.5) so the expectation is that I would see each display 5 times in total. However, I see "first case" print 6 times and "second case" print 4 times. If this is the behavior of randcase, then how would I achieve my intention of equal weight? I used vcs compiler for this execution.
output:
displaying from second case
displaying from first cases
displaying from first cases
displaying from first cases
displaying from first cases
displaying from second case
displaying from first cases
displaying from second case
displaying from second case
displaying from first cases
Looking at this problem another way, suppose you had to choose a completely random 10-bit number where each bit has a 50% chance of being 0 or 1. There are 1024 possible numbers with a 1/1024 chance of having 10 1's and a 1/1024 chance of having 10 0's. And the odds of choosing a number with exactly 5 1's and 5 0's is around 25%. If you run more iterations, your randcase distribution would approach 0.50, but the odds of getting an exact 0.5 distribution diminish.
If your requirement is getting an exact distribution, you need to know upfront how many iterations you plan to have. There are several approaches you could take, one of which I can show you
class test1;
enum {FIRST, SECOND} itor[10];
function new;
itor[0:4] = '{5{FIRST}};
itor[5:9] = '{5{SECOND}};
endfunction
function void test_randcase();
itor.shuffle();
foreach(itor[i]) begin
case(itor[i])
FIRST: begin
$display("displaying from first cases");
end
SECOND: begin
$display("displaying from second case");
end
endcase
end
endfunction
endclass
module main;
test1 t1=new();
initial repeat(10)begin
$display("---");
t1.test_randcase();
end
endmodule
Other ways are shown in my paper from DVCon 2020, SystemVerilog Constraints: Appreciating What You Forgot in School to Get Better Results

Mean of values before and after a specific element

I have an array of 1 x 400, where all element values are above 1500. However, I have some elements that have values<50 which are wrong measures and I would like to have the mean of the elements before and after the wrong measured data points and replace it in the main array.
For instance, element number 17 is below 50 so I want to take the mean of elements 16 and 18 and replace element 17 with the new mean.
Can someone help me, please? many thanks in advance.
No language is specified in the question, but for Python you could work with List Comprehension:
# array with 400 values, some of which are incorrect
arr = [...]
arr = [arr[i] if arr[i] >= 50 else (arr[i-1]+arr[i+1])/2 for i in range(len(arr))]
That is, if arr[i] is less than 50, it'll be replaced by the average value of the element before and after it. There are two issues with this approach.
If i is the first or last element, then one of the two values will be undefined, and no mean can be obtained. This can be fixed by just using the value of the available neighbour, as specified below
If two values in a row are very low, the leftmost one will use the rightmost one to calculate its value, which will result in a very low value. This is a problem that may not occur for you in practice, but it is an inherent result of the way you wish to recalculate values, and you might want to keep it in mind.
Improved version, keeping in mind the edge cases:
# don't alter the first and last item, even if they're low
arr = [arr[i] if arr[i] >= 50 or i == 0 or i+1 == len(arr) else (arr[i-1]+arr[i+1])/2 for i in range(len(arr))]
# replace the first and last element if needed
if arr[0] < 50:
arr[0] = arr[1]
if arr[len(arr)-1] < 50:
arr[len(arr)-1] = arr[len(arr)-2]
I hope this answer was useful for you, even if you intend to use another language or framework than python.

Palindromic permutated substrings

I was asked this question in a HackerEarth test and I couldn't wrap my head around even forming the algorithm.
The question is -
Count the number of substrings of a string, such that any of their permutations is a palindrome.
So, for aab, the answer is 5 - a, a, b, aa and aab (which can be permuted to form aba).
I feel this is dynamic programming, but I can't find what kind of relations the subproblems might have.
Edit:
So I think the recursive relation might be
dp[i] = dp[i-1] + 1 if str[i] has already appeared before and
substring ending at i-1 has at most 2 characters with odd frequency
else dp[i] = dp[i-1]
No idea if this is right.
I can think of O(n^2) - traverse substrings of length > 1, from indexes (0, 1) up to (0, n-1), then from (1, n-1) down to (1, 3), then from (2, 3) up to (2, n-2), then from (3, n-2) down to (3, 5)...etc.
While traversing, maintain a map of current frequency for each character, as well as totals of the number of characters with odd counts and the number of characters with even counts. Update those on each iteration and add to the total count of palindromic permuted substrings if we are on a substring with (1) odd length and only one character with odd frequency, or (2) even length and no character with odd frequency.
(Add the string length for the count of single character palindromes.)
If I did not misunderstand your question, I tend to believe this is a math problem. Say the length of a string is n, then the answer should be n * (n+1) / 2, the sum of an infinite series. See https://en.wikipedia.org/wiki/1_%2B_2_%2B_3_%2B_4_%2B_%E2%8B%AF
For example, string abcde, we can get substrings
a, b, c, d, e,
ab, bc, cd, de,
abc, bcd, cde,
abcd, bcde,
abcde .
You may find the answer from the way I listed the substrings.
So here is my solution that may help you.
you can get a list of every possible substring of input by running a nested loop and for every substring you have to check if the substring can form a palindrome or not.
now how to check if a string/substring can form palindrome:
If a substring is having alphabet of odd number of occurance more than 1, them it can't form a palindrome.Here is the code:
bool stringCanbeFormAPalindrome(string s)
{
int oddValues, alphabet[26];
for(int i =0; i< s.length(); i++)
{
alphabet[s[i]-'a']++;
}
for(int i=0; i<26; i++)
{
if(alphabet[i]%2==1)
{
oddValues++;
if(oddValues>1) return FALSE;
}
}
return TRUE;
}
May that helps.
You can do it easily in O(N) time and O(N) space complexity
notice, the only thing that if the permutation of substring is palindrome or not is the parity of odd character in it so just create a mask of parity of every character, now for any valid substring there can be at most 1 bit different to our current mask, let's iterate on which bit is different, and adding the corresponding answer.
Here's a C++ code (assuming unordered_map is O(1) per query)
string s;
cin>>s;
int n=s.length();
int ans=0;
unordered_map<int,int>um;
um[0]=1;
int mask=0;
for(int i=0;i<n;++i){
mask^=1<<(s[i]-'a');
ans+=um[mask];
for(int j=27;j>=0;--j){
ans+=um[mask^(1<<j)];
}
um[mask]++;
}
cout<<ans;
take care of integer overflow.

Is real number natural?

I have 2 real numbers ( e.g. a , b). Is there any way to know whether is their division's result natural number?
I have tried
a mod b {to check if the result is 0}
but "mod" doesn't work for real numbers.
Also
a/b-trunc(a/b) {but sometimes the answer isn't 0}
I'm beginner, please, whether is there any other way, let me know.
Using Frac could be one idea as #Sertac mentions. But since binary floating point does not represent all real numbers, there could be cases where the fraction could end up close to zero (or one for that matter) as well.
Here is a simple routine that avoids testing for both close to one or zero:
function IsNaturalNumber( value : Double) : Boolean;
const
epsilon : Double = 1E-12;
begin
IsNaturalNumber := Abs(value - Round(value)) < epsilon;
end;
var
A,B : Double;
begin
A := 3.3;
B := 1.1;
WriteLn(IsNaturalNumber(A/B)); // Writes TRUE
end.
The function tests if the absolute difference between the value and the value rounded to nearest integer is smaller than a reasonable limit.
Note that there is no absolute certainty. That would require using a decimal floating point arithmetic library.
I will leave it up to the interested reader to implement the exclusion of integer numbers that is outside the range of the natural numbers, whether that is all negative numbers including zero or not.
If the values to test are larger than the upper range of the Round() function, use an equivalent floating point function. In Delphi that is Math.RoundTo(value,0).

Multiply a number by 2 in Brainfuck?

Given an arbitrarily long number, how can I output its double? I know how to multiply small numbers together as long as the result is <10, but what about larger integers like 32984335, and doubling something like that? I don't know the right way to handle something like this.
This is the algorithm you need to implement:
Start the current count with 0;
Multiply the current count by ten: this can be achieved by dupping 10 times, and then adding all dupes together;
Read a digit;
If it's null proceed to 8;
Convert it to an actual number: this can be achieved by subtracting 48;
Add it to the current count;
Proceed to 2;
Duplicate the current count;
Adding the dupes together;
Divide by ten using repeated subtraction; keep quotient and remainder;
Grab the remainder;
Make it a digit (add 48);
Print it;
Grab the quotient from 10;
If it's not zero, goto 10;
The end.
All these steps consists of basic brainfuck idioms, so it should be easy to implement.
Here's a start. It will multiply a byte of input, but I think you can build off it to make it work for any number. Basically, you take in a number, and store the number to multiply by (2) in the next pointer. You loop decrementing the first number, and then nest a loop decrementing the second number; in each iteration of the inner loop, you increment the pointer to the right of your second operand. This is your result.
, take input to ptr 0
[
- decrement first operand (input)
>++ number to multiply by (2) at ptr 1
[
>+ result in ptr 2
<- decrement second operand (2)
]
<
]
>> move to result
Here is my BF code: http://ideone.com/2Y9pk8
->>+>,+
[
-----------
[
-->++++++[-<------>]<
[->+<[->+<[->+<[->+<[>----<-<+>[->+<]]]]]]>
[-<++>]<+
>,+
[
-----------
[->+<]
]
>[-<+>]<
]
<[<]
>-[<++++++++[->++++++<]>.[-]]
>[<++++++++[->++++++<]>-.[-]>]
++++++++++.[-]
<+[-<+]
->>+>,+
]
It reads each number in each line until EOF, and multiply all numbers by two..
Here is the code for multiplying a number by 2.
,[>++<-]>.
Hope this helps.