I'm start to learn Standard ML with Programming languages course.
In the first homework, I try to write a function is_older that takes two dates and evaluates to true or false. It evaluates to true if the first argument is a date that comes before the second argument (If the two dates are the same, the result is false.).
So I write the following code:
fun is_older(first: int * int * int, second: int * int * int) =
if(#1 first = #1 second andalso #2 first = #2 second andalso #3 first = #3 second) then false
else if (#1 first < #1 second) then true
else if (#1 first = #1 second andalso #2 first < #2 second) then true
else if (#1 first = #1 second andalso #2 first = #2 second andalso #3 first < #3 second) then true
else false
The code is works fine, but it looks ugly.
How can I rewrite this code in functional style?
Two suggestions:
Use pattern matching to decompose tuples.
Use boolean operators (andalso, orelse, etc.) when if/else constructs return boolean.
A more readable version:
(* Compare two dates in the form of (year, month, day) *)
fun is_older((y1, m1, d1), (y2, m2, d2)) =
y1 < y2 orelse (y1 = y2 andalso m1 < m2)
orelse (y1 = y2 andalso m1 = m2 andalso d1 < d2)
In general when you have something on the form
if b then
true
else
false
you should exchange it with just b, as it is seen trivially to be the same.
The solution provided by pad would probably also have been my solution, as it is nice and short.
However when you end up having those nasty/nested if-then-else's, and you don't return something simple (e.g., true/false or a number), then you should consider using a case. Your function is not a prime candidate to use, however I hope the below still shows the idea (that you easily can make structure of those nested if's)
fun is_older((y1, m1, d1), (y2, m2, d2)) =
case (Int.compare(y1,y2), Int.compare(m1,m2), Int.compare(d1, d2)) of
(LESS , _ , _ ) => true
| (EQUAL, LESS , _ ) => true
| (EQUAL, EQUAL, LESS) => true
| _ => false
fun is_older((yr1 : int , mo1 : int , dt1 : int), (yr2 : int , mo2 : int , dt2 : int )) =
yr1 < yr2 orelse (yr1 = yr2 andalso mo1 < mo2)
orelse (yr1 = yr2 andalso mo1 = mo2 andalso dt1 < dt2)
Related
I'm trying to write a function of the type:
pascal : int * int -> int
where the pair of ints represent the row and column, respectively, of Pascal's triangle.
Here's my attempt:
fun pascal(i : int, j : int) : int =
if (i = 0 andalso j = 0) orelse i = j orelse i = 0
then 1
else
pascal(i - 1, j - 1) + pascal(i - 1, j);
It works for my base cases but gives me strange output otherwise. For instance:
pascal(4, 2) gives me 11 and pascal(4, 1) gives me 15
It's a bit strange because, as long as the if clause fails and the else gets evaluated, I do want to return the sum of the element one row above and the element one row above and one element to the left.
What am I doing wrong?
Consider pascal 1 0. If you're using zero-based indexing for the table then this should be equal to 1. But:
pascal 1 0 = pascal 0 -1 + pascal 0 0 = 2
You should put some guards to deal with negative indices and indices where j is greater than i.
Suppose I have the following array:
[6,3,3,5,6],
Is there an already implemented way to sort the array and that returns also the number of permutations that it had to make the algorithm to sort it?
For instance, I have to move 3 times to the right with the 6 so it can be ordered, which would give me parity -1.
The general problem would be to order an arbitrary array (all integers, with repeated indexes!), and to know the parity performed by the algorithm to order the array.
a=[6,3,3,5,6]
sortperm(a) - [ 1:size(a)[1] ]
Results in
3-element Array{Int64,1}:
1
1
1
-3
0
sortperm shows you where each n-th index should go into. We're using 1:size(a)[1] to compare the earlier index to its original indexation.
If your array is small, you can compute the determinant of the permutation matrix
function permutation_sign_1(p)
n = length(p)
A = zeros(n,n)
for i in 1:n
A[i,p[i]] = 1
end
det(A)
end
In general, you can decompose the permutation as a product of cycles,
count the number of even cycles, and return its parity.
function permutation_sign_2(p)
n = length(p)
not_seen = Set{Int}(1:n)
seen = Set{Int}()
cycles = Array{Int,1}[]
while ! isempty(not_seen)
cycle = Int[]
x = pop!( not_seen )
while ! in(x, seen)
push!( cycle, x )
push!( seen, x )
x = p[x]
pop!( not_seen, x, 0 )
end
push!( cycles, cycle )
end
cycle_lengths = map( length, cycles )
even_cycles = filter( i -> i % 2 == 0, cycle_lengths )
length( even_cycles ) % 2 == 0 ? 1 : -1
end
The parity of a permutation can also be obtained from the
number of inversions.
It can be computed by slightly modifying the merge sort algorithm.
Since it is also used to compute Kendall's tau (check less(corkendall)),
there is already an implementation.
using StatsBase
function permutation_sign_3(p)
x = copy(p)
number_of_inversions = StatsBase.swaps!(x)
number_of_inversions % 2 == 0 ? +1 : -1
end
On your example, those three functions give the same result:
x = [6,3,3,5,6]
p = sortperm(x)
permutation_sign_1( p )
permutation_sign_2( p )
permutation_sign_3( p ) # -1
I have the initial address and the output .. I need to find out what was used for XOR
129.94.5.93:46 XOR ????? == 10.165.7.201:14512
XOR has an interesting property that if you apply it to one of its operands and the result, you get the other operand back. In other words, if
r = a ^ b
then
b = r ^ a
where a and b are operands, and r is the result.
Hence, the data with which the original has been XOR-ed is
139.251.2.148:14494
Here is a short program in C# to produce this result from your data:
var a = new[] {129,94,5,93,46};
var b = new[] {10,165,7,201,14512};
var c = new int[a.Length];
for (int i = 0 ; i != a.Length ; i++) {
c[i] = a[i] ^ b[i];
Console.WriteLine("a={0} b={1} c={2} back={3}", a[i], b[i], c[i], c[i] ^ a[i]);
}
Here is a link to ideone showing this program in action.
XOR is a "reversible" function of sorts so:
A XOR B = C
A XOR C = B
therefore if you just XOR the 2 values that you do have you will be able to get the missing number
so
129.94.5.93:46 XOR X == 10.165.7.201:14512
x == 129.94.5.93:46 OXR 10.165.7.201:14512
The easiest way to figure this out is to look at the binary representation of each number (let's take the first number on each side):
129 = 10000001
XOR 139 = 10001011
======================
010 = 00001010
From this we can see that 129 XOR 139 == 10 is equivalent to 129 XOR 10 == 139.
I have the following code for Trial Divison Algorithm in Maple:
TrialDivision := proc( n :: integer )
if n <= 1 then
false
elif n = 2 then
true
elif type( n, 'even' ) then
false
else
for local i from 3 by 2 while i * i <= n do
if irem( n,i) = 0 then
return false
end if
end do;
true
end if
end proc:
which I got from http://rosettacode.org/wiki/Primality_by_trial_division#MATLAB. But when I try to run it, it is giving me the following error: Error, unexpected local declaration in procedure body.
Does anyone know what I am doing wrong?
Allowing local declarations throughout the procedure body is a somewhat recent addition to the Maple language.
You could change it to this, say.
TrialDivision := proc( n :: integer )
local i;
if n <= 1 then
false
elif n = 2 then
true
elif type( n, 'even' ) then
false
else
for i from 3 by 2 while i * i <= n do
if irem( n,i) = 0 then
return false
end if
end do;
true
end if
end proc:
Using a random library with these functions:
randomChance(p) Returns true with the probability indicated by p.
randomInteger(low, high) Returns a random integer in the range low to high, inclusive.
what is the easiest way to implement a "random selector" that takes consideration of percentage, 1/4 or 1/3 etc... I got a array with key/value pairing. For example "a" migth have the value 2 and "b" have the value 2. 1/2 chance for both.
The max value will be the size of the array, cause it only contains unique items. The randomChance() function ranges between 0.0 - 1.0 where 1 = 100%. If my array size is, say 4. What is the best way of "letting 4 be 1".
Lets say you have:
a = 2, b = 2, c = 1, d = 3
now make it:
a = 2, b = 4, c = 5, d = 8
Create a random number from 1 to MaxVal (value of the last key, 8 in this example). Select the first Key where Value >= RandomNum
EDIT
I made a small VB.Net to show the algorithm and how it works. The code is not meant to be: Good, elegant, performant or readable.
Module Module1
Private Class Value
Public vOrg, vRecalc, HitCount As Integer
Public Key As String
Public Sub New(s, v1, v2, c)
Key = s : vOrg = v1 : vRecalc = v2 : HitCount = c
End Sub
End Class
Sub Main()
' set initial values
Dim KVP() As Value = {New Value("A", 2, 0, 0),
New Value("B", 2, 0, 0),
New Value("C", 1, 0, 0),
New Value("D", 3, 0, 0)}
' recalc values
For i = 0 To KVP.Length - 1
If i = 0 Then KVP(0).vRecalc = KVP(0).vOrg Else KVP(i).vRecalc = KVP(i).vOrg + KVP(i - 1).vRecalc
Next
' do test
Dim r As New Random
Dim runs As Integer = 1000 * 1000, maxval As Integer = KVP(KVP.Length - 1).vRecalc
For i = 1 To runs
Dim RandVal = r.Next(1, maxval + 1)
Dim chosen As Integer = (From j In Enumerable.Range(0, KVP.Length) Where KVP(j).vRecalc >= RandVal Take 1 Select j)(0)
KVP(chosen).HitCount += 1
Next
' ouput results
For Each kv In KVP
Console.WriteLine("{0} was chosen with {1:F3} propability, expected was {2:F3}", kv.Key, kv.HitCount / CDbl(runs), kv.vOrg / CDbl(maxval))
Next
Console.ReadLine()
End Sub
End Module
An output sample:
A was chosen with 0.250 propability, expected was 0.250
B was chosen with 0.251 propability, expected was 0.250
C was chosen with 0.124 propability, expected was 0.125
D was chosen with 0.375 propability, expected was 0.375
just multiply the randomChance() outcome and the array length together. It'll give you the index in the range [0,array_length-1] which you can use to access the array
array_index = (unsigned int)(randomChance(p) * (array_length - 1));
maybe you mean "letting 3 to be 1" (not 4) in your example. The last index of an array of length 4 is 3.