Related
So I need to create such list
[2,4,5,8,9,10,11,16,17,18,19,20,21,22,23,32 ..]
The pattern goes as follows:
2^1,2^2, 2^2 +1, 2^3, 2^3 +1, 2^3 +2, 2^3 +3 .. So the number of repeats of (2^n +1, 2^n +2 .. is also doubling with each go ) I hope you got the point.
I can create such list using functions in Haskell but I was interested whether or not it is possible to do it using solely list Comprehension
EDIT: Some people asked me to demonstrate a functional approach to this problem. Here it is
rep _ 0 = []
rep a b = a : rep (a+1) (b-1)
createlist a = rep (2^(a+1)) (2^a) ++ createlist (a+1))
So if we say `take 50 (createlist 0) the results would be
[2,4,5,8,9,10,11,16,17,18,19,20,21,22,23,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82]
So you always need to call the function with initial parameter 0. It is really a nasty solution I would like to make it easier.
Based on your example, the list looks like:
2
4 5
8 9 10 11
16 17 18 19 20 21 22 23
32 33 34 35 36 37 38 39 40 41 ...
So for every i from 1 to infinity, we yield the elements in the range [2i,2i+2i-1). We can write this directly into list comprehension:
[ j | i <- [1..], j <- [2^i .. 2^i + 2^(i-1) - 1] ]
We can also let i take powers of two, and yield elements between i, and div (3*i) 2 (exclusive), so:
[ j | i <- iterate (2*) 2, j <- [i .. div (2*i) 3 - 1] ]
We can turn that also into a list monad, like:
iterate (*2) 2 >>= \i -> [i..div (3*i) 2 - 1]
or more point-free (and point-less):
import Control.Monad(ap)
iterate (*2) 2 >>= ap enumFromTo (pred . flip div 2 . (3 *))
One could try to write the ith term of the list using a function f(i), where i >= 0
The overall infinite list can be represented as
L_0 ++ L_1 ++ L_2 ++ ...
where each L_n is a finite list of the form
L_n = [ 2^(n+1), 2^(n+1) + 1, ..., 2^(n+1) + (2^n - 1) ]
The size of L_n is 2^n and we know that for any k, 2^0 + 2^1 + ... + 2^k = 2^(k+1) - 1 (it's a geometric progression) so if we're asked to find which finite list the ith term of the infinite list is in, we can find the highest integer m for which i >= 2^m - 1. Once that's done, we can safely say the ith term is in L_m. We can also say that the ith term of the infinite list is the (i - 2^m + 1)th element of L_m.
This allows us to define the final sequence (let's call it thatList) as
thatList :: [Int]
thatList = [ f i | i <- [0..] ]
and
f :: Int -> Int
f i = (2 ^ (m + 1)) + (i - (2 ^ m) + 1)
where
m = floor (logBase 2 (fromIntegral i + 1))
I have go a problem with function in SML. This function should return list index of number which will not be summed, but was taken to sum.
A call of a function: index(10, [1,2,3,4,5,6,7])
Result should be 3
(10 is a sum of numbers, we seek an index from the list which gives us 10, e.g:
1+2+3=6, 1+2+3+4=10, and return previuos one)
fun index (sum : int, numbers : int list) =
if null numbers
then 0
else if hd(numbers) > sum
then 0
else 1 + index(sum, (hd(numbers)+(hd(tl numbers)))::(tl numbers))
It seems to work, but result is wrong.
Function increments the result every two calling even if it should not.
Can anybody tell me how to fix this?
You're almost there. While I agree with #koodawg that adding a counter and a running total is another solution for this problem, having those in your code will complicate it more than it needs to be.
First, I have a few comments about your code. You must remove the unnecessary parens. hd(numbers) is same as hd numbers and (hd(tl numbers)) is equal to hd(tl numbers). So your (hd(numbers)+(hd(tl numbers))) could be simplified to (hd numbers + hd(tl numbers)). Also, you can combine if null numbers and if hd(numbers) > sum in a single condition for code brevity since they yield the same result: 0.
I'll try to explain how code works and I hope you'll get the idea where you have to amend your code.
Using your example, index(10, [1,2,3,4,5,6,7]), your code execution will be like this:
1)
fun index(10, [1,2,3,4,5,6,7]) =
if 1 > 10
then 0
else 1 + (10, [1 + 2] append to [2,3,4,5,6,7])
new list: [3,2,3,4,5,6,7]
result: 1
2)
fun index(10, [3,2,3,4,5,6,7]) =
if 3 > 10
then 0
else 1 + (10, [3 + 2] append to [2,3,4,5,6,7])
new list: [5,2,3,4,5,6,7]
result: 1
3)
fun index(10, [5,2,3,4,5,6,7]) =
if 5 > 10
then 0
else 1 + (10, [5 + 2] append to [2,3,4,5,6,7])
new list: [7,2,3,4,5,6,7]
result: 1
4)
fun index(10, [7,2,3,4,5,6,7]) =
if 7 > 10
then 0
else 1 + (10, [7 + 2] append to [2,3,4,5,6,7])
new list: [9,2,3,4,5,6,7]
result: 1
5)
fun index(10, [9,2,3,4,5,6,7]) =
if 9 > 10
then 0
else 1 + (10, [9 + 2] append to [2,3,4,5,6,7])
new list: [11,2,3,4,5,6,7]
result: 1
6)
fun index(10, [11,2,3,4,5,6,7]) =
if 11 > 10
then 0
result: 0
To sum all results: 1 + 1 + 1 + 1 + 1 + 0 = 5 (just like what you said that your function adds 2 to the expected result)
The correct code must behave like this:
1)
fun index(10, [1,2,3,4,5,6,7]) =
if 1 > 10
then 0
else 1 + (10, [1 + 2] append to [3,4,5,6,7])
new list: [3,3,4,5,6,7]
result: 1
2)
fun index(10, [3,3,4,5,6,7]) =
if 3 > 10
then 0
else 1 + (10, [3 + 3] append to [4,5,6,7])
new list: [6,4,5,6,7]
result: 1
3)
fun index(10, [6,4,5,6,7]) =
if 6 > 10
then 0
else 1 + (10, [6 + 4] append to [5,6,7])
new list: [10,5,6,7]
result: 1
4)
fun index(10, [10,5,6,7]) =
if 10 > 10
then 0
result: 0
To sum all results: 1 + 1 + 1 + 0 = 3 which is the expected answer.
HINT: You always make sure that the new list your function is processing must be smaller than the previous list/original list.
I hope I explained clearly why your code isn't working. I didn't include the code because I know this is a homework for an online class.
You need to keep a counter and total. Counter that increments with every recursive call, total equal to sum of each hd(numbers) as you go, then return the counter when your total > sum.
Something like this;
if (total + hd numbers) >= sum
then counter
else recursivecall(total + hd numbers, tl numbers, counter + 1)
I'm trying to find the n-th set in a powerset. By n-th I mean that the powerset is generated in the following order -- first by the size, and then, lexicographically --, and so, the indices of the sets in the powerset of [a, b, c] is:
0 - []
1 - [a]
2 - [b]
3 - [c]
4 - [a, b]
5 - [a, c]
6 - [b, c]
7 - [a, b, c]
While looking for a solution, all I could find was an algorithm to return the n-th permutation of a list of elements -- for example, here.
Context:
I'm trying to retrieve the entire powerset of a vector V of elements, but I need to do this with one set at a time.
Requirements:
I can only maintain two vectors at the same time, the first one with the original items in the list, and the second one with the n-th set from the powerset of V -- that's why I'm willing to have an n-th set function here;
I need this to be done not in linear time on the space of solutions -- which means it cannot list all the sets and them pick the n-th one;
my initial idea is to use bits to represent the positions, and get a valid mapping for what I need -- as the "incomplete" solution I posted.
I don't have a closed form for the function, but I do have a bit-hacking non-looping next_combination function, which you're welcome to, if it helps. It assumes that you can fit the bit mask into some integer type, which is probably not an unreasonable assumption given that there are 264 possibilities for the 64-element set.
As the comment says, I find this definition of "lexicographical ordering" a bit odd, since I'd say lexicographical ordering would be: [], [a], [ab], [abc], [ac], [b], [bc], [c]. But I've had to do the "first by size, then lexicographical" enumeration before.
// Generate bitmaps representing all subsets of a set of k elements,
// in order first by (ascending) subset size, and then lexicographically.
// The elements correspond to the bits in increasing magnitude (so the
// first element in lexicographic order corresponds to the 2^0 bit.)
//
// This function generates and returns the next bit-pattern, in circular order
// (so that if the iteration is finished, it returns 0).
//
template<typename UnsignedInteger>
UnsignedInteger next_combination(UnsignedInteger comb, UnsignedInteger mask) {
UnsignedInteger last_one = comb & -comb;
UnsignedInteger last_zero = (comb + last_one) &~ comb & mask;
if (last_zero) return comb + last_one + (last_zero / (last_one * 2)) - 1;
else if (last_one > 1) return mask / (last_one / 2);
else return ~comb & 1;
}
Line 5 is doing the bit-hacking equivalent of the (extended) regular expression replacement, which finds the last 01 in the string, flips it to 10 and shifts all the following 1s all the way to the right.
s/01(1*)(0*)$/10\2\1/
Line 6 does this one (only if the previous one failed) to add one more 1 and shift the 1s all the way to the right:
s/(1*)0(0*)/\21\1/
I don't know if that explanation helps or hinders :)
Here's a quick and dirty driver (the command-line argument is the size of the set, default 5, maximum the number of bits in an unsigned long):
#include <iostream>
template<typename UnsignedInteger>
std::ostream& show(std::ostream& out, UnsignedInteger comb) {
out << '[';
char a = 'a';
for (UnsignedInteger i = 1; comb; i *= 2, ++a) {
if (i & comb) {
out << a;
comb -= i;
}
}
return out << ']';
}
int main(int argc, char** argv) {
unsigned int n = 5;
if (argc > 1) n = atoi(argv[1]);
unsigned long mask = (1UL << n) - 1;
unsigned long comb = 0;
do {
show(std::cout, comb) << std::endl;
comb = next_combination(comb, mask);
} while (comb);
return 0;
}
It's hard to believe that this function might be useful for a set of more than 64 elements, given the size of the enumeration, but it might be useful to enumerate some limited part, such as all subsets of three elements. In this case, the bit-hackery is only really useful if the modification fits in a single word. Fortunately, that's easy to test; you simply need to do the computation as above on the last word in the bitset, up to the test for last_zero being zero. (In this case, you don't need to bitand mask, and indeed you might want to choose a different way of specifying the set size.) If last_zero turns out to be zero (which will actually be pretty rare), then you need to do the transformation in some other way, but the principle is the same: find the first 0 which precedes a 1 (watch out for the case where the 0 is at the end of a word and the 1 at the beginning of the next one); change the 01 to 10, figure out how many 1s you need to move, and move them to the end.
Considering a list of elements L = [a, b, c], the powerset of L is given by:
P(L) = {
[],
[a], [b], [c],
[a, b], [a, c], [b, c],
[a, b, c]
}
Considering each position as a bit, you'd have the mappings:
id | positions - integer | desired set
0 | [0 0 0] - 0 | []
1 | [1 0 0] - 4 | [a]
2 | [0 1 0] - 2 | [b]
3 | [0 0 1] - 1 | [c]
4 | [1 1 0] - 6 | [a, b]
5 | [1 0 1] - 5 | [a, c]
6 | [0 1 1] - 3 | [b, c]
7 | [1 1 1] - 7 | [a, b, c]
As you see, the id is not directly mapped to the integers. A proper mapping needs to be applied, so that you have:
id | positions - integer | mapped - integer
0 | [0 0 0] - 0 | [0 0 0] - 0
1 | [1 0 0] - 4 | [0 0 1] - 1
2 | [0 1 0] - 2 | [0 1 0] - 2
3 | [0 0 1] - 1 | [0 1 1] - 3
4 | [1 1 0] - 6 | [1 0 0] - 4
5 | [1 0 1] - 5 | [1 0 1] - 5
6 | [0 1 1] - 3 | [1 1 0] - 6
7 | [1 1 1] - 7 | [1 1 1] - 7
As an attempt on solving this, I came up using a binary tree to do the mapping -- I'm posting it so that someone may see a solution from it:
#
______________|_____________
a / \
_____|_____ _______|______
b / \ / \
__|__ __|__ __|__ __|__
c / \ / \ / \ / \
[ ] [c] [b] [b, c] [a] [a, c] [a, b] [a, b, c]
index: 0 3 2 6 1 5 4 7
Suppose your set has size N.
So, there are (N choose k) sets of size k. You can find the right k (i.e. the size of the nth set) very quickly just by subtracting off (N choose k) from n until n is about to go negative. This reduces your problem to finding the nth k-subset of an N-set.
The first (N-1 choose k-1) k-subsets of your N-set will contain its least element. So, if n is less than (N-1 choose k-1), pick the first element and recurse on the rest of the set. Otherwise, you have one of the (N-1 choose k) other sets; throw away the first element, subtract (N-1 choose k-1) from n, and recurse.
Code:
#include <stdio.h>
int ch[88][88];
int choose(int n, int k) {
if (n<0||k<0||k>n) return 0;
if (!k||n==k) return 1;
if (ch[n][k]) return ch[n][k];
return ch[n][k] = choose(n-1,k-1) + choose(n-1,k);
}
int nthkset(int N, int n, int k) {
if (!n) return (1<<k)-1;
if (choose(N-1,k-1) > n) return 1 | (nthkset(N-1,n,k-1) << 1);
return nthkset(N-1,n-choose(N-1,k-1),k)<<1;
}
int nthset(int N, int n) {
for (int k = 0; k <= N; k++)
if (choose(N,k) > n) return nthkset(N,n,k);
else n -= choose(N,k);
return -1; // not enough subsets of [N].
}
int main() {
int N,n;
scanf("%i %i", &N, &n);
int a = nthset(N,n);
for (int i=0;i<N;i++) printf("%i", !!(a&1<<i));
printf("\n");
}
I just come across a challenging problem (from programming competition practice) that contain recursive sequence as following
given 3 numbers m n k find element a[k] where
a[0] = m
a[1] = n
a[i] = a[i-1] + a[i-2] ; if floor(i/2) mod 2 = 1
a[i] = a[i-1] - a[i-4] ; if floor(i/2) mod 2 = 0
example case: for m=2 n=3 k=6 answer would be 9
a[0] = 2
a[1] = 3
a[2] = 3 + 2 = 5
a[3] = 5 + 3 = 8
a[4] = 8 - 2 = 6
a[5] = 6 - 3 = 3
a[6] = 3 + 6 = 9
...
this is how I generate the sequence (which obviously consume lots of stack and super slow even for the first 100 element)
1 fbm :: Int → Int → Int → Int
2 fbm m n 0 = m
3 fbm m n 1 = n
4 fbm m n x = let a = fbm m n (x-1)
5 b = fbm m n (x-2)
6 c = fbm m n (x-4)
7 in case (x `div` 2) `mod` 2 of
8 1 → a + b
9 0 → a - c
10
11 fbs m n = map (λx→fbm m n x) [0..]
Since the problem required to find element at big (~1000+) index. I try to do a different approach by trying to limit computation only on function with 4 inputs and apply the function with 4 element window recursively on the list but can't success implementing any of them (something mean I can't figured out how to do it)
fs1 = map fst $ iterate next (a,b)
where next (a,b) = something
fs2 = m:n:scanl (gen) 2 fs2
where gen [a,b,c,d] = something
fs3 = scanl (genx m n 0 0) (repeat 0)
where genx a b c d = something
Question 1: Does any of my approach the good way to solve this problem? (+ please show me an example of how to do it)
Question 2: How would you solve this kind of problem if I am in the wrong way?
This problem is similar to "Fibonacci series", but in my opinion, there is a big difference between them.
Memoization is a common technique to solve this kind of problems.
For example, we can use it to compute Fibonacci series.
The following is a very simple illustration. It is not as good as that zipWith solution, but it is still a linear operation implementation.
fib :: Int -> Integer
fib 0 = 1
fib 1 = 1
fib n = fibs !! (n-1) + fibs !! (n-2)
fibs :: [Integer]
fibs = map fib [0..]
If we try to imitate the above fib and fibs, perhaps we would write the following code.
fbm :: Int -> Int -> Int -> Int
fbm m n 0 = m
fbm m n 1 = n
fbm m n x = let a = fbs m n !! (x-1)
b = fbs m n !! (x-2)
c = fbs m n !! (x-4)
in case (x `div` 2) `mod` 2 of
1 -> a + b
0 -> a - c
fbs :: Int -> Int -> [Int]
fbs m n = map (fbm m n) [0..]
But the above fbs is also super slow. Replacing list by array makes little difference. The reason is simple, there is no memoization when we call fbs.
The answer will be more clear if we compare the type signatures of fibs and fbs.
fibs :: [Integer]
fbs :: Int -> Int -> [Int]
One of them is a list of intergers, while the other is a function.
To let memoization happen, we have to implement fbs in anothing way.
e.g.
fbs m n = let xs = map fbm [0..]
fbm 0 = m
fbm 1 = n
fbm x = let a = xs !! (x-1)
b = xs !! (x-2)
c = xs !! (x-4)
in case (x `div` 2) `mod` 2 of
1 -> a + b
0 -> a - c
in xs
Tail recursion is anothing common approach for this kind of problems.
fbm :: Int -> Int -> Int -> (Int, Int, Int, Int)
-- a[0] = m
-- a[1] = n
-- a[2] = m + n
-- a[3] = m + 2 * n
fbm m n 3 = (m+2*n, m+n, n, m)
fbm m n x = case (x `div` 2) `mod` 2 of
1 -> (a+b, a, b, c)
0 -> (a-d, a, b, c)
where (a,b,c,d) = fbm m n (x-1)
Last but not least, here is a mathematical solution.
a[0] = m
a[1] = n
a[2] = m + n
a[3] = m + 2n
a[4] = 2n
a[5] = n
a[6] = 3n
a[7] = 4n
a[8] = 2n
fbs m n = [m, n, m+n, m+2*n] ++ cycle [2*n, n, 3*n, 4*n]
I'd like to propose two solutions, which also based on the concept of memoisation introduced here by dbaupp. Unlike the existing answer, following solutions compute new elements of the list using indices instead of values of previous elements.
The first idea is following
fbs :: Int -> Int -> [Int]
fbs m n = m : n : map (fbMake m n) [2 ..]
fbMake :: Int -> Int -> Int -> Int
fbMake m n = f
where f i | (i `div` 2) `mod` 2 == 1 = (xs !! (i - 1)) + (xs !! (i - 2))
| otherwise = (xs !! (i - 1)) - (xs !! (i - 4))
xs = fbs m n
This solution builds elements of the fbs m n list from its memoised predecessors. Unfortunately, due to the fact that indexing of lists is O(n) it performs rather poorly.
What's better when it comes to indexing than lists? Arrays come into play. Here's the second solution.
import Data.Array
fbs :: Int -> Int -> Int -> [Int]
fbs m n k = m : n : map (fbm m n k) [2 .. k]
fbsArr :: Int -> Int -> Int -> Array Int Int
fbsArr m n k = listArray (0, k) (fbs m n k)
fbm :: Int -> Int -> Int -> Int -> Int
fbm m n k i | (i `div` 2) `mod` 2 == 1 = (xs ! (i - 1)) + (xs ! (i - 2))
| otherwise = (xs ! (i - 1)) - (xs ! (i - 4))
where xs = fbsArr m n k
It's nearly the same as the first one, but this time the results are memoised in an array and indexing its elements is significantly faster. According to my tests it generates answers for (m, n, k) = (2, 3, 1000) over 10 times faster than the list-based approach. The answer in this case is fbsArr m n k ! k.
I've been tasked with writing a function that generates a table given n operators. The truth table must be in a list and each row of the table must be in separate lists (inside the main list).
I know the solution involves recursion but I just can't seem to think it through.
Can someone help me out? This is only a small part of the assignment.
Easiest way I can think of off the top of my head is to simply convert 2^n to binary and count down, then convert the output to a list.
ie for n=3:
Truth table:
a b c
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
2^3 = 8, 8 in binary = 1000, start from 1000-1 = 111 and work your way down to 0, record outputs, and voila!
If hkf's interpretation of your question is right, this should work in Racket:
#lang racket
(define (generate-table n)
(if (zero? n)
'(())
(for*/list ((y (in-list (generate-table (sub1 n))))
(x (in-list '(0 1))))
(cons x y))))
Use it like this:
(generate-table 3)
> ((0 0 0) (1 0 0) (0 1 0) (1 1 0) (0 0 1) (1 0 1) (0 1 1) (1 1 1))
Let's assume that all N operators are binary functions, like AND and OR.
;; Common Lisp
(defun truth-tables (ops)
(loop for op in ops
collecting
(loop for args in '((nil nil) (nil t) (t nil) (t t))
collecting (eval `(,op ,#args)))))
(truth-tables '(and or xor)) -> ((NIL NIL NIL T) (NIL T T T) (NIL T T NIL))
This gives you an idea. Well, here I don't have "each row of the truth table" as a sublist; I have the columns for the AND, OR and XOR truth tables, respectively. The input variable combinations are left implicit: you know that the third entry of every one corresponds to (<op> t nil). Your description of the problem is not very clear.
As you can also see, I cheated by using the Lisp operators through generated code which is dynamically evaluated.