how to call a function to another function in julia? - function

I am writing a code in julia but I am unable to call a function from another function. Code is:
function add(x, y)
if x == 3 && y ==1
z =0
else x == 0 && y ==0
z =1
end
return z
end
function width(a, b, c)
add(x,y)
.....
end
The variables in add function will be used in width function but as I am new to julia, I am unable to call add in the other function. Kindly guide.
Edit:
I tried declaring with the z but it also didn't worked
struct z
a::Int
b::Int
end

There are two problems in your code that are not related to Julia per se. First problem in the add function: if x == 3 && y == 1 the output should be z = 0, else if x == 0 && y == 0, actually the if was missing, the output should be z = 1. Now what will be the output if, e.g., x = 1 && y == 1? The answer is nothing and z will be undefined.
To fix the add function, you should add a default branch for the if-else.
function add(x, y)
if x == 3 && y == 1
z = 0
elseif x == 0 && y == 0
z = 1
else
z = -1 # some default
end
return z
end
The same function could be written more concisely as:
function add(x, y)
x == 3 && y == 1 && return 0
x == 0 && y == 0 && return 1
return -1 # some default
end
which can even be written in a one-liner like this:
add(x, y) = x == 3 && y == 1 ? 0 : x == 0 && y == 0 ? 1 : -1 # some default
The second problem is with the width function. x and y are not defined inside the body of the width function. So, you can't call add(x, y). It should be z = add(a, b) where z should be used in subsequent calculations. Finally, check what the third argument c is for, otherwise, remove it.
function width(a, b, c)
z = add(a, b)
.....
end

Related

haskell TicTacToe game

