Julia (Julia-lang) conditional in function chaining - function

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.

Related

Function that adds numbers of the list are divisible by 3,4 but not by 6

Write a function sumdv that holds a list of integers and adds up all numbers in the list that are divisible by 3 or 4 but not by 6. The functions sum, filter, convolutions and list generators are forbidden.
sumdv :: [Integer] -> [a] -> [Integer]
sumdv = add
sumdv [] = 0
sumdv (x:xs)
| mod 3 x == 0 || mod 4 x == 0 = x + sumdv (x:xs)
| mod 6 x == 0 = sumdv (x:xs)
Hey guys again, I´m a little bit confused about the right type, because the system shows only "Variable not in scope: sumdv :: [Integer] -> t". My thoughs are that at first I have a list with Integer, because of the fact that it must be "whole numbers" then the gave me a list of different elements that must be add together for me it is: [Integer] -> [a] -> a but it didnt work :( –
I would say that there are multiple mistakes:
type is wrong (based on the description you should accept collection of elements and return one)
seems like sumdv = add should be just removed
sumdv (x:xs) calls lead to infinite recursion (you are calling function passing the same input without modification)
mod arguments are in the wrong order
mod x 6 == 0 pattern guard should be before mod x 3 == 0 || mod x 4 == 0 cause only first matching guard is evaluated, and you will not filter out number divisible by 6 if mod x 3 == 0 is placed first
you are missing pattern guard for otherwise case (when number is not divisible by 3,4 or 6)
Taking in account all the notes above sample implementation can look like this:
sumdv [] = 0
sumdv (x:xs)
| mod x 6 == 0 = sumdv (xs)
| mod x 3 == 0 || mod x 4 == 0 = x + sumdv (xs)
| otherwise = sumdv (xs)

how to call a function to another function in julia?

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

OCaml : recursive function dealing with parity between list elements and an int

This function should take two arguments a list and an int. if an element of the list and the number “a” parity is equal then they’d have to be summed, else the two numbers should be subtracted.
The calculation should be done in this order :
At the beginning, the residual value r is the value of a,
Each element e of lst (taken in the order given by the list) affects the residual value: if e and r are of the same parity (both odd or both even) then the new r’ is equal to the sum of r + e, if not then it should be equal to the subtraction of r - e,
The last r is the result expected.
To put this into an example:
par [4;7;3;6] 5
should return -1, it would work as follows :
5 and 4 have a different parity so we subtract -> 5 - 4 = 1
1 and 7 are both odd, so we add them together -> 1 + 7 = 8
8 and 3 have a different parity -> 8 - 3 = 5
Finally, 5 and 6 have different parity -> 5 - 6 = -1
I have thought of something like this below :
let rec par lst a =
match lst with
| [] -> 0
| h::t -> if (h mod 2 == 0 && a mod 2 == 0) || (h mod 2 == 1 && a mod 2 == 1) then a + h
| h::t -> if (h mod 2 == 0 && a mod 2 == 1) || (h mod 2 == 1 && a mod 2 == 0) then a - h :: par t a ;;
EDIT1 : Here is the error I get from the compiler :
Line 4, characters 83-88: Error: This expression has type int but an
expression was expected of type unit because it is in the result of a
conditional with no else branch
The idea is to build this function using no more than the following predefined functions List.hd, List.tl et List.length.
What is disturbing in my proposition above and how to remediate it? Anyone can help me resolve this, please?
EDIT 2:
I was able to do what is needed with if...then... else syntax (not the best I know for OCaml) but I personally have more difficulties sometimes understanding the pattern matching. Anyhow here's what I got :
let rec par lst a = (* Sorry it might hurt some sensible eyes *)
if List.length lst = 0 then a
else
let r = if (List.hd lst + a) mod 2 == 0 then (a + (List.hd lst))
else (a - (List.hd lst)) in
par (List.tl lst) r ;;
val par : int list -> int -> int = <fun>
Suggestions and help to put it into a pattern-matching syntax are welcomed.
Your code doesn't compile. Did you try compiling it? Did you read the errors and warnings produced by the compiler? Could you please add them to your question?
A few comments about your code:
| h::t -> if ... then ... should be | h::t when ... -> ...;
(h mod 2 == 0 && a mod 2 == 0) || (h mod 2 == 1 && a mod 2 == 1) can be simplified to (h - a) mod 2 == 0;
The compiler likes to know that the matching was exhaustive; in particular, you don't need to repeat the test in the third line of the matching (the third line will only be read if the test was false in the second line);
You are missing the recursive call in the second line of the matching;
In the third line of the matching, you are returning a list rather than a number (the compiler should have explicitly told you about that type mismatch!! did you not read the compiler error message?);
In the first line of the matching, in case the list is empty, you return 0. Are you sure that 0 is the value you want to return, when you've reached the end of the list? What about the residual value that you have calculated?
Once you have fixed this version of your code as a recursive function, I recommend trying to write a code solving the same problem using List.fold_left, rather than List.hd and List.tl as you are suggesting.
When I first wrote my answer, I included a fixed version of your code, but I think I'd be doing you a disservice by handing out the solution rather than letting you figure it out.

Better way of finding combination for 3 boolean variables

I have 3 bool variables x,y,z. Now at any given moment I can have one out of 2^3=8 combinations as below.
e.g. x=true, y=false and z=false or
x=false, y=true and z=true and so on.
If I see from programming perspective there are 8 cases or may be 8 or greater if else statement to determine what is the combination at that moment.
At any given moment if I want to know what combination is present(given the values of x,y,z) How can I know without using if-else ladder, which makes code logic little bulky. Is there any better/simple logic/way to do it.
If you must handle 8 situations separately. You could encode the value of x, y, z in a variable and then do a switch case on that variable. Pseudo code below -
v = 0
if (x) { v += 4 }
if (y) { v += 2 }
if (z) { v += 1 }
switch (v)
{
case 0 : // all false
case 1 : // z is true
case 2 : // y is true
case 3 : // z and y are true
case 4 : // x is true
...
}
It might be worth using bitwise operators, rather than the numeric value to determine which boolean variables are on or off.
// Assign the bitwise value of each variable
X = 4
Y = 2
Z = 1
// Setting X and Z as true using the bitwise OR operator.
v = X | Z // v = 4 + 1 = 5
// Checking if any of the variables are true using the bitwise OR operator
if (v | X+Y+Z) // v = 4 + 2 + 1 = 7
// Checking if ALL of the variables are true using the bitwise AND operator
if (v & X+Y+Z)
// Checking if variable Y is true using the bitwise OR operator
if (v | Y)
// Checking if variable Y is false using the bitwise OR operator
if (v | Y == false)
// Checking if ONLY variable Y is true using the bitwise AND operator
if (v & Y)
// Checking if ONLY variable Y is false using the bitwise AND operator
if (v & Y == false)
This saves you from messing up the resulting number of a combination of values X, Y, Z. It is also more readable.

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