Haskell program simple game - function

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

MySQL Query With Combinatorial Where Clause

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.

is there something wrong in my code? i am not receiving the desired output

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;

Haskell Instances required for definition

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)

Excel VBA UDF Formatting - Change argument values before calculation

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

Pari/GP Exceptions/break loops

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);
}