I am trying to build a tic tac toe game in haskell and I am having trouble with a function haswon. The function should return True if for a given player p and the game board bs, he has already won the game, and False otherwise.
Here is the code:
Int -> [((Int,Int),Int)] -> Bool
haswon p [((a,d), x), ((b,e), y), ((c,f), z)] = (x == y && y == z && x == p) && ( ((a == b) && (b == c)) || ((d == e) && (e == f)) || ( (a == d) && (b == e) && (c == f) && (a /= b) && (b /= c)) || ( (a == f) && (c == d) && (b==e)&&(a/=b)&&(b/=c)) )
Could you please tell me how can I generalize this for an input list that is bigger than 3 elements?
For instance, the input could be : [((1,1),1), ((1,2),1), ((2,1),2), ((2,2),2), ((3,1),1), ((3,2),1), ((3,3),2)].
Thank you.
Here is the code:
Here's my take at it:
Let's define proper data types first:
data Player = Black | White deriving (Eq, Show)
data Position = Position Int Int deriving (Eq, Show)
data Move = Move { position :: Position, player :: Player } deriving (Eq, Show)
Now the actual function just counts the lines that qualify for winning
hasWon :: Player -> [Move] -> Bool
hasWon p ms = (length $ winningLines p ms) > 0
The winning lines generation is one big comprehension:
winningLines p ms = [(x,y,z) | x <- ms,
y <- ms,
z <- ms,
oneLine (position x) (position y) (position z),
samePlayer (player x) (player y) (player z),
x /= y,
y /= z,
x /= z
]
samePlayer px py pz = px == py && py == pz
oneLine (Position x1 y1) (Position x2 y2) (Position x3 y3) = sameRow || sameCol
where
sameRow = (y1 == y2 && y2 == y3)
sameCol = (x1 == x2 && x2 == x3)
And finally some testing:
moves = [
Move (Position 1 1) White,
Move (Position 2 1) White,
Move (Position 3 1) White
]
main :: IO ()
main = do
print $ hasWon White moves
print $ winningLines White moves
The solution is only using the basics, so you should be able to understand it quite easily and add your own fixes; it's still missing diagonals (easy to add), and it's counting all the lines 6 times (because it's taking all permutations into account; easy to fix with Ord instance for position and only taking a "sorted triple" into account).
Of course this is not the only way to do it; one notable alternative would be to put it into an array in-place, and then find the solution iteratively. I think the Prolog-esque declarative style just fits Haskell better, though.

What is = followed by == operation?

I've encountered this code and don't know what its performing :
yk = y == k;
Recreating :
>> a = 1
a = 1
>> b = 2
b = 2
>> c = 3
c = 3
>> a = b == c
a = 0
>>
I think it is a boolean operation. If y == k then yk = 1 else yk = 0 ?
In order to figure out what your statement means, you can refer to Octave's operator precedence. As you can see from that list, assignment (=) has the lowest precedence of any operator (including ==). As a result, the line that you have posted translates to
Perform the relational operation y == k
Assign the result to the variable yk

Sequence function error?

I'm getting an error on line 3 "TypeError: 'int' object is not iterable," and its been bothering me. Any advice/fixes appreciated.
Example test: collatz_counts(4) → 3 # 4 -> 2 -> 1 (3 steps)
Code I have:
def collatz_counts(x):
num = 0
for i in (x):
if i == 1:
num += 1
return num
elif i % 2 == 0:
num(i) / 2
num += 1
num.append(i)
else:
num = (i*2) + 3
num += 1
num.append(i)
return num
This can be solved recursively:
def collatz_length(n):
if n == 1:
return 1
return 1 + collatz_length(3*n+1 if n%2 else n//2)
Which lends itself to be memoized if you are going to be calling for a range of numbers, e.g. in Py3
import functools as ft
#ft.lru_cache(maxsize=None)
def collatz_length(n):
if n == 1:
return 1
return 1 + collatz_length(3*n+1 if n%2 else n//2)
Which will run through the first million collatz sequences in about 2.31s vs about 28.6s for the iterative solution.
Use a while loop. Just modify x in place until you get to 1 and keep track of the number of steps each time you run a cycle.
def collatz_counts(x):
steps = 0
while x != 1:
if x % 2:
x = x * 3 + 1
else:
x = x // 2
steps += 1
return steps

Julia (Julia-lang) conditional in function chaining

I'm trying to sum all numbers from 1 to 1000 that are either divisible by 3 or 5.
The first attempt is straight forward:
ans1 = 0
for x in 3:999
ans1 += x % 3 == 0 || x % 5 == 0 ? x : 0
end
When I try the same approach using function chaining, it fails to return the answer I expect, it instead returns 0.
ans2 = [3:999] |> x -> x % 3 == 0 || x % 5 == 0 ? x : 0 |> sum
I believe the problem is the center function, since the code below prints all values within the range of 3 to 999. So i know there is no problem with iteration.
[3:999] |> x -> println(x)
Could anyone please help me.
I discovered the reason was because I did not understand the type being parsed. Here is an example:
[3:999] |> println(typeof(x)) # Array{Int64,1}
Meaning the value being parsed is an array of integer64. So evaluating the following:
[1:999] % 3 == 0 # false
So my answer was to instead use the filter function, here is an example:
ans3 = sum(filter(x -> x % 3 == 0 || x % 5 == 0,[1:999]))
The final answer using function chaining is:
ans4 = [1:999] |> x -> filter(y -> y % 3 == 0 || y % 5 == 0,x) |> sum
Which evaluates to the expected answer.

How to perform a conditional assignment on each element of the vector

I have a function like this:
y=-2 with x<=0
y=-2+3x^2 with 0=1
I need to compute this function on each element of the 1D matrix, without using a loop.
I thought it was possibile defining a function like this one:
function y= foo(x)
if x<=0
y=-2;
elseif x>=1
y=1;
else
y= -2+3*x.^2;
end
end
But this just produces a single result, how to operate on all elements? I know the . operator, but how to access the single element inside an if?
function b = helper(s)
if s<=0
b=-2;
elseif s>=1
b=1;
else
b= -2+3*s^2;
end
end
Then simply call
arrayfun(#helper, x)
to produce the behaviour you want of your function foo.
Another approach which doesn't need arrayfun() would be to multiply by the conditions:
y = -2*(x <= 0) + (-2+3*x.^2).*(x < 1).*(x > 0) + (x >= 1)
which you could also make a function. This will accept vector inputs for x e.g.
x = [1 4 0 -1 0.5];
y = -2*(x <= 0) + (-2+3*x.^2).*(x < 1).*(x > 0) + (x >= 1)
outputs
y =
1.0000 1.0000 -2.0000 -2.0000 -1.2500