I am very new in haskell-programming. I try to program a simple dice-game, but I don't know to do it in haskell.
suc :: (Int,Int,Int) -> Int -> (Int,Int,Int) -> Bool
suc (a₁,a₂,a₃) c (d₁,d₂,d₃)
I want to consider each difference dᵢ - aᵢ (but not if aᵢ > dᵢ) and return False if (d1-a1)+(d2-a2)+(d3-a3) are larger than c. (if aᵢ > dᵢ then I sum up 0 instead the difference)
I try something like this:
suc :: (Int,Int,Int) -> Int -> (Int,Int,Int) -> Bool
suc (a1, a2, a3) c (d1, d2, d3) = ?????
where diff1 = if (d1 > a1) then d1-a1
diff2 = if (d2 > a2) then d2-a2
diff3 = if (d3 > a3) then d3-a3
Because in Haskell, else is not a optional part of an if expression, so you need to define diff1 as diff1 = if d1 > a1 then d1 - a1 else 0. Other two are similar.
Notes that > returns a Bool value, so you could just sum these three differences up and compare it with c, and use it as your condition.
There are several ways to define this function:
suc1 (a1, a2, a3) c (d1, d2, d3) = diff1 + diff2 + diff3 <= c
where diff1 = if d1 > a1 then d1 - a1 else 0
diff2 = if d2 > a2 then d2 - a2 else 0
diff3 = if d3 > a3 then d3 - a3 else 0
suc2 (a1, a2, a3) c (d1, d2, d3) = sum diffs <= c
where diff1 = max (d1-a1) 0
diff2 = max (d2-a2) 0
diff3 = max (d3-a3) 0
diffs = [diff1, diff2, diff3]
suc3 (a1, a2, a3) c (d1, d2, d3) = sum (zipWith diff as ds) <= c
where diff a d = max (d-a) 0
as = [a1, a2, a3]
ds = [d1, d2, d3]
How about this?
suc :: (Int,Int,Int) -> Int -> (Int,Int,Int) -> Bool
suc (a1, a2, a3) c (d1, d2, d3) =
((if a1> d1 then 0 else d1-a1) + (if a2> d2 then 0 else d2-a2) + (if a3>d3 then 0 else d3-a3) > c )
Or alternatively
suc :: (Int,Int,Int) -> Int -> (Int,Int,Int) -> Bool
suc (a1, a2, a3) c (d1, d2, d3) =
max 0 (d1-a1) + max 0 (d2-a2) + max 0 (d3-a3) > c
Related
Let's say I have a table with Columns A, B, C, D, E and F.
How would I query for entries where (A, B, C, D, E, F) = (1, 2, 3, 4, 5, 6) but only a subset of columns need to match? For example at least 3 out of the 6 columns have to match.
The only solution I can think of is to go through all combinations where (A, B, C) = (1, 2 ,3) or (A, B, D) = (1, 2, 4) or...
But in this example that would already be 20 where clauses, if my math is correct. Is there a better solution, that also works with more columns? Or is my only option to programmatically create a huge, non human-readable query string with hundreds of where clauses?
In MySql boolean expressions are evaluated as 1 for true or 0 for false, so you can add them in the WHERE clause:
WHERE (A = 1) + (B = 2) + (C = 3) + (D = 4) + (E = 5) + (F = 6) >= 3
Just in case any of the 6 columns is nullable, use the NULL-safe equal to operator <=> instead of =:
You can use a score system and then get the rows sorted by score. For example:
select *
from (
select t.*,
case when a = 1 then 1 else 0 end +
case when b = 2 then 1 else 0 end +
case when c = 3 then 1 else 0 end +
case when d = 4 then 1 else 0 end +
case when e = 5 then 1 else 0 end +
case when f = 6 then 1 else 0 end as score
from t
) x
where score >= 3
order by score desc
Of course, this query won't be efficient in terms of execution time, but should work well for small subsets of data.
SELECT
CASE
WHEN (A = B) AND (B = C) THEN 'Equilateral'
WHEN (A = B) OR (B = C) OR (A = C) THEN 'Isosceles'
WHEN ((A+B) < C) OR ((A+C) < B) OR ((C+B) < A) THEN 'Not A Triangle'
ELSE 'Scalene'
END
FROM TRIANGLES;
i am checking the type of triangle if length of the sides are given as A, B, C in the table TRIANGLES.
I think you SQL should be like this.
You should check Not A Triangle condition first, and you should change < operator to <= as well. And I suggest you should select A, B, C as well to make it more readable.
SELECT A, B, C,
CASE
WHEN ((A+B) <= C) OR ((A+C) <= B) OR ((C+B) <= A) THEN 'Not A Triangle'
WHEN (A = B) AND (B = C) THEN 'Equilateral'
WHEN (A = B) OR (B = C) OR (A = C) THEN 'Isosceles'
ELSE 'Scalene'
END
FROM TRIANGLES;
I have the following Haskell code, a function that checks how many digits are the same in a number and based on how many of them were the same takes a value. I keep getting the error:
Instances of (Ord (Int -> Int -> Int), Num (Int -> Int -> Int)) required for definition of digits
digits :: Int->Int->Int
digits x y
|(equal < 2) = 0
|(equal == 2) = 1
|(equal == 3) = 5
|(equal == 4) = 20
|(equal == 5) = 300
|(equal == 6) = 8000
|(equal == 7) = 10000
|otherwise = 100000
where
equal :: Int -> Int -> Int
equal 0 0 = 0
equal a b
|(a `mod` 10 == b `mod` 10) = 1 + equal (a `div` 10) (b `div` 10)
|otherwise = 1 + equal (a `div` 10) (b `div` 10)
What am I doing wrong? Also what does the error mean exactly?
EDIT: Did it like this and it works like a charm!
digits :: Int->Int->Int
digits x y
|(c < 2) = 0
|(c == 2) = 1
|(c == 3) = 5
|(c == 4) = 20
|(c == 5) = 300
|(c == 6) = 8000
|(c == 7) = 10000
|otherwise = 100000
where c = equal x y
where
equal :: Int -> Int -> Int
equal 0 0 = 0
equal a b
|(a `mod` 10 == b `mod` 10) = 1 + equal (a `div` 10) (b `div` 10)
|otherwise = 0 + equal (a `div` 10) (b `div` 10)
I am trying to write a formula in Excel VBA to calculate: RR = ((A / (A + B)) / (C / (C + D)))
When any of the four arguments (A, B, C, D) are 0, I want to change their value to 0.5 in the calculation.
Is there an easy way of doing this? I believe my formatting is wrong or I'm going about it the wrong way. Any helpful tips would be greatly appreciated.
I've tried:
Function RR(A, B, C, D) As Double
If A = 0 And B = 0 Then
A = 0.5
B = 0.5
RR = ((A / (A + B)) / (C / (C + D)))
ElseIf A = 0 Then
A = 0.5
RR = ((A / (A + B)) / (C / (C + D)))
ElseIf B = 0 Then
B = 0.5
RR = ((A / (A + B)) / (C / (C + D)))
ElseIf C = 0 Then
C = 0.5
RR = ((A / (A + B)) / (C / (C + D)))
ElseIf D = 0 Then
D = 0.5
RR = ((A / (A + B)) / (C / (C + D)))
ElseIf A = 0 And D = 0 Then
A = 0.5 And D = 0.5
RR = ((A / (A + B)) / (C / (C + D)))
Else: RR = ((A / (A + B)) / (C / (C + D)))
End If
End Function
Try this one:
Function RR(A, B, C, D) As Double
If A = 0 Then A = 0.5
If B = 0 Then B = 0.5
If C = 0 Then C = 0.5
If D = 0 Then D = 0.5
RR = ((A / (A + B)) / (C / (C + D)))
End Function
ellpow(E, P, m) will always throw an exception:
*** ellpow: impossible inverse modulo: Mod(x, y).
*** Break loop: type 'break' to go back to GP
where x and y are integers.
I want to trap the value x, without finishing the program in order to use it
later.
The snippet of the code is:
trap(invmoder,
x,
ellpow(E, P, m)
), n);
The whole program is:
ellcurv(n) = {
local(B, a1, a2, a3, a4, a6, b, E, P, m, x);
B = 20;
a4 = Mod(random(n), n);
b = 4*a4^3 + 27;
b = 1/b;
a1 = a2 = a3 = Mod(0, n);
a6 = Mod(1, n);
E = ellinit([a1, a2, a3, a4, a6]);
P = [0,1];
ellisoncurve(E, P);
m = 1;
for(i = 1, B,
m = lcm(m, i));
print(m);
x = gcd(
trap(,
ellpow(E, P, m),
ellpow(E, P, m)
), n);
}