SML recursive programming with String.substring - recursion

I am trying to write a program that takes two strings s1 and s2 as arguments. The function should check whether s2 contains s1 and if it does, the program should write the position in s2 at which the first letter of s1 occurs.
I want to check: String.substring(s2, size s2 - size s1, size s1) = s1.
And I then need to do a recursion on (size s2 - 1) so that s2 gets smaller by one after each comparison and thereby "move the s1" comparison of s2 one letter to the left.
I have no problems with recursions like:
fun recurison 0 = 0
| recurison n = n + (n - 1)
But when i shall interact with other functions or String.substring it feels messy. How should I think when I'm trying to write some recursive stuff? Can you give me a hint on the problem? I love to come up with the solutions myself but need help to point out the right road.

First, there is already the function String.isSubstring : string -> string -> bool which does what you want. But since you are interested in implementing such a function yourself recursively you just have to think about the following:
What is the base-case (i.e., when does the recursion end)?
What is the step-case (i.e., how to get a solution from a smaller solution)?
Since in your description you started to check for substrings from the right and then move to the left, the base-case is when you arrive at the leftmost position (i.e., 0). As for the step-case, after you checked position i you have to check position i - 1.
First you might start with a function that handles the case of checking position i.
fun substringat s1 s2 i =
if size s1 + i > size s2 then false
else String.substring (s2, i, size s1) = s1;
Then the skeleton for the recursion
fun substringfrom s1 s2 i =
if i < 0 then ~1
else if substringat s1 s2 i then i
else substringfrom s1 s2 (i - 1);
Finally we initialize everything appropriately
fun substring s1 s2 = substringfrom s1 s2 (size s2 - 1);
To avoid some unnecessary checks we could combine all this to
fun substring s1 s2 =
let
val l1 = size s1;
val l2 = size s2;
fun substringat s1 s2 i =
if l1 + i > l2 then false
else String.substring (s2, i, l1) = s1;
fun substringfrom s1 s2 i =
if i < 0 then ~1
else if substringat s1 s2 i then i
else substringfrom s1 s2 (i - 1);
in
substringfrom s1 s2 (l2 - 1)
end

Related

Can I use Instantaneous screw with Finite screw?

I'm trying to calculate angular velocity of each axis by movement of end-effector,
If S1 and S2 is finite screw, and S2 had infinitesimal movement from S1.
Also, let S1_ be (-)array of S1 and instantaneous screw of S1 is St1
So If I triangle product S2 and S1_ (S2△S1_=St1), It becomes almost instantaneous screw of S1 (I believe)
What I want to calculate is, if St1 is instantaneous screw, than can I calculate the angular velocity of each axis by using inverse jacobian with [ (J^-1)*St1 = answer ]?
(jacobian is from S1, if S1=S1_6△S1_5△S1_4△S1_3△S1_2△S1_1, (the robot has 6 axis),
jacobian matrix 'J' = [Su1_1, Su1_2, Su1_3, Su1_4, Su1_5, Su1_6], Su is for 'unit twist')
When you look at the kinematics recursively from the base to the end effector you have
vi = vi-1 + si ui
where vi is the velocity screw of each link, vi-1 is the velocity screw of the previous link, si is the unit screw of the joint axis, and ui the joint speed.
So the end effector has a final velocity screw of
v6 = s1 u1 + s2 u2 + s3 u3 + s4 u4 + s5 u5 + s6 u6
and I think you are asking on how to find the vector of joint speeds u = (u1, u2, u3, u4, u5, u6)
So you compose the 6×6 jacobian matrix J, by combining the individual joint axis unit screws in columns
J = [ s1 s2 s3 s4 s5 s6]
and invert the kinematics
v6 = J * u ⇒ u = J-1 v6

How to add elements to a Map?

I have a node type like the following :
type position = float * float
type node = position
I wrote these modules to use nodes as keys in my Map :
module MyMap =
struct
type t = node
let compare n1 n2 =
if n1 = n2 then 1
else 0
end
module Dist = Map.Make(MyMap)
Then I created an empty Map :
let mapTest = Dist.empty;;
let mapTest = Dist.add (1.,1.) 1. mapTest;;
I get the length of the Map like this :
Dist.cardinal mapTest;;
- : int = 1
I try to add another element :
let mapTest = Dist.add (2.,2.) 2. mapTest;;
But then my Map is still of length 1 when I use Dist.cardinal mapTest
More surprising, when I run :
Dist.find (1.,1.) mapTest;;
- : float = 2.
So now I'm left clueless about what's going on or what I've done wrong.
My goal is to be able to use the Map, add bindings etc.
Any ideas?
Thanks
The compare function does not behave as expected : it is expected to return 0 when n1 and n2 are equals, otherwise 1 if n1 is greater than n2, -1 if not.
The following code shall fix the issue :
module MyMap =
struct
type t = node
let compare (a1,b1) (a2,b2) =
if a1 > a2 then 1
else if a1 < a2 then -1
else if b1 > b2 then 1
else if b1 < b2 then -1
else 0
end
let compare n1 n2 =
if n1 = n2 then 1
else 0
It looks like you've misunderstood how compare is supposed to behave. Here's the description of compare from the documentation of OrderedType:
This is a two-argument function f such that f e1 e2 is zero if the keys e1 and e2 are equal, f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is strictly positive if e1 is greater than e2.
So the way you defined it, n1 would be considered greater than n2 if n1 = n2 and otherwise n1 would be considered equal to n2. This does not follow any of the rules you'd expect from a comparison function: a key isn't considered equal to itself and "n1 is greater than n2" can (and in fact always will) be true at the same time as "n2 is greater than n1". Consequently the map will not behave in a sensible way.
Assuming you want to consider one node equal to another if and only if they contain the same values in the same order, you can just define compare using Stdlib.compare.
That is not how you're supposed to write the compare function.
To quote the manual:
A total ordering function over the keys. This is a two-argument
function f such that f e1 e2 is zero if the keys e1 and e2 are equal,
f e1 e2 is strictly negative if e1 is smaller than e2, and f e1 e2 is
strictly positive if e1 is greater than e2. Example: a suitable
ordering function is the generic structural comparison function
compare.
So your compare function should be:
let compare n1 n2 =
if n1 < n2 then -1
else if n1 > n2 then 1
else 0
Note that on floating point numbers, comparison is weird. First, the rounding makes some numbers that seem equal to not be so. Second and even worse, the standard comparisons are not total (they all always return false on a NaN).
Thankfully, you can trust the standard compare function to solve the latter problem:
let compare (n1:t) n2 = Stdlib.compare n1 n2

convert an R script to IDL: Array manipulation

I am an R and IDL beginner. Im trying to convert an R script to IDL.
R can do array manipulation with t1 (array[100000]) but IDL cannot.
ERROR: Array subscript for CZ must have same size as source expression
s1= 100000.
c1 = array[200000]
n1 = s1*2+2
t1 = array[100000]
————————————————————————————————
(function)
f03, c1, s1, n1
cz = fltarr(n1,3)
cz[0:((2*s1)-1),0] = c1
cz[1:(2*s1),1] = c1
cz[2:((2*1)+1),2] = c1
cr = cz[0:(n1-1),1] - cz[0:(n1-1),2]
cl = cz[0:(n1-1),1] - cz[0:(n1-1),0]
p1 = where(cr GE 0.0 AND cl GE 0.0 AND (cz[0:(n1-1),1]) GE 1.4)
n2 = n_elements(p1)
ct = fltarr(n2+1,2)
ct[0:n2-1,0] = p1
ct[1:n2,1] = p1
c2 = ct[*,0] - ct[*,1]
ip = where(c2 GT 2.)
ch = p1[ip]
return, ch
————————————————————————————————
p1 = f03(c1,s1,n1) ;;;;; function works here
f1 = f03(t1,s1,n1) ;;;;; error on array size
I used MATRIX and AS.MATRIX in R (for f03). Does FLTARR cause this error?
Your lines:
cz = fltarr(n1, 3)
cz[0:((2 * s1) - 1), 0] = c1
make sense when cz has a first dimension of size 2000002 and c1 is 200000 elements — the sizes on the left and right of the = sign match, i.e., 0:199999 is 2000000 elements just like the size of c1.
But in the second call, c1 only has 100000 elements, but the left side is still asking for 2000000 elements.
Also, define a function like:
function f03, c1, s1, n1
; a bunch of code goes here
return, ch
end

Multiple != versus == operators

The following program works exactly as expected:
data = input("Input the length of three sides of a triangle: ").strip()
if data.count(',') != 2:
print("You did not enter the lengths of three sides: ")
a, b, c = data.split(', ')
def triangle_type(s1, s2, s3):
if s1 == s2 == s3:
return print("The values entered represent an equilateral triangle.")
elif s1 != s2 and s1 != s3 and s2 != s3:
return print("The values entered represent a scalene triangle.")
else:
if s1 == s2 or s1 == s3 or s2 == s3:
return print("The values entered represent an isosceles triangle.")
triangle_type(int(a), int(b), int(c))
However, if I change the second condition to the following:
elif s1 != s2 != s3:
it does NOT work as expected.
If I input 3, 6, 3 I get:
Input the length of three sides of a triangle: 3, 6, 3
The values entered represent a scalene triangle.
This is incorrect. This should clearly match condition #3 (isosceles).
It works correctly with the first version of the code.
I am confused on two things:
1) Why does the second version work improperly?
2) If the second version is invalid, then why does the first condition work
correctly?
Given the above behavior with the != operator, I would expect to have to treat a == b == c like a == b and a == c and b == c, but I don't have to.
When you chain comparisons in Python, it ands them together, and it only does as many comparisons as you have comparison operators. So
if s1 == s2 == s3:
is equivalent to
if s1 == s2 and s2 == s3:
That works because if both of those conditions are True, then s1 must also be equal to s3 (because they're both equal to s2).
However
if s1 != s2 != s3:
is equivalent to
if s1 != s2 and s2 != s3:
As you've discovered, for the values 3, 6, and 3, the above two conditions are True, but the third assumed condition (s1 != s3) is not True. This doesn't work as you expect because Python isn't making that third comparison.
The chained version is equivalent to s1 != s2 and s2 != s3; it does not require that s1 != s3, because inequality is not transitive.

Reversing an int in OCaml

I'm teaching myself OCaml, and the main resources I'm using for practice are some problem sets Cornell has made available from their 3110 class. One of the problems is to write a function to reverse an int (i.e: 1234 -> 4321, -1234 -> -4321, 2 -> 2, -10 -> -1 etc).
I have a working solution, but I'm concerned that it isn't exactly idiomatic OCaml:
let rev_int (i : int) : int =
let rec power cnt value =
if value / 10 = 0 then cnt
else power (10 * cnt) (value/10) in
let rec aux pow temp value =
if value <> 0 then aux (pow/10) (temp + (value mod 10 * pow)) (value / 10)
else temp in
aux (power 1 i) 0 i
It works properly in all cases as far as I can tell, but it just seems seriously "un-OCaml" to me, particularly because I'm running through the length of the int twice with two inner-functions. So I'm just wondering whether there's a more "OCaml" way to do this.
I would say, that the following is idiomatic enough.
(* [rev x] returns such value [y] that its decimal representation
is a reverse of decimal representation of [x], e.g.,
[rev 12345 = 54321] *)
let rev n =
let rec loop acc n =
if n = 0 then acc
else loop (acc * 10 + n mod 10) (n / 10) in
loop 0 n
But as Jeffrey said in a comment, your solution is quite idiomatic, although not the nicest one.
Btw, my own style, would be to write like this:
let rev n =
let rec loop acc = function
| 0 -> acc
| n -> loop (acc * 10 + n mod 10) (n / 10) in
loop 0 n
As I prefer pattern matching to if/then/else. But this is a matter of mine personal taste.
I can propose you some way of doing it:
let decompose_int i =
let r = i / 10 in
i - (r * 10) , r
This function allows me to decompose the integer as if I had a list.
For instance 1234 is decomposed into 4 and 123.
Then we reverse it.
let rec rev_int i = match decompose_int i with
| x , 0 -> 10 , x
| h , t ->
let (m,r) = rev_int t in
(10 * m, h * m + r)
The idea here is to return 10, 100, 1000... and so on to know where to place the last digit.
What I wanted to do here is to treat them as I would treat lists, decompose_int being a List.hd and List.tl equivalent.

Resources