I have a function that accepts a slurpy array and I want to constrain the contents of the array to Int between 0 and 255. So using raku's good documentation, I find I can write:
my &simp = -> *#a where { 0 <= $_.all <= 255 } { #a <<+>> 10 }
say &simp( 2, 3, 4);
# returns: [12 13 14]
As desired if I provide a list that is not in the range, then I get an error correctly, viz.
say &simp( 2,3,400 );
# Constraint type check failed in binding to parameter '#a'; expected anonymous constraint to be met but got Array ($[2, 3, 400])
Is it possible to name the constraint in some way, so that the error message can provide a better response?
If this were to be coded with multi subs, then a default sub with an error message would be provided. But for an inline pointy ??
You can try to generate the error in the where clause with the || operator.
my &simp = -> *#a where { (0 <= $_.all <= 255) || die 'not in Range' } { #a <<+>> 10 }
say &simp( 2, 3, 4);
# returns: [12 13 14]
say &simp( 2,3,400 );
#not in Range
What you want is a subset.
subset ByteSizedInt of Int where { 0 <= $_ <= 255 };
my &simp = -> ByteSizedInt *#a { #a <<+>> 10 };
Related
I've created a Set of array of int (to keep unique triplets) and after doing some steps need to return the list of triplets. Following snippet shows only the part that is trying to do this conversion and something is going wrong there. The resulted 2D Slice is getting triplets duplicated.
Please help me with following:
What is the problem with following code?
What should be the correct way to do this conversion?
Try Playground
func main() {
setOfTriplets := make(map[[3]int]struct{})
// Oversimplified steps here just to show some usage of the setOfTriplets.
t1, t2 := [3]int{1, 2, 3}, [3]int{4, 5, 6}
setOfTriplets[t1] = struct{}{}
setOfTriplets[t2] = struct{}{}
// Convert the triplets to 2D slice (because that's what I need in the bigger problem)
matrix := make([][]int, 0, len(setOfTriplets))
for t, _ := range setOfTriplets {
// array to slice
st := t[:]
// PROBLEM: Something unkown happening here.
matrix = append(matrix, st)
}
// PROBLEM:
// Expected Output: [[1 2 3] [4 5 6]]
// Actual Output: [[1 2 3] [1 2 3]] and sometimes [[4 5 6] [4 5 6]]
fmt.Println(matrix)
}
You are using the loop variable to create a slice. The loop variable is an array that is overwritten for each iteration. During the first iteration, if the tiplet is [1,2,3], this gets copied to t and a slice is created from this. Next iteration will overwrite t with [4,5,6], which will also overwrite the triplet you added to the list before.
To fix, create a copy of the array:
for t, _ := range setOfTriplets {
t:=t // Copy the array
// array to slice
st := t[:]
matrix = append(matrix, st)
}
I'm trying to improve my recursion skill(reading a written recursion function) by looking at examples. However, I can easily get the logic of recursions without local variables. In below example, I can't understand how the total variables work. How should I think a recursive function to read and write by using local variables? I'm thinking it like stack go-hit-back. By the way, I wrote the example without variables. I tried to write just countThrees(n / 10); instead of total = total + countThrees(n / 10); but it doesn't work.
with total variable:
int countThrees(int n) {
if (n == 0) { return 0; }
int lastDigit = n % 10;
int total = 0;
total = total + countThrees(n / 10);
if (lastDigit == 3) {
total = total + 1;
}
return total;
}
simplified version
int countThrees(int x)
{
if (x / 10 == 0) return 0;
if (x % 10 == 3)
return 1 + countThrees(x / 10);
return countThrees(x / 10);
}
In both case, you have to use a stack indeed, but when there are local variables, you need more space in the stack as you need to put every local variables inside. In all cases, the line number from where you jump in a new is also store.
So, in your second algorithme, if x = 13, the stack will store "line 4" in the first step, and "line 4; line 3" in the second one, in the third step you don't add anything to the stack because there is not new recursion call. At the end of this step, you read the stack (it's a First in, Last out stack) to know where you have to go and you remove "line 3" from the stack, and so.
In your first algorithme, the only difference is that you have to add the locale variable in the stack. So, at the end of the second step, it looks like "Total = 0, line 4; Total = 0, line 4".
I hope to be clear enough.
The first condition should read:
if (x == 0) return 0;
Otherwise the single 3 would yield 0.
And in functional style the entire code reduces to:
return x == 0 ? 0
: countThrees(x / 10) + (x % 10 == 3 ? 1 : 0);
On the local variables:
int countThrees(int n) {
if (n == 0) {
return 0;
}
// Let an alter ego do the other digits:
int total = countThrees(n / 10);
// Do this digit:
int lastDigit = n % 10;
if (lastDigit == 3) {
++total;
}
return total;
}
The original code was a bit undecided, when or what to do, like adding to total after having it initialized with 0.
By declaring the variable at the first usage, things become more clear.
For instance the absolute laziness: first letting the recursive instances calculate the total of the other digits, and only then doing the last digit oneself.
Using a variable lastDigit with only one usage is not wrong; it explains what is happening: you inspect the last digit.
Preincrement operator ++x; is x += 1; is x = x + 1;.
One could have done it (recursive call and own work) the other way around, so it probably says something about the writer's psychological preferences
The stack usage: yes total before the recursive call is an extra variable on the stack. Irrelevant for numbers. Also a smart compiler could see that total is a result.
On the usage of variables: they can be stateful, and hence are useful for turning recursion into iteration. For that tail recursion is easiest: the recursion happening last.
int countThrees(int n) {
int total = 0;
while (n != 0) {
int digit = n % 10;
if (digit == 3) {
++total;
}
n /= 10; // Divide by 10
}
return total;
}
My teacher just asked this question in the exam and I have no idea where to go on.
More details, the prototype of function is given as:
stack<int> Fibonacci_sequence(int n); //fibonacci numbers count up to n
The point is this function is recursive and it should return a stack data type. In my opinion I don't think this is a possible thing to do, but my teacher asked it!!
P.s: sorry, my language is C++
function stack<int> Fibonacci_sequence(int n) {
if n == 0 {
var a stack<int>;
a.push(0);
return a
} else if n == 1 {
var a stack<int>;
a.push(0);
a.push(1);
return a
} else
var temp int;
var seq int;
seq = Fibonacci_sequence(n-1);
temp = seq.pop;
seq.push(temp);
seq.push(temp);
//above: the top element of the stack must be duplicated because it
//is popped off in the process of calculating the sum.
seq.push(seq.pop()+Fibonacci_sequence(n-2).pop());
return seq
}
}
Above is a function that does just that, written in pseudo code because you did not specify a language. Hopefully this helps, it was fun to come up with! Thanks for the interesting question.
Since you didn't specify a language, and you specified it's an exam, here it is in Ruby. Ruby provides stack operations for arrays, but I'm only using push and pop operations in the following so you should be able to easily translate it to the language of your choice.
def fib(n) # no explicit return type, since everything's an object in Ruby
fail "negative argument not allowed" if n < 0
if n > 1
stack = fib(n - 1)
# grab the last two values...
f_n_1 = stack.pop
f_n_2 = stack.pop
# ...and use them to calculate the next.
# The value of this expression is the resulting stack, return it
return stack.push(f_n_2).push(f_n_1).push(f_n_1 + f_n_2)
elsif n == 1
return fib(0).push(1)
else
return [].push(0)
end
end
p fib(10) # => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
You may have to translate this to the language of your exam, but that's appropriate.
Here is my C++ code based on #Elliot pseudo, and it got errors, I specified these errors in the code. And I just figure out that pop() doesn't return a value, I'm gonna fix this.
stack<int> Fibonacci_sequence(int n)
{
if (n == 0) {
stack<int> a;
a.push(0);
return a;
}
else if (n == 1) {
stack<int> a;
a.push(0);
a.push(1);
return a;
}
else
{
int temp;
temp = Fibonacci_sequence(n - 1).pop(); //error C2440: '=': cannot convert from 'void' to 'int'
Fibonacci_sequence(n - 1).push(temp);
Fibonacci_sequence(n - 1).push(temp);
//above: the top element of the stack must be duplicated because it
//is popped off in the process of calculating the sum.
return Fibonacci_sequence(n - 1).push(Fibonacci_sequence(n - 1).pop() + Fibonacci_sequence(n - 2).pop());//error C2186: '+': illegal operand of type 'void'
}
}
New MiniZinc user here ... I'm having a problem understanding the syntax of the counting constraint:
predicate exactly(int: n, array[int] of var int: x, int: v)
"Requires exactly n variables in x to take the value v."
I want to make sure each column in my 10r x 30c array has at least one each of 1,2 and 3, with the remaining 7 rows equal to zero.
If i declare my array as
array[1..10,1..30] of var 0..3: s;
how can I use predicate exactly to populate it as I need? Thanks!
Well, the "exactly" constraint is not so useful here since you want at least one occurrence of 1, 2, and 3. It's better to use for example the count function:
include "globals.mzn";
array[1..10,1..30] of var 0..3: s;
solve satisfy;
constraint
forall(j in 1..30) (
forall(c in 1..3) (
count([s[i,j] | i in 1..10],c) >= 1
)
)
;
output [
if j = 1 then "\n" else " " endif ++
show(s[i,j])
| i in 1..10, j in 1..30
];
You don't have do to anything about 0 since the domain is 0..3 and all values that are not 1, 2, or 3 must be 0.
Another constraint is "at_least", see https://www.minizinc.org/2.0/doc-lib/doc-globals-counting.html .
If you don't have read the MiniZinc tutorial (https://www.minizinc.org/downloads/doc-latest/minizinc-tute.pdf), I strongly advice you to. The tutorial teaches you how to think Constraint Programming and - of course - MiniZinc.
I'm currently facing a strange problem for which I can't find the reason. I'm trying to create a multidimensional array in AutoIt and initialize it with values. Keeping the variant datatype in mind, it should be possible to create an array, that
consists of multiple elements (of course)
each element is another array containing exactly 2 elements (with different types)
these two elements are a single integer and another array with 4 integers
So basically I want to have an array of key/value pairs where the value is an array of numbers. I know that the "value" in this case is treated as a simple variable and not as an directly accessible array - that is what I want.
However, if I try
Global Const $x[3][2] = [ _
[1, [11,12,13,14] ], _
[2, [21,22,23,24] ], _
[3, [31,32,33,34] ] _
]
I just get
error: syntax error
[1, [
~~~~^
error: syntax error
[2, [
~~~~^
error: syntax error
[3, [
~~~~^
Either I'm missing something or the initializer doesn't realize that I don't want to have 3 dimensions but just 2 and handle the 4 item array as a single variant.
Can anybody suggest the preferred solution for that? Or should I forget this combined solution and simple go with an array of arrays with 5 elements each, like
Global Const $x[3][5] = [ _
[1, 11,12,13,14 ], _
[2, 21,22,23,24 ], _
[3, 31,32,33,34 ] _
]
and handle the difference in the code?
It is possible but you need to initialise the inner arrays separately.
Global $arr[3][2]
Global $a1[4] = [11,12,13,14] ;these are the inner arrays
Global $a2[4] = [21,22,23,24]
Global $a3[4] = [31,32,33,34]
$arr[0][0] = 1
$arr[0][1] = $a1 ;put the inner arrays into the outer array
$arr[1][0] = 2
$arr[1][1] = $a2
$arr[2][0] = 3
$arr[2][1] = $a3
Global $arrTemp
For $i = 0 to UBound($arr)-1
$arrTemp = $arr[$i][1]
For $j = 0 To UBound($arrTemp)-1
ConsoleWrite($arr[$i][0] & ': ' & $arrTemp[$j] & #CRLF)
Next
Next
This will output:
1: 11
1: 12
1: 13
1: 14
2: 21
2: 22
2: 23
2: 24
3: 31
3: 32
3: 33
3: 34
I don't think that is possible. You can got for this:
#region ;************ Includes ************
#include <Array.au3>
#endregion ;************ Includes ************
Global $a[4] = [11, 12, 13, 14]
Global Const $x[3][2] = [ _
[1, $a], _
[2, "21,22,23,24"], _
[3, "31,32,33,34"] _
]
_ArrayDisplay($x)
; Getting the values of [0][1]
For $i = 0 To UBound($a) - 1
ConsoleWrite($a[$i] & #CR)
Next
$re = StringSplit($x[1][1], ',', 2)
For $i = 0 To UBound($re) - 1
ConsoleWrite($re[$i] & #CR)
Next