For instance, given the input n = 3 I want to obtain:
[(1,),(2,),(3,),(1,2),(1,3),(2,3),(1,2,3)]
I tried a python-like syntax:
combs = [comb for x in collect(1:n) for comb in combinations(collect(1:n),x)]
but I got the following error message:
ERROR: LoadError: syntax: expected ]
I've also tried this:
combs = [comb for comb in vcat([combinations(collect(1:n),x) for x in collect(1:n)])]
but I got:
[Base.Combinations{Array{Int64,1}}([1,2,3],1),Base.Combinations{Array{Int64,1}}([1,2,3],2),Base.Combinations{Array{Int64,1}}([1,2,3],3)]
How to get the result I want?
Is
n = 3
vcat([collect(combinations(1:n,i)) for i=1:n]...)
OK?
Output:
7-element Array{Array{Int64,1},1}:
[1]
[2]
[3]
[1,2]
[1,3]
[2,3]
[1,2,3]
OTHER METHODS:
Another method is [65-findin(bits(i),'1') for i=1:(2^n-1)], which points the way to a very efficient implementation along the lines of:
tmp = BitVector(sizeof(Int)*8)
[begin tmp.chunks[1]=i; find(tmp) end for i=1:(2^n-1)]
although it uses BitVector internals, which might be obscure.
For memory efficiency:
using Iterators
chain(([combinations(1:n,i) for i=1:n])...) |> collect
(could be used directly as iterator in a for loop). But with Iterators one could use:
drop(subsets(1:n),1) |> collect
which is readable.
Related
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))
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
I just started to learn Haskell today and is completely overwhelmed by its syntax.
I am trying to apply math calculation to a list of items.
For example, lets say I want to square every item in the list using list comprehension.
My attempt
myfunc (n:lis) = [ k | k <-lis, k == k^k]
result_list = myfunc[1..]
take 10 result_list
My understand of my myfunc code: take a list and loop through elements that is stored in variable k and set k equals to its square.
after i execute the take command, and hit enter, apparently the process is running but does not do anything.
Note that i want to use list comprehension as a way to do it. I can use map do achieve my goal already.
You misunderstand the list comprehension.
[ k | k <- lis, k == k^k ]
The k == k^k clause is a filter –– it only keeps elements of the list that satisfy this equation. (== is a comparison operator that returns a bool, which is one hint). The reason you see no output is that there are no numbers in [1..] that satisfy this equation. But we get an infinite loop because we keep checking ever higher numbers to see if they satisfy it.
Something to experiment with
[ k | k <- lis, k < 100 ]
As for how to get a list of squares, use a comprehension like this
[ k^2 | k <- lis ]
If you want something more like your original phrasing, you can make let bindings within a list comprehension:
[ r | k <- lis, let r = k^2 ]
There are other issues with your code, but one baby step at a time! Good luck!
I'm working with some code and there seems to be an issue which I can't figure out.
So I've got a method which decrements an input Int by 1 until it hits 5. (I know if i enter less than 1 it would cause an error but i will fix that later)
I have a second function which calls a takes a List as a parameter which calls this function and returns the list of numbers, I want to call length on this list and populate a separate list (I'm not the best at explaining, i'll show with code examples below)
sub 5 = return [1]
sub x =
do
xs <- sub (x - 1)
return (x:xs)
f xs = [ length (sub x) | x<-xs ]
If I call sub 10 on it's own it gives the output [10,9,8,7,6,1], however if I call length on this, it gives the output [1].
In my head i thought the output would be 6, as it has 6 elements in.
Does anyone have any idea why this is happening and/or a way to fix it?
Thanks in advance.
sub doesn't return [10,9,8,6,1] but [[10,9,8,6,1]] (a list of list) therefore the length is 1. You don't need the return. You are in a list monad, return wraps it's value into a list, this why you end up with nested list. Your code should be
sub 5 = [1] -- or return 1
sub x = do
let xs = sub (x -1)
(x:xs)
The problem is that this sub function is written like you were in an imperative language and that return doesn't mean the same thing in Haskell : it means "wrap this thing in a Monad (which Monad depends on the context)". Here since you use length on the result of sub the list [] monad is used and the result is [ [10, 9, 8, 7, 6, 5] ] a list of one element which happen to be a list of 6 elements. mb14 correctly identified that but then corrected only the first case of your function, the second case is also monadic but shouldn't be...
sub 5 = [1]
sub x = x : sub (x - 1)
is the simple code you should be using, you don't need any monad here...
all_nat x = [ls| sum ls == x]
I'd like to write a function that given an integer x it returns all the lists that the result of their elements when summed is the integer x but I always get the error "not in scope: 'ls' " for both times it apperas. I'm new to haskell. What's the syntax error here?
The problem is that you need to define all used variables somewhere, but ls is undefined. Moreover, it can't be defined automatically, because the compiler doesn't know about the task — how the list should be generated? Ho long can it be? Are terms positive or not, integral or not? Unfortunately your code definition of the problem is quite vague for modern non-AI languages.
Let's help the compiler. To solve such problems, it's often useful to involve some math and infer the algorithm inductively. For example, let's write an algorithm with ordered lists (where [2,1] and [1,2] are different solutions):
Start with a basis, where you know the output for some given input. For example, for 0 there is only an empty list of terms (if 0 could be a term, any number could be decomposed as a sum in infinitely many ways). So, let's define that:
allNats 0 = [[]] --One empty list
An inductive step. Assuming we can decompose a number n, we can decompose any number n+k for any positive k, by adding k as a term to all decompositions of n. In other words: for numbers greater than 0, we can take any number k from 1 to n, and make it the first term of all decompositions of (n-k):
allNats n = [ k:rest --Add k as a head to the rest, where
| k <- [1 .. n] --k is taken from 1 to n, and
, rest <- allNats (n - k)] --rest is taken from solutions for (n—k)
That's all! Let's test it:
ghci> allNat 4
[[1,1,1,1],[1,1,2],[1,2,1],[1,3],[2,1,1],[2,2],[3,1],[4]]
Let's break this up into two parts. If I've understood your question correctly, the first step is to generate all possible (sub)lists from a list. There's a function to do this, called subsequences.
The second step is to evaluate the sum of each subsequence, and keep the subsequences with the sum you want. So your list comprehension looks like this:
all_nat x = [ls| ls <- subsequences [1..x], sum ls == x]
What about
getAllSums x = [(l,r)| l <- partial_nat, r <- partial_nat, l + r == x ]
where partial_nat = [1..x]