haskell function that takes a list and constructs a list of the elements between certain elements - haskell

--profs solution
splitsep sep [] = [[]]
splitsep sep (h:t)
| sep h = []: splitsep sep t
| otherwise = ((h:w):rest)
where w:rest = splitsep sep t
Having trouble wrapping my head around how exactly this works. Can anyone trace it out?

Related

How can I take multiple elemtents in a list comprehension

I want to take five consecutive primes generated as an infinite list by primes and check them if they summed make another prime. I want to have something like this:
consecutivePrimes = [ a+b+c+d+e | a:b:c:d:e <- primes, prime a+b+c+d+e]
This a:b:c:d:e <- primes however doesn't work and I can't find any way as to get multiple elements at once in a list comprehension.
Since a list comprehension can be thought of as a map combined with a filter (at least for lists), you can only get one element at a time inside of it.
But you can still do this by making primes into a list of lists using tails, then taking 5 elements from each of the lists. The single element you map over (ps) in this case is a list.
import Data.List (tails)
consecutivePrimes = [ a+b+c+d+e | ps <- tails primes, let [a,b,c,d,e] = take 5 ps, prime a+b+c+d+e]
Pattern matching on the list of 5 elements will always succeed if your input list is infinite.
This is my solution which works but I find it quite ugly:
consecutivePrimes = [x | x <- consecutivePrimes' primes, prime x]
consecutivePrimes' (a:b:c:d:e:xs) | prime (a+b+c+d+e) = (a+b+c+d+e) : consecutivePrimes' (b:c:d:e:xs)
| otherwise = consecutivePrimes' (b:c:d:e:xs))

list vs. incremental values security

Can someone tell me the formal reason why list/arrays and such are considered more secure when it comes to incremental steps i.e (List.fold > loops).
Exampel code in F#
Functional way (list)
let rec sum lst =
match lst with
| [] -> 0
| x::xs -> x + sum xs
Imperative way (incremental)
let sum n m =
let mutable s = 0
for i=n to m do
s <- s + i
s
If by security you mean "safer" -- then I think this will explain it some. To begin with if you're summing a list, a fold should be somewhat safer as it removes the need for the programmer to correctly index the list:
let sum lst =
let mutable s = 0
for i=0 to (List.length lst - 1) do
s <- s + lst.[i]
s
You avoid a lot of pitfalls completely by using the library function:
let sum lst =
let folder acc element =
acc + element
List.fold folder 0 lst
The fold handles all the edge cases for you, in terms of indices, and list length. (note: this could also be done with a List.reduce (+) lst however that does not handle an empty list, where as a fold does).
The short of it all is that it keeps the programmer from making mistakes on silly index math, and keeps the focus on the actual logic of what is being done.
EDIT: I ironically messed up the index logic in my initial post

How can i use conditionals in list comprehension?

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.

python 3.4.2 joining strings into lists

I am a python newbie so am writing small programs to get more familiar. I have a rasp PI to, very unix skilled,done programming but not python3. One of these is a simple bubble sort, it reads in two txt files with numbers 5 9 2 19 18 17 13 and another with different numbers 10 14 2 4 6 20 type thing
I use a function to read in each file then join them before I bubblesort the whole string, I'm aware it needs to be a list so that the bubblesort function can move the numbers around during each pass. From what I can tell my issue is the mergesort (var name for the concatenated list) always is a string.
Anyone shed any light on why this is so? and how could I convert the two files into a single list?
------------------sample code-------------------
mergesort = []
def readfile1():
tempfile1 = open('sortfile1.txt','r')
tempfile1 = tempfile1.read()
return tempfile1
def readfile2():
tempfile2 = open('sortfile2.txt','r')
tempfile2 = tempfile2.read()
return tempfile2
sortstring1 = readfile1()
# print (sortstring1)
sortstring2 = readfile2()
# print (sortstring2)
# mergesort = list(set(sortstring1) | set(sortstring2)
mergesort = sortstring1 + sortstring2
print (mergesort, "Type=", type(mergesort))
Assuming you want to get one list of integers, you could do it like this. Notice I also combined your functions into one because they were doing the exact same thing.
In your code, you are not splitting the contents of the file into a list, so it was read in as a string. use the split() method to split a string into a list.
def read_file_to_list(filename):
temp = open(filename, 'r')
string = temp.read()
numbers = [int(x) for x in string.split(' ')]
return numbers
sort1 = read_file_to_list('sortfile1.txt')
sort2 = read_file_to_list('sortfile2.txt')
total = sort1 + sort2

Listing one element in a string[] list f#

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.

Resources