I have string "* * * *" and I want to get "*2*2*10001*" but my function can change only one side and I don't know how to increment Char.
I don't know how to make right conditions for this syntax, so sorry for my newbie questions.
rowIncrements shoud increase every single character by ' * ' possition. e.g. "00" -> "12"
The function receives two parameters.
#string which is a line/row
#list of integers which has loaded indexes of positions '*'
I would need all the numbers in the string around the '*' characters to be incremented by the number of occurrences next to them.
replaceNth :: Int -> a -> [a] -> [a]
replaceNth _ _ [] = []
replaceNth n newVal (x:xs)
| n == 0 = newVal:xs
| otherwise = x:replaceNth (n-1) newVal xs
rowIncrements :: String -> [Int] -> String
rowIncrements [] _ = []
rowIncrements x [] = x
rowIncrements row pos = changeInc pos where
changeInc [] = []
changeInc (x:xs)
| x == 0 && (x+1) `notElem` pos = rowIncrements (replaceNth (x+1) '1' row) xs
| (x+1) `notElem` pos = rowIncrements (replaceNth (x-1) '1' row) xs
| otherwise = -- only for testing
Now I will get "*1*1*00001*" instead of "*2*2*10001*" this is everything new for me, so if you can, please improve me.
I conditionaly change characters to ints and increment by 1.
replaceNth :: Int -> a -> [a] -> [a]
replaceNth _ _ [] = []
replaceNth n newVal (x:xs)
| n == 0 = newVal:xs
| otherwise = x:replaceNth (n-1) newVal xs
replaceNths :: [Int] -> [a] -> [a] -> [a]
replaceNths _ _ [] = []
replaceNths [x] [y] str = replaceNth x y str
replaceNths (x:xs) (y:ys) str = replaceNths xs ys (replaceNth x y str)
rowIncrements :: String -> [Int] -> String
rowIncrements [] _ = []
rowIncrements x [] = x
rowIncrements row pos = changeInc pos where
changeInc [] = []
changeInc (x:xs)
|(x == 0) && ((x+1) `notElem` pos) = rowIncrements (replaceNth (x + 1) (intToDigit(digitToInt(row !! (x + 1)) + 1)) row) xs
| (not(x == 0) && (x - 1) `notElem` pos ) && ((x + 1) `notElem` pos) = rowIncrements (replaceNths [x-1, x+1] [(intToDigit(digitToInt(row !! (x - 1)) + 1)), (intToDigit(digitToInt(row !! (x + 1)) + 1))] row) xs
| not(x == 0) && ((x + 1) `notElem` pos) = rowIncrements (replaceNth (x+1) (intToDigit(digitToInt(row !! (x + 1)) + 1)) row) xs
| not(x == 0) && ((x - 1) `notElem` pos) = rowIncrements (replaceNth (x-1) (intToDigit(digitToInt(row !! (x - 1)) + 1)) row) xs
| otherwise = changeInc xs -- This shoud not be called
Related
Write with OCaml Longest Common Sottosequence (Deep Search)
Consider a finite set S of strings and an integer K. Determine, if it exists, a string x of length greater than or equal to K subsequence of each string s∈S. The problem is solved by using an in-depth search.
I tried it with two strings without k, it works!
this bellow is my code:
(*trasfmorm string in list char*)
let explode s =
let rec exp i l =
if i < 0 then l
else exp (i - 1) (s.[i] :: l)
in
exp (String.length s - 1) []
(*print list of strings*)
let rec print_list_strings = function
| [] -> ()
| e::l ->
print_string e;
print_string "\n";
print_list_strings l
(*print list of char*)
let rec print_list_char = function
| [] -> print_string "\n"
| e::l ->
print_char e;
print_string " ";
print_list_char l
(*between the lists tell me which one is longer*)
let longest xs ys =
if List.length xs > List.length ys then xs
else ys
(*lcs deep*)
let rec lcs a b =
match a, b with
| [], _ | _, [] -> []
| x::xs, y::ys ->
if x = y then
x :: lcs xs ys
else
longest (lcs a ys) (lcs xs b)
(*
On input: "ABCBDAB", "ABCBDAB"
The LCS returned is "BDAB"
*)
let a = "ABCBDAB";;
let b = "ABCBDAB";;
let a = explode a;;
let b = explode b;;
print_list_char (lcs a b);;
But when I start to find the solution for s strings it seems impossible.
For the moment i write the code bellow:
(* function return n-elemt of a list *)
exception Nth
let rec nth n lista =
match (n, lista) with
| (_, []) -> raise Nth
| (0, t::_) -> t
| (n, t::c) -> nth (n-1) c;;
(* functione given input list of char output string *)
let rendi_stringa s =
String.of_seq (List.to_seq s)
(* delete first n-element of a string *)
let rec drop n = function
| [] -> []
| x::xs ->
if n <= 0 then x::xs
else drop (n-1) xs ;;
(*string into a char list*)
let explode s =
let rec exp i l =
if i < 0 then l
else exp (i - 1) (s.[i] :: l)
in
exp (String.length s - 1) []
(*read k-elemt and return a list*)
let rec leggi k =
if k=0 then []
else
let x = read_line() in
(x) :: leggi (k-1)
(*print element list*)
let rec print_list = function
| [] -> ()
| e::l ->
print_string e;
print_string "\n";
print_list l
(*funzione lista string esplosa--> lista di lista*)
let rec explode_list n lista =
if n = 0 then []
else
let x = List.hd lista in
[(explode x)] # explode_list (n-1) (List.tl lista)
(*n-esima raw e m-column of matrix*)
let pos tabla n m =
let lista = (List.nth tabla n) in
List.nth lista m;;
let subset tabella n =
let rec aux solution tot = function
| [] ->
if tot > 0 then raise NotFound
else solution
| x::rest ->
print_string x;
print_string "\n";
aux (x::solution) (tot-1) rest
in
aux [] n tabella
let subset tabella n =
let rec aux solution = function
| [] ->
if List.length solution < n then raise NotFound
else solution
| x::rest -> nuova_funzione (explode x) rest n
in
aux [] n tabella
let nuova_funzione lista_char lista_string n = function
| _, [] -> print_string "non posso piu fare niente, stringhe finite\n"
| [], _ -> print_string "ho finito confronto con la lista\n"
| [] , x::lt ->
if (lcs lista_char (explode x)) > n then
else
let longest xs ys =
if List.length xs > List.length ys then xs
else ys
(*lcs profonda*)
let rec lcs a b =
match a, b with
| [], _ | _, [] -> []
| x::xs, y::ys ->
if x = y then
x :: lcs xs ys
else
longest (lcs a ys) (lcs xs b)
(**)
(*let rec lcs stringhe num = function
| []
| List.length stringhe < num -> []
| *)
(*------------------------main--------------*)
print_string "how many strings?\n";;
let m = read_int();;
print_string "please write your strings\n";;
let lista = leggi m;;
print_string "strings wrote\n";;
print_list lista;;
explode (nth 0 c);;
let a = "ABCBDAB";;
let a = explode a;;
let b = "BDCABA";;
let b = explode b;;
let c = "BADACB";;
let c = explode c;;
My idea was to use Backtracking, but i'm stuck with logical idea, I have no idea to implement it even with pseudocode!
Any idea or advise?
let rec first_part n l =
if n = 0 then
[]
else
match l with
| [] -> []
| x :: xs -> x :: first_part n-1 xs
let rec second_part n l =
match l with
| [] -> []
| x :: xs ->
if n = 0 then l
else second_part n-1 xs
let rec split n l =
match n with
| 0-> ([], l)
| n -> (first_part n l , second_part n l)
This isn't a very well posed question. You don't show the details of the error or ask a specific question. You also didn't format the code in a readable way (I improved it for you).
Your problem is that
first_part n-1 xs
is parsed like this
(first_part n) - (1 xs)
Function calls in OCaml (juxtaposed expressions) have high precedence. So you need parentheses around (n - 1) in two places.
When I compile my code is ok, but when I call and execute the function Quicksort, the program seems to be in infinite loop. What Can I do ?
I tested all the functions, but it seems the problem is in tQuicksort function.
I'm a beginner.
let h l =
match l with
| [] -> raise (Failure "head")
| x::xs -> x;;
let t l =
match l with
| [] -> raise (Failure "tail")
| x::xs -> xs;;
let rec trev l r =
match l with
| [] -> r
| x::xs -> trev xs (x::r);;
let rev l = trev l [];;
let rec tunir l1 l2 r =
match l1 with
| [] -> if l2 == [] then
rev r
else
tunir [] (t l2) ((h l2)::r)
| x1::xs1 -> tunir xs1 l2 (x1::r);;
let unir l1 l2 = tunir l1 l2 [];;
let rec tpart x l l1 l2 =
match l with
| [] -> if l1 == [] then
((x::[]), l2)
else
(l1, (x::l2))
| (lx:: lxs) -> if (h l) <= x then
tpart x (t l) ((h l)::l1) l2
else
tpart x (t l) l1 ((h l)::l2);;
let part x l = tpart x l [] [];;
let rec tnroelem l n =
match l with
| [] -> n
| x::xs -> tnroelem (t l) (n+1);;
let nroelem l = tnroelem l 0;;
let rec tunirL l r =
match l with
| [] -> rev r
| lx::lxs -> if lx == [] then tunirL lxs r
else tunirL((t lx)::lxs) ((h lx)::r);;
let unirL l = tunirL l [];;
let rec tquicksort lm l lM =
match l with
| [] -> unirL (unir (rev lm) lM)
| lx::lxs -> let (la, lb) = part (h l) (t l) in
if (nroelem la < nroelem lb) then tquicksort ((quicksort la)::lm) lb lM
else tquicksort lm la ((quicksort lb)::lM)
and quicksort l = tquicksort [] l [];;
let rec geraListaT n l =
if n == 0 then l
else geraListaT (n-1) (n::l);;
let geraLista n = geraListaT n [];;
let lista : int list = geraLista 9;;
List.iter (fun x->print_int x) (quicksort lista)
You are missing a case when you're attempting to quicksort lm l lM and l only has one element. In that case the branch taken is
| lx::lxs -> let (la, lb) = part (h l) (t l) in
if (nroelem la < nroelem lb)
then tquicksort ((quicksort la)::lm) lb lM
else tquicksort lm la ((quicksort lb)::lM)
And then no matter what the result of the if is, you perform a recursive call quicksort lm' l' lM' where l' also has only one element. This can be fixed by adding an extra case after the one for the empty list:
| lx::[] -> unirL (unir (rev (l :: lm)) lM)
I'm trying to write a function that takes in a list, and returns the number of successive duplicate elements in the list.
For example, given [1;2;3;3;4;4;5], the function should return 2
This is my initial implementation, but unfortunately it always returns 0. I'm not quite sure where the bug lies.
Any help on how to improve it will be highly appreciated.
let rec count_successive_duplicates (lst: int list) (count: int) : (int) =
match lst with
| [] | [_]-> 0
| x :: y :: tl ->
if x = y then count_successive_duplicates (y::tl) (count + 1) else count_successive_duplicates (y::tl) count
;;
let () =
print_int (count_successive_duplicates [1;2;3;3;4;4;5] 0)
In the end, you'll want to return the accumulator with the count instead of 0 always:
let rec count_successive_duplicates (lst: int list) (count: int) : (int) =
match lst with
| [] | [_] -> count
(* ^^^^^ */)
| x :: y :: tl -> count_successive_duplicates (y::tl) (count + if x = y then 1 else 0)
Seems I was doing something silly by always returning 0 for the base case, instead of the computed count. The previous version was just ignoring the computed count it received. This now works:
let rec count_successive_duplicates lst count : (int) = match lst with
| [] | [_]-> count
| x :: y :: tl ->
if x = y then count_successive_duplicates (y::tl) (count + 1) else count_successive_duplicates (y::tl) count
;;
let () =
print_int (count_successive_duplicates [1;2;3;3;4;4;5] 0)
How would I combine the following 2 functions:
replaceNth n newVal (x:xs)
| n == 0 = newVal:xs
| otherwise = x:replaceNth (n-1) newVal xs
replaceMthNth m n v arg = replaceNth m (replaceNth n v (arg !! m)) arg
into a single function?
Is it possible?
This is pretty hideous but it does the job:
replacemn 0 0 z ((x : xs) : xss) = (z : xs) : xss
replacemn 0 n z ((x : xs) : xss) =
let (ys : yss) = replacemn 0 (n-1) z (xs : xss)
in ((x : ys) : yss)
replacemn m n z (xs:xss) = xs : replacemn (m-1) n z xss
Function composition
Functions in Haskell may be composed at no cost. E.g. given two functions, f and g, you can compose them into a new function: f . g, which applies g to an argument, then applies f to the result. You should be able to use composition in the same way here.
Ok, here it is with no other named functions in the global namespace, or using any where or let clauses or any other global functions.
{-# LANGUAGE ScopedTypeVariables,RankNTypes #-}
module Temp where
newtype Mu a = Mu (Mu a -> a)
replaceMthNth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceMthNth = (\h (f :: Int -> forall b . b -> [b] -> [b]) -> h f f)
( \replaceNth replaceNth' ->
-- definition of replaceMthNth in terms of some replaceNth and replaceNth'
\m n v arg -> replaceNth m (replaceNth' n v (arg !! m)) arg
)
$
-- y combinator
((\f -> (\h -> h $ Mu h) $ \x -> f $ (\(Mu g) -> g) x $ x) :: (a -> a) -> a) $
(\replaceNth ->
-- definition of replaceNth given a recursive definition
(\(n::Int) newVal xs -> case xs of
[] -> []
(x:xs) -> if n == 0 then newVal:xs else x:replaceNth (n-1) newVal xs
)
)
I don't understand what the question is at all :), but here is how I would implement it:
modifyNth :: Int -> (a -> a) -> [a] -> [a]
modifyNth n f (x:xs)
| n == 0 = f x : xs
| otherwise = x : modifyNth (n-1) f xs
replaceNthMth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceNthMth m n v = modifyNth m (modifyNth n (const v))
This way you don't need to traverse the list twice (first time with !!, second time with replaceNth)
Here's a grotesque implementation that rebuilds the 2d list structure with nested list comprehensions over zips with infinite lists:
replaceMthNth :: Int -> Int -> a -> [[a]] -> [[a]]
replaceMthNth m n v ass = [[if (x,y) == (m,n) then v else a
| (y, a) <- zip [0..] as]
| (x, as) <- zip [0..] ass]