My recursion of getting subset doesn't print out the right answer - algorithm

I am trying to implement a method to get all subset of a set. I understand the logic of doing that. i.e. Subset(n) = n + Subset(n-1), but the code I wrote keep printing out the wrong answers. Here is my code:
void subset(vector<int> &input, vector<int> output, int current) {
if (current == input.size()-1) {
output.push_back(input[current]);
print(output);
}
else {
for (int i = current; i < input.size();i++) {
output.push_back(input[i]);
print(output);
subset(input, output, i+1);
}
}
}
Here is the output I got (input is {1,2,3}):
1
1 2
1 2 3
1 2 3
1 2
1 2 3
1 2 3
Any idea where I went wrong? Any help will be appreciated!

I think this can help you:
void subset(vector<int> &input, vector<int> output, int current) {
static int n=0;
if (current == input.size()) {
cout<<n++<<":\t {";
for(int i=0;i<output.size();i++) cout<<output[i]<<", ";
cout<<"\b\b}\n";
}
else {
subset(input, output, current+1); //exclude current'th item
output.push_back(input[current]);
subset(input, output, current+1); //include current'th item
}
}
and first time you may call it like this:
int main()
{
std::vector<int> inp, out;
for(int i=0; i<5; i++) // for example {1,2,3,4,5}
inp.push_back(i);
subset(inp, out, 0);
return 0;
}

You always print the output from its beginning: therefore you would never see [2,3], or [2] or [3] in the output
You have print statements in two places - thus the duplication of outputs

Related

Recursive algorithm to find all possible solutions in a nonogram row

I am trying to write a simple nonogram solver, in a kind of bruteforce way, but I am stuck on a relatively easy task. Let's say I have a row with clues [2,3] that has a length of 10
so the solutions are:
$$-$$$----
$$--$$$---
$$---$$$--
$$----$$$-
$$-----$$$
-$$----$$$
--$$---$$$
---$$--$$$
----$$-$$$
-$$---$$$-
--$$-$$$--
I want to find all the possible solutions for a row
I know that I have to consider each block separately, and each block will have an availible space of n-(sum of remaining blocks length + number of remaining blocks) but I do not know how to progress from here
Well, this question already have a good answer, so think of this one more as an advertisement of python's prowess.
def place(blocks,total):
if not blocks: return ["-"*total]
if blocks[0]>total: return []
starts = total-blocks[0] #starts = 2 means possible starting indexes are [0,1,2]
if len(blocks)==1: #this is special case
return [("-"*i+"$"*blocks[0]+"-"*(starts-i)) for i in range(starts+1)]
ans = []
for i in range(total-blocks[0]): #append current solutions
for sol in place(blocks[1:],starts-i-1): #with all possible other solutiona
ans.append("-"*i+"$"*blocks[0]+"-"+sol)
return ans
To test it:
for i in place([2,3,2],12):
print(i)
Which produces output like:
$$-$$$-$$---
$$-$$$--$$--
$$-$$$---$$-
$$-$$$----$$
$$--$$$-$$--
$$--$$$--$$-
$$--$$$---$$
$$---$$$-$$-
$$---$$$--$$
$$----$$$-$$
-$$-$$$-$$--
-$$-$$$--$$-
-$$-$$$---$$
-$$--$$$-$$-
-$$--$$$--$$
-$$---$$$-$$
--$$-$$$-$$-
--$$-$$$--$$
--$$--$$$-$$
---$$-$$$-$$
This is what i got:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef std::vector<bool> tRow;
void printRow(tRow row){
for (bool i : row){
std::cout << ((i) ? '$' : '-');
}
std::cout << std::endl;
}
int requiredCells(const std::vector<int> nums){
int sum = 0;
for (int i : nums){
sum += (i + 1); // The number + the at-least-one-cell gap at is right
}
return (sum == 0) ? 0 : sum - 1; // The right-most number don't need any gap
}
bool appendRow(tRow init, const std::vector<int> pendingNums, unsigned int rowSize, std::vector<tRow> &comb){
if (pendingNums.size() <= 0){
comb.push_back(init);
return false;
}
int cellsRequired = requiredCells(pendingNums);
if (cellsRequired > rowSize){
return false; // There are no combinations
}
tRow prefix;
int gapSize = 0;
std::vector<int> pNumsAux = pendingNums;
pNumsAux.erase(pNumsAux.begin());
unsigned int space = rowSize;
while ((gapSize + cellsRequired) <= rowSize){
space = rowSize;
space -= gapSize;
prefix.clear();
prefix = init;
for (int i = 0; i < gapSize; ++i){
prefix.push_back(false);
}
for (int i = 0; i < pendingNums[0]; ++i){
prefix.push_back(true);
space--;
}
if (space > 0){
prefix.push_back(false);
space--;
}
appendRow(prefix, pNumsAux, space, comb);
++gapSize;
}
return true;
}
std::vector<tRow> getCombinations(const std::vector<int> row, unsigned int rowSize) {
std::vector<tRow> comb;
tRow init;
appendRow(init, row, rowSize, comb);
return comb;
}
int main(){
std::vector<int> row = { 2, 3 };
auto ret = getCombinations(row, 10);
for (tRow r : ret){
while (r.size() < 10)
r.push_back(false);
printRow(r);
}
return 0;
}
And my output is:
$$-$$$----
$$--$$$---
$$---$$$--
$$----$$$--
$$-----$$$
-$$-$$$----
-$$--$$$--
-$$---$$$-
-$$----$$$-
--$$-$$$--
--$$--$$$-
--$$---$$$
---$$-$$$-
---$$--$$$
----$$-$$$
For sure, this must be absolutely improvable.
Note: i did't test it more than already written case
Hope it works for you

