I have a list like List = ["google","facebook","instagram"] and a string P1 = "https://www.google.co.in/webhp?pws=0&gl=us&gws_rd=cr".
Now I need to find which element of List is present inside the P1.
For this I implemented below recursive function, but it returns ok as final value, is there a way that when (in this case) google is found, then H is returned and terminate the other recursive calls in stack.
I want this function to return google.
traverse_list([],P1)-> ok;
traverse_list([H|T],P1) ->
Pos=string:str(P1,H),
if Pos > 1 ->
io:fwrite("Bool inside no match is ~p~n",[Pos]),
io:fwrite("inside bool nomathc, ~p~n",[H]),
H;
true->
io:fwrite("value found :: ~p~n",[Pos])
end,
traverse_list(T,P1).
It returns ok because the stop condition of your recursion loop does it:
traverse_list([],P1)-> ok;
For this you should use lists:filter/2 or a list comprehension:
List = ["google","facebook","instagram"],
P1 = "https://www.google.co.in/webhp?pws=0&gl=us&gws_rd=cr",
lists:filter(fun(X) -> string:str(P1,X) > 1 end,List),
% or
[X || X <- List, string:str(P1,X) > 1],
Related
I am trying to solve one of my Haskell question. The question asks me to that extracts a slice of a list of integers. Function should take a list and two indexes new list number contains between two indexes.
For this function;
First index should smaller than second index
First index cannot be negative number
we cannot use any built-in functions
example:
makeSlice [1,2,3,4,5] 2 3
[3,4]
makeSlice [1,2,3,4,5] (-1) 3
*** Exception: First index cannot be negative
I tried a few option but below function if I give positive number I am getting "First index cannot be negative" exception
makeSlice :: [a] -> Int -> Int -> [a]
makeSlice [] _ _ =[]
makeSlice (h:t) i k
|k < 0 = []
| i>k = error "First index cannot be greater than second index (i > k)"
| i< 0 = error "First index cannot be negative (i < 0)!"
| i>0 = makeSlice t (i - 1) (k - 1)
| otherwise = h:makeSlice t (i -1 ) (k - 1)
Can you help me to find where I am making wrong?
Add terminating condition for your recursion. On each call you subtract one from i and when it reaches below 0 you just throw error.
Probably the easiest approach to this uses the Prelude take and drop functions to process the list. Then you just need to do the bounds checking:
slice :: Int -> Int -> [a] -> Either String [a]
slice from to lst
| from < 0 = Left "First index cannot be negative (i < 0)!"
| to < from = Left "First index cannot be greater than second index (i > k)"
| otherwise = Right $ take (to - from) $ drop from $ lst
Here I'm using Either to report either success or failure. On the one hand that disagrees with the problem as stated; on the other, it gives callers a chance to handle the error without immediately terminating the program, which is more polite.
I am trying to build a list of 0's using list comprehension. But i also want to make an index 1 where i choose in the list. For example myList 5 2 = [0,1,0,0,0] where 5 is the number of elements and 2 is the index.
myList el index = [0 | n <- [1..el], if n == index then 1 else 0]
but this results in an error.
The smallest change that fixes that is
myList el index = [if n == index then 1 else 0 | n <- [1..el]]
Note that what's at the left of | is what generates the list elements. A list comprehension of the form [ 0 | ...] will only generate zeros, and the ... part only decides how long is the resulting list.
Further, in your code the compiler complains because at the right of | we allow only generators (e.g. n <- someList), conditions (e.g. x > 23), or new definitions (let y = ...). In your code the if ... is interpreted to be a condition, and for that it should evaluate to a boolean, but then 1 makes the result a number, triggering a type error.
Another solution could be
myList el index = replicate (index-1) 0 ++ [1] ++ replicate (el-index) 0
where replicate m 0 generates a list with m zeros, and ++ concatenates.
Finally, note that your index is 1-based. In many programming languages, that's unconventional, since 0-based indexing is more frequently used.
I'm trying to build a function which takes as input two list of type
(string*string) list
and returns one list of the same type. The first list is like a "lookup" list in which the second element is the element to search and the first element is the element to use for the substitution. The aim of the function is to find which element in the second list is equal to which element of the first list. In case of matching the element of the second list will be substitute with the correspondent element of the tuple in the first element. Below an example:
fun check([("0","s0"),("1","s0l0s1"),("2","s1"),("3","s1l1s0")],[("s0","s0l0s1"),("s0l0s1","s1"),("s1","s1l1s0"),("s1l1s0","s0")]);
With these inputs the function should return:
val it = [("0","1"),("1","2"),("2","3"),("3","0")]
Since "s0" corresponds to "0", "s0l0s1" corresponds to "1", "s1" corresponds to "2" and "s1l1s0" corresponds to "3".
I've done two functions so far:
fun check1((l1 as (x1,y1))::nil,(l2 as (x2,y2))::nil) = if x2 = y1 then [(x1,y2)] else nil
|check1((l1 as (x1,y1))::rest1,(l2 as (x2,y2))::rest2) =
if x2 = y1 then (x1,y2)::check1(rest1,rest2)
else check1(rest1,l2::rest2)
fun check2((l1 as (x1,y1))::nil,(l2 as (x2,y2))::nil) = if y2 = y1 then [(x2,x1)] else nil
|check2((l1 as (x1,y1))::rest1,(l2 as (x2,y2))::rest2) =
if y2 = y1 then (x2,x1)::check2(rest1,rest2)
else check2(rest1,l2::rest2)
The first one checks the element of the first tuple of the second list and the second function checks the element of the second tuple. But they don't work properly. Someone can help me in understanding where is the mistake?
Thanks a lot!
You're making this way too complicated.
This first function looks up a string in the first list:
fun lookup ((a,b)::xs) v = if v = b then a else lookup xs v
| lookup nil v = v;
And this one just runs recursively on both elements in the second list:
fun check (xs,((a,b)::ys)) = (lookup xs a, lookup xs b)::check(xs,ys)
| check (xs,nil) = nil;
I am working on some of the exercism.io exercises. The current one I am working on is for Scala DNA exercise. Here is my code and the errors that I am receiving:
For reference, DNA is instantiated with a strand String. This DNA can call count (which counts the strand for the single nucleotide passed) and nucletideCounts which counts all of the respective occurrences of each nucleotide in the strand and returns a Map[Char,Int].
class DNA(strand:String) {
def count(nucleotide:Char): Int = {
strand.count(_ == nucleotide)
}
def nucleotideCounts = (
for {
n <- strand
c <- count(n)
} yield (n, c)
).toMap
}
The errors I am receiving are:
Error:(10, 17) value map is not a member of Int
c <- count(n)
^
Error:(12, 5) Cannot prove that Char <:< (T, U). ).toMap
^
Error:(12, 5) not enough arguments for method toMap: (implicit ev:
<:<[Char,(T, U)])scala.collection.immutable.Map[T,U]. Unspecified
value parameter ev. ).toMap
^
I am quite new to Scala, so any enlightenment on why these errors are occurring and suggestions to fixing them would be greatly appreciated.
for comprehensions work over Traversable's that have flatMap and map methods defined, as the error message is pointing out.
In your case count returns with a simple integer so no need to "iterate" over it, just simply add it to your result set.
for {
n <- strand
} yield (n, count(n))
On a side note this solution is not too optimal as in the case of a strand AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA count is going to be called many times. I would recommend calling toSet so you get the distinct Chars only:
for {
n <- strand.toSet
} yield (n, count(n))
In line with Akos's approach, consider a parallel traversal of a given strand (String),
strand.distinct.par.map( n => n -> count(n) )
Here we use distinct to gather unique items and construct each Map association in map.
A pipeline solution would look like:
def nucleotideCounts() = strand.groupBy(identity).mapValues(_.length)
Another approach is
Map() ++ {for (n <- strand; c = count(n)) yield n->c}
Not sure why it's different than {...}.toMap() but it gets the job done!
Another way to go is
Map() ++ {for (n <- strand; c <- Seq(count(n))) yield n->c}
I have a string[] list and I wish to group the 5th element in the string array of all the list..
I found two different ways in doing this
let rec Publication x y (z:string [] list) =
if x < z.Length then
let muro = [z.[x].[y]]
let rest = Publication (x+1) y z
List.append muro rest
else []
where z is the string[] list and y is the element that I wish to list.
and
let Publication x (z:string [] list) = [for i in 0 .. (z.Length-1) -> z.[i].[x]]
In the first case, I get a stack overflow error when working with a large set of data and the second one takes to long. Can anyone help me find a third and more eficient way? thanks!
Your second version seems sensible on the surface, but I wonder if the problem is not the indexed access to z, as the list is iterated from the head for each z.[i] call. What I would try is plain and simple:
let publication idx (lst: string [] list) =
lst |> List.map (fun arr -> arr.[idx])
You have a list of arrays and an index, you go through the list and get element by the index from each array.