Shortest string to try all 3 digit lock

I was asked this question in one of my recent interviews. A three digit lock can have its key value between range "000" - "999". So basically 1000 combinations have to be tried to open the lock. So I had to generate the shortest string such that all possible combinations (i.e between "000"-"999") would be checked. So for example if we had string "01234" then it would check the combinations "012", "123" and "234". So I had to generate a string which would check all combination. I tried to use a hashset to implement this, where I started with "000" and then took the last two character in string i.e "00" and then appended a new number from 0 to 9 and checked if it existed in hashset. If not I appended that number to output string and repeated the process. Is there any other efficient and clean way to solve this problem.
The procedure you described is based on the assumption that the shortest string has every code exactly once. It turns out that this assumption is correct.
Here's a simple backtracking implementation (C++):
#include <stdio.h>
bool used[1000];
int digits[33333];
bool backtrack(int index, int total)
{
if (total == 1000)
{
printf("%d\n", index);
for (int i = 0; i < index; ++i) {
printf("%d", digits[i]);
}
printf("\n");
return true;
}
for (int d = 0; d < 10; ++d)
{
int prev = 100*digits[index-2]+10*digits[index-1]+d;
if (!used[prev]) {
digits[index] = d;
used[prev] = true;
if (backtrack(index+1, total+1))
return true;
used[prev] = false;
}
}
}
int main(void) {
digits[0] = 0;
backtrack(2, 0);
return 0;
}
Output:
1002
00010020030040050060070080090110120130140150160170\
18019021022023024025026027028029031032033034035036\
03703803904104204304404504604704804905105205305405\
50560570580590610620630640650660670680690710720730\
74075076077078079081082083084085086087088089091092\
09309409509609709809911121131141151161171181191221\
23124125126127128129132133134135136137138139142143\
14414514614714814915215315415515615715815916216316\
41651661671681691721731741751761771781791821831841\
85186187188189192193194195196197198199222322422522\
62272282292332342352362372382392432442452462472482\
49253254255256257258259263264265266267268269273274\
27527627727827928328428528628728828929329429529629\
72982993334335336337338339344345346347348349354355\
35635735835936436536636736836937437537637737837938\
43853863873883893943953963973983994445446447448449\
45545645745845946546646746846947547647747847948548\
64874884894954964974984995556557558559566567568569\
57657757857958658758858959659759859966676686696776\
78679687688689697698699777877978878979879988898999\
00
The procedure is efficient.

Graph visit every node once and reach exit

I had a test right now and this was one of the questions:
Input
The places to visit in the labyrinth are numbered from 1 to n. The entry and
the exit correspond to number 1 and number n, respectively; the remaining
numbers correspond to crossings. Note that there are no dead ends and
there is no more than one connection linking a pair of crossings.
For each test case, the first line gives n and the number of connections
between crossings (m). Then, in each of the following m lines, you find a pair
of integers corresponding to the connection between two crossings.
Output
For each test case, your implementation should output one single line
containing "Found!", if it is possible to reach the exit by visiting every
crossing once or "Damn!", otherwise. Other test cases may follow.
Constraints
m < 32
n < 21
Example input:
8 13
1 2
1 3
2 3
2 4
3 4
3 5
4 5
4 6
5 6
5 7
6 7
6 8
7 8
8 8
1 2
1 3
2 4
3 5
4 6
5 7
6 8
7 8
Example output:
Found!
Damn!
I solved the problem using a sort of DFS algorithm but i have a few questions.
Using DFS algorithm, I implemented a recursive function that starts in the given node and tries to visit every node once and the last node must be the exit node. I don't have the full code right now but but it was something like this:
findPath(int current node, int numVisitedNodes, int *visited){
int *tmpVisited = copyArray(visited); //copies the visited array to tmpVisited
//DFS algo here
}
Every recursive call it copies the visited nodes array. I'm doing this because when it finds an invalid path and the recursion goes back to the origin, it can still go because no one overwrote the visited nodes list.
Is there any better way to do this?
How would you solve it? (you can provide code if you want)
Read the crossing
if start or end of the crossing belongs to a reachable set, add both to that set else create a new reachable set.
When input has finished, check if any of the reachable sets contains
both entrance and exit points
HashSet operations complexity is O(1). If every crossing are distinct, complexity is O(n^2),which is the worst case complexity of this algorithm. Space complexity is O(n), there is no recursion so there is no recursion overhead of memory.
Roughly speaking, every node is visited only once.
Java code using valid reachable sets is as follows.
public class ZeManel {
public static void main(String[] args) {
Integer[][] input = {{1,2},{2,3},{4,6}};
zeManel(input);
}
public static void zeManel(Integer[][] input){
List<Set<Integer>> paths = new ArrayList<Set<Integer>>();
int max = 0;
for(int i = 0;i < input.length;i++) {
max = input[i][0] > max ? input[i][0] : max;
max = input[i][1] > max ? input[i][1] : max;
boolean inPaths = false;
for (Set<Integer> set : paths) {
if(set.contains(input[i][0]) || set.contains(input[i][1])) {
set.add(input[i][0]);
set.add(input[i][1]);
inPaths = true;
break;
}
}
if(!inPaths) {
Set<Integer> path = new HashSet<Integer>();
path.add(input[i][0]);
path.add(input[i][1]);
paths.add(path);
}
}
for (Set<Integer> path : paths) {
if(path.contains(1) && path.contains(max)) {
System.out.println("Found!");
return;
}
}
System.out.println("Damn!");
}
}
This was my implementation during the test:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
# define N 21
# define M 32
int i;
int adj[N][N];
int count = 0;
int findPath(int numNodes, int currentNode, int depth, int *visited){
visited[currentNode] = 1;
if(currentNode == numNodes - 1 && depth == numNodes){
return 1;
}
if(depth > numNodes)
return -1;
int r = -1;
if(depth < numNodes){
count++;
int *tmp = (int*) malloc(numNodes*sizeof(int));
for(i = 0; i < numNodes; i++)
tmp[i] = visited[i];
for(i = 0; i < numNodes; i++){
if(adj[currentNode][i] == 1 && tmp[i] == 0 && r == -1){
if(findPath(numNodes, i, depth + 1, tmp) == 1)
r = 1;
}
}
free(tmp);
}
return r;
}
int main(){
int numLigacoes, a, b, numNodes;
int *visited;
while (scanf("%d %d", &numNodes, &numLigacoes) != EOF){
visited = (int*) malloc(numNodes*sizeof(int));
count = 0;
memset(adj, 0, N*N*sizeof(int));
memset(visited, 0, numNodes*sizeof(int));
for (i = 0; i < numLigacoes; i++){
scanf("%d %d", &a, &b);
adj[a - 1][b - 1] = 1;
adj[b - 1][a - 1] = 1;
}
if(findPath(numNodes, 0, 1, visited) == 1)
printf("Found! (%d)\n", count);
else
printf("Damn! (%d)\n", count);
free(visited);
}
return 0;
}
What do you think about that?

How to print numbers in a spiral order?

Thank you ,
i am trying to solve a project euler problem it wants me to print the sum of
21 22 23 24 25
20 7 8 9 10
19 6 1 2 11
18 5 4 3 12
17 16 15 14 13
this is formed by starting with the number 1 and moving to the right in a clockwise direction for a 5 by 5 matrix but i am in trouble writing a code for the spiral matrix !!
It is Highly recommended to do project Euler problems on your own and ask for help if you are really stuck
here is how i will write a code in c to print a spiral as suggested in the question
#include<stdio.h>
main()
{
int i,j,nq=9;//nq is a odd number which represents the order of the matrix
int lim=(int)nq/2,cnt=2;
int a[nq][nq];
for(i=0;i<nq;i++){
for(j=0;j<nq;j++)
a[i][j]=0;
}
a[lim][lim]=1;
a[lim][lim+1]=2;
int i1=lim,j1=lim+1;i=lim,j=lim;
while(1){
if(cnt>(nq*nq))
break;
cnt++;
if(i==i1)
{ j=j1;
if(i<=lim)
{
i=i1;
if(a[i1+1][j1]==0)
a[++i1][j]=cnt;
else
a[i1][++j1]=cnt;
}
else
{ i=i1;
if(a[i1-1][j1]==0)
a[--i1][j1]=cnt;
else
a[i1][--j1]=cnt;
}
}
else
{ i=i1;
if(j<lim)
{
j=j1;
if(a[i1][j+1]==0)
a[i1][++j1]=cnt;
else
a[--i1][j1]=cnt;
}
else
{ j=j1;
if(a[i1][j1-1]==0)
a[i1][--j1]=cnt;
else
a[++i1][j1]=cnt;
}
}
}
for(i=0;i<nq;i++){
for(j=0;j<nq;j++)
printf(" %d ",a[i][j]);
printf("\n");
}
}
I Googled your question http://projecteuler.net/problem=28 this can also be solved by taking advantage of its mathematical nature note that
Top right corner is n^2
and other corners can be shown to be n^2-2n+2 ,n^2-n+1, and n^2-3n+3. you just need to sum those corners which comes to be
= 4*n^2 - 6*n + 6
hence the final answer can be calculated by iterating over every second number from 1001 to 3
long int sum(int n){
long int sum=1;
while(n>1){
sum=sum+4*n*n-6*n+6;
n=n-2;
}
return sum;
}
I dont know whether you actually want to print the spiral but see below for my solution for #28 written in Python 2.7.
l = [1]
def corners(step,l):
counter = 0
while counter < 4:
l.append(max(l)+step)
counter +=1
return l
step = 2
while step < 1001:
l = corners(step, l)
step += 2
print sum(l)
void printSpiral(int A[3][5],int m, int n)
{
int T=0; int B=m-1; int L=0; int R=n-1;
int dir=0;
int i =0; int j=0; int k=0; int l=0;
while(T<=B && L<=R)
{
//printf("dir %d ",dir);
if(dir == 0)
{
for( i=L;i<=R;i++)
{
printf("%d ",A[T][i]);
//printf("\n");
}
T++;
dir=1;
}
else if(dir == 1)
{
// printf("%d R ",R);
for( j=T;j<= B;j++)
{
printf("%d ",A[j][R]);
//printf("\n");
//printf("dir1");
}
dir=2;
R--;
}
else if(dir == 2)
{
for(k=R;k>= L;k--)
{
printf("%d ",A[B][k]);
}
dir=3;
B--;
}
else if(dir == 3)
{
for( l=B;l>= T;l--)
{
printf("%d ",A[l][L]);
}
L++;
dir=0;
}
}
}

N nested for-loops

I need to create N nested loops to print all combinations of a binary sequence of length N. Im not sure how to do this.
Any help would be greatly appreciated. Thanks.
Use recursion. e.g., in Java
public class Foo {
public static void main(String[] args) {
new Foo().printCombo("", 5);
}
void printCombo(String soFar, int len) {
if (len == 1) {
System.out.println(soFar+"0");
System.out.println(soFar+"1");
}
else {
printCombo(soFar+"0", len-1);
printCombo(soFar+"1", len-1);
}
}
}
will print
00000
00001
00010
...
11101
11110
11111
You have two options here:
Use backtracking instead.
Write a program that generates a dynamic program with N loops and then executes it.
You don't need any nested loops for this. You need one recursive function to print a binary value of length N and a for loop to iterate over all numbers [0 .. (2^N)-1].
user949300's solution is also very good, but it might not work in all languages.
Here's my solution(s), the recursive one is approximately twice as slow as the iterative one:
#include <stdio.h>
#ifdef RECURSIVE
void print_bin(int num, int len)
{
if(len == 0)
{
printf("\n");
return;
}
print_bin(num >> 1, len -1);
putchar((num & 1) + '0');
}
#else
void print_bin(int num, int len)
{
char str[len+1];
int i;
str[len] = '\0';
for (i = 0; i < len; i++)
{
str[len-1-i] = !!(num & (1 << i)) + '0';
}
printf("%s\n", str);
}
#endif
int main()
{
int len = 24;
int i;
int end = 1 << len;
for (i = 0; i < end ; i++)
{
print_bin(i, len);
}
return 0;
}
(I tried this myself on a Mac printing all binary numbers of length 24 and the terminal froze. But that is probably a poor terminal implementation. :-)
$ gcc -O3 binary.c ; time ./a.out > /dev/null ; gcc -O3 -DRECURSIVE binary.c ; time ./a.out > /dev/null
real 0m1.875s
user 0m1.859s
sys 0m0.008s
real 0m3.327s
user 0m3.310s
sys 0m0.010s
I don't think we need recursion or n nested for-loops to solve this problem. It would be easy to handle this using bit manipulation.
In C++, as an example:
for(int i=0;i<(1<<n);i++)
{
for(int j=0;j<n;j++)
if(i&(1<<j))
printf("1");
else
printf("0");
printf("\n");
}

Resources