Help:the problem of Ring of Josephus

Y

Yuri CHUANG

Hi,
I'm the beginner of the CPL.I write a program about the problem of Ring
of Josephus,using DoubleLinkList data structure.
I'm very confused that I think there is really no error in my
code.But,the compiler sometimes show some strange errors,sometimes can
pass through with an unknown trouble when it is running,and no
result.So,could anyone give me some help? Thank you very much!
Here is my code:
--------------------------------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>

typedef struct DuLNode
{
int data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode,*DuLinkList;

int ex_16(int *,int,int);

int main(int argc, char *argv[])
{
int a[]={1,2,3,4,5,6,7,8,9,10,11,12,-1};//use -1 as the flag of
ending of the array
int n=8,k=5;
printf("The last number is %d",ex_16(a,n,k));
return 0;
}

int ex_16(int *a,int n,int k)
{
DuLinkList L;
L=(DuLinkList)malloc(sizeof(DuLNode));
L->data=0;L->next=L;L->prior=L;//create the DuLinkList with the
head-node

int *p=a;
while(*p!=-1)
{
DuLinkList DL;
DL=(DuLinkList)malloc(sizeof(DuLNode));
DL->data=*p;
DL->prior=L->prior;L->prior->next=DL;
DL->next=L;L->prior=DL;
L->data++; //L->data is the length of the List exclude the
head-node
p++;
}//initiate the DuLinkList

DuLinkList q;int i,temp;

while(1)
{
if(L->next!=L)
{
q=L;
for(i=0;i<(n-1)%L->data;i++)
{
q=q->next;
temp=q->data;
}
q->prior->next=q->next;
q->next->prior=q->prior;
free(p);
L->data--;
}
else break;

if(L->prior!=L)
{
q=L;
for(i=0;i<(k-1)%L->data;i++)
{
q=q->prior;
temp=q->data;
}
q->prior->next=q->next;
q->next->prior=q->prior;
free(p);
L->data--;
}
else break;
}//delete the node which is at the point

return temp;
}//ex_16
 
R

Richard Heathfield

Yuri CHUANG said:
Hi,
I'm the beginner of the CPL.I write a program about the problem of Ring
of Josephus,using DoubleLinkList data structure.

That's probably a mistake right there. If you have a small amount of data,
an array will be just fine. For arbitrary amounts of data, Josephus is
probably better solved with a circular list rather than a linear one.
#include <stdio.h>
#include <stdlib.h>

typedef struct DuLNode
{
int data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode,*DuLinkList;

Hiding pointers in typedefs is always a bad idea. I'd much rather see a
function like DuLNode *addnode() than DuLinkList addnode() - it makes it
far clearer what's going on.
int ex_16(int *,int,int);

int main(int argc, char *argv[])
{
int a[]={1,2,3,4,5,6,7,8,9,10,11,12,-1};//use -1 as the flag of
ending of the array

Or simply calculate the number of elements in the array (it's equal to the
size of the array divided by the size of one member thereof), and then pass
this information to any function that needs it.
int n=8,k=5;
printf("The last number is %d",ex_16(a,n,k));
return 0;
}

int ex_16(int *a,int n,int k)
{
DuLinkList L;
L=(DuLinkList)malloc(sizeof(DuLNode));

The cast is meaningless. Fortunately, in your case, it doesn't conceal an
error - but it could have done. Much simpler: L = malloc(sizeof *L);

In the event that the allocation fails, by the way, your program heads off
into hyperspace. It doesn't just rely on the success of the allocation - it
/assumes/ the success of the allocation.
L->data=0;L->next=L;L->prior=L;//create the DuLinkList with the
head-node

For the second time, line-wrap makes a monkey of your comment syntax. The
old-fashioned /* comment style */ may be old-fashioned, but it is more
robust.

By the way, 0 isn't part of your input data, so why are you including it in
the list? As a node counter?

On the plus side, you're pointing L->next and L->prior at L, which makes me
think you did after all decide to go for circularity.
int *p=a;
while(*p!=-1)
{
DuLinkList DL;
DL=(DuLinkList)malloc(sizeof(DuLNode));

Why not just: DL = malloc(sizeof *DL);
DL->data=*p;
DL->prior=L->prior;L->prior->next=DL;
DL->next=L;L->prior=DL;

Yeah, that looks good so far.
L->data++; //L->data is the length of the List exclude the
head-node
p++;
}//initiate the DuLinkList

DuLinkList q;int i,temp;

Presumably you have a C99 compiler which understands all this mixed
declarations/code and //-style comment stuff? My compiler just calls them
syntax errors. In fact, all my compilers call them syntax errors.

Surely you mean while(I haven't yet solved the Josephus problem)?
{
if(L->next!=L)

....i.e. if the list is not empty apart from the head node

....point q to the head node
for(i=0;i<(n-1)%L->data;i++)
{
q=q->next;

....count n people round the ring...
temp=q->data;
}
q->prior->next=q->next;
q->next->prior=q->prior;
free(p);

p just points to your array, which you didn't malloc. You meant to free(q),
I think.
 
R

Rod Pemberton

Yuri CHUANG said:
Hi,
I'm the beginner of the CPL.I write a program about the problem of Ring
of Josephus,using DoubleLinkList data structure.
I'm very confused that I think there is really no error in my
code.But,the compiler sometimes show some strange errors,sometimes can
pass through with an unknown trouble when it is running,and no
result.So,could anyone give me some help? Thank you very much!
Here is my code:

I'd never heard of the "Ring of Josephus." So I looked it up.

For the actual "Ring of Josephus," n=13 and k=3. But, all rings stop on the
nth element. You have n=8, and k=5. Unfortunately, your ring won't stop on
the 8th element since the 13th element is -1, not the 8th. Also, you need
the nth element in the array, i.e., 13 is missing for n=13. You may want to
setup 'a' as a pointer, malloc() the space for it, and then fill it with 1
through n and -1.


Rod Pemberton
 
Y

Yuri CHUANG

Well,it's question in my Chinese book,maybe there are translated
problems.
So,I describe it as follows:
There are integers from 1 to m,forming a circle.The number 1 is the
head.Delete the nth number in one direction,then delete the kth number
in the other,until there is only one number left.Print the last number.
e.g. n=12,m=8,k=5
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 9 10 11 12 //delete 8
1 2 3 4 5 6 9 10 11 12 //delete 7
1 2 3 4 5 6 9 11 12 //delete 10(8th location)
.....
1 4 6 9 11
4 6 9 11
4 6 9
4 9
4
so the result is 4.
The critical problem of my code is that I couldn't get any answer,even
error one.I think there must be wrong use of malloc function.
Give me some help,please.
Thanks a lot.
 
Y

Yuri CHUANG

Well,it's question in my Chinese book,maybe there are translated
problems.
So,I describe it as follows:
There are integers from 1 to m,forming a circle.The number 1 is the
head.Delete the nth number in one direction,then delete the kth number
in the other,until there is only one number left.Print the last number.
e.g. n=12,m=8,k=5
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 9 10 11 12 //delete 8
1 2 3 4 5 6 9 10 11 12 //delete 7
1 2 3 4 5 6 9 11 12 //delete 10(8th location)
.....
1 4 6 9 11
4 6 9 11
4 6 9
4 9
4
so the result is 4.
The critical problem of my code is that I couldn't get any answer,even
error one.I think there must be wrong use of malloc function.
Give me some help,please.
Thanks a lot.
 
Y

Yuri CHUANG

Well,it's question in my Chinese book,maybe there are translated
problems.
So,I describe it as follows:
There are integers from 1 to m,forming a circle.The number 1 is the
head.Delete the nth number in one direction,then delete the kth number
in the other,until there is only one number left.Print the last number.
e.g. n=12,m=8,k=5
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 9 10 11 12 //delete 8
1 2 3 4 5 6 9 10 11 12 //delete 7
1 2 3 4 5 6 9 11 12 //delete 10(8th location)
.....
1 4 6 9 11
4 6 9 11
4 6 9
4 9
4
so the result is 4.
The critical problem of my code is that I couldn't get any answer,even
error one.I think there must be wrong use of malloc function.
Give me some help,please.
Thanks a lot.
 
R

Rod Pemberton

Yuri CHUANG said:
Well,it's question in my Chinese book,maybe there are translated
problems.
So,I describe it as follows:
There are integers from 1 to m,forming a circle.The number 1 is the
head.Delete the nth number in one direction,then delete the kth number
in the other,until there is only one number left.Print the last number.
e.g. n=12,m=8,k=5
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 9 10 11 12 //delete 8
1 2 3 4 5 6 9 10 11 12 //delete 7
1 2 3 4 5 6 9 11 12 //delete 10(8th location)
....
1 4 6 9 11
4 6 9 11
4 6 9
4 9
4
so the result is 4.
The critical problem of my code is that I couldn't get any answer,even
error one.I think there must be wrong use of malloc function.

The problem is too simple to use linked lists. This codes solves the
specific problem shown.


#include <stdio.h>
#include <stdlib.h>

typedef struct
{
int value;
int flag;
} ring_el;

int main(void)
{
ring_el *ring;
int n,m,k;
signed int x,y,z;
int t;

n=12;
m=8;
k=5;

ring=malloc(n*sizeof(ring_el));

for(x=0;x<n;x++)
{
ring[x].value=x+1;
ring[x].flag=1;
}
for(y=0;y<(n-1);)
{
for(x=0,z=0;x<m;)
{
if (ring[z].flag==1)
{
x++;
z++;
if(x>=n)
x=0;
if(z>=n)
z=0;

}
else
{
z++;
if(z>=n)
z=0;
}
}
y++;
if(y>(n-1))
break;
z--;
if(z<0)
z=n-1;
ring[z].flag=0;
for(t=0;t<n;t++)
if(ring[t].flag)
printf("%2d ",ring[t].value);
else
printf(" . ");
printf("\n");
for(x=n-1,z=n-1;x>=(n-k);)
{
if (ring[z].flag==1)
{
x--;
z--;
if(x<0)
x=n-1;
if(z<0)
z=n-1;
}
else
{
z--;
if(z<0)
z=n-1;
}
}
y++;
if(y>(n-1))
break;
z++;
if(z>=n)
z=0;
ring[z].flag=0;
for(t=0;t<n;t++)
if(ring[t].flag)
printf("%2d ",ring[t].value);
else
printf(" . ");
printf("\n");
}
for(x=0;x<n;x++)
{
if(ring[x].flag)
printf("Answer:%d",ring[x].value);
}

exit(EXIT_SUCCESS);
}


Rod Pemberton
 
C

Chad

The problem is too simple to use linked lists. This codes solves the
specific problem shown.


#include <stdio.h>
#include <stdlib.h>

typedef struct
{
int value;
int flag;
} ring_el;

int main(void)
{
ring_el *ring;
int n,m,k;
signed int x,y,z;
int t;

n=12;
m=8;
k=5;

Couldn't you have also gone like
int n = 12;
int m = 8;
int k = 5;
ring=malloc(n*sizeof(ring_el));

Why don't we check malloc() for NULL? Is malloc() this special when it
comes to the Ring of Josephus
for(x=0;x<n;x++)
{
ring[x].value=x+1;
ring[x].flag=1;
}
for(y=0;y<(n-1);)
{
for(x=0,z=0;x<m;)
{
if (ring[z].flag==1)
{
x++;
z++;
if(x>=n)
x=0;
if(z>=n)
z=0;

}
else
{
z++;
if(z>=n)
z=0;
}
}
y++;
if(y>(n-1))
break;
z--;
if(z<0)
z=n-1;
ring[z].flag=0;
for(t=0;t<n;t++)
if(ring[t].flag)
printf("%2d ",ring[t].value);
else
printf(" . ");
printf("\n");
for(x=n-1,z=n-1;x>=(n-k);)
{
if (ring[z].flag==1)
{
x--;
z--;
if(x<0)
x=n-1;
if(z<0)
z=n-1;
}
else
{
z--;
if(z<0)
z=n-1;
}
}
y++;
if(y>(n-1))
break;
z++;
if(z>=n)
z=0;
ring[z].flag=0;
for(t=0;t<n;t++)
if(ring[t].flag)
printf("%2d ",ring[t].value);
else
printf(" . ");
printf("\n");
}
for(x=0;x<n;x++)
{
if(ring[x].flag)
printf("Answer:%d",ring[x].value);
}

exit(EXIT_SUCCESS);
}

Where is free()? Is the function off having an affair with teacher in
comp.lang.c++ ?
Rod Pemberton

Ohh..... my aching hips.
 
R

Rod Pemberton

Couldn't you have also gone like
int n = 12;
int m = 8;
int k = 5;

Yes. I could have. I could have also done this:
int n=12,m=8,k=5;

I specifically placed them in the open. It's very likely he'll replace them
with a scanf() etc.
Why don't we check malloc() for NULL? Is malloc() this special when it
comes to the Ring of Josephus

Do you _honestly_ think that malloc() will fail to provide 32 bytes? 4Kb?
64Kb? on any modern computer, miniframe or mainframe?

Do you _honestly_ think that he'll be running a 64Gb "Ring of Josephus"? In
that case, he'd definately want a linked-list.
Where is free()? Is the function off having an affair with teacher in
comp.lang.c++ ?

You don't understand what exit() must do to interface properly with an OS.

The two important lines from the spec:
"The exit function causes normal program termination to occur."
"Finally, control is returned to the host environment."

Returning resources to an OS, such as deallocation of the memory allocated
by a program, is a mandatory part of the host OS's "normal program
termination" and "control ...[being] returned to the host environment."
Without it, the OS would run out of memory... Since all successful OS's
where partly developed or influenced heavily by EE's, I doubt that there is
a 'stupid' OS which doesn't deallocate memory.


Stop being inane.


Rod Pemberton
 
F

Flash Gordon

Rod said:
Do you _honestly_ think that malloc() will fail to provide 32 bytes? 4Kb?
64Kb? on any modern computer, miniframe or mainframe?

Do you _honestly_ think that he'll be running a 64Gb "Ring of Josephus"? In
that case, he'd definately want a linked-list.

Do you honestly think that people never run out of virtual memory? If
so, I've got news for you. I've *seen* modern PCs run out of both real
and virtual memory. Obviously this means the PC is not up to spec for
what it is being asked to do, but that does not alter the fact that it
*does* happen, and when a machine is out of memory it can fail to
allocate *one* byte because there is *no* memory available.

The two important lines from the spec:
"The exit function causes normal program termination to occur."
"Finally, control is returned to the host environment."

Returning resources to an OS, such as deallocation of the memory allocated
by a program, is a mandatory part of the host OS's "normal program
termination" and "control ...[being] returned to the host environment."

Not as far as C is concerned it isn't. The C standard does not care what
happens to the system after the program has terminated.
Without it, the OS would run out of memory... Since all successful OS's
where partly developed or influenced heavily by EE's, I doubt that there is
a 'stupid' OS which doesn't deallocate memory.

People still use DOS and that is pretty stupid. Although I don't know if
it has this specific problem.
 
F

Flash Gordon

Richard said:
Flash Gordon said:


Presumably you are referring to MS-DOS.

Or IBM-DOS or Caldera-DOS, or...

In fact, Caldera-DOS seems to be common for bootable BIOS upgrade floppies.
Not if it meets their needs better than the alternatives.

I meant that the OS is pretty stupid, not the decision to use it.
 
N

Nelu

Rod said:
Do you _honestly_ think that malloc() will fail to provide 32 bytes? 4Kb?
64Kb? on any modern computer, miniframe or mainframe?

Do you _honestly_ think that he'll be running a 64Gb "Ring of Josephus"? In
that case, he'd definately want a linked-list.


You don't understand what exit() must do to interface properly with an OS.


The two important lines from the spec:
<snip>

Whether or not the OS knows how to cleanup after a program terminates
is not important here. What is important is that if you allocate
something you need to do the cleanup yourself. It's unlikely that the
OP will use this program for things other than learning, but he must
know that he has to check for errors and do the cleanup. Let's say he
will write a program that does a lot of memory allocations and he will
consider that it will all be deallocated at exit. What if his program
is supposed to run for a long period of time and call malloc a lot? It
will run out of memory because he's not freeing it and malloc will
eventually fail and he won't know it. If you want to help do it
properly even in small example programs.
 
C

CBFalconer

Flash said:
Or IBM-DOS or Caldera-DOS, or...

In fact, Caldera-DOS seems to be common for bootable BIOS upgrade
floppies.


I meant that the OS is pretty stupid, not the decision to use it.

Presumably you consider a snow shovel a stupid tool, when you can
use a snowblower with a 10 HP engine instead. I, for one, run
stupid DOS programs every day, many of which are twenty years old.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
D

David Holland

> Do you _honestly_ think that malloc() will fail to provide 32 bytes? 4Kb?
> 64Kb? on any modern computer, miniframe or mainframe?

As has already been explained, no matter how much storage you have on
your machine, you can still run out.
> Returning resources to an OS, such as deallocation of the memory allocated
> by a program, is a mandatory part of the host OS's "normal program
> termination" and "control ...[being] returned to the host environment."
> Without it, the OS would run out of memory... Since all successful OS's
> where partly developed or influenced heavily by EE's, I doubt that there is
> a 'stupid' OS which doesn't deallocate memory.

No, the OS will only run out of memory if the programs you run on it
fail to release the resources they have allocated and otherwise
generally restore the state of the operating environment.

Many OSes run miscellaneous programs in sandboxes that can be cleaned
up automatically, because the OS's trust model requires it. However,
it's far from universal, nor is the cleanup necessarily complete.

<OT> Even in Unix it's possible to make a mess by failing to clean
certain things up if you've been fiddling with them. </OT>

It is good practice to pick up after yourself, and not go through life
trailing a stream of candy bar wrappers and used tissues behind you.
> Stop being inane.

Indeed.
 
F

Flash Gordon

CBFalconer said:
Presumably you consider a snow shovel a stupid tool, when you can
use a snowblower with a 10 HP engine instead. I, for one, run
stupid DOS programs every day, many of which are twenty years old.

This isn't an advocacy group, so I'm going to stop discussing this.
 
R

Richard Heathfield

Flash Gordon said:
This isn't an advocacy group, so I'm going to stop discussing this.

Since you know this isn't an advocacy group, it may have been better not to
launch an attack on DOS in the first place.

Incidentally, the term "DOS" was first used a long time before the PC was a
twinkle in IBM's eye. If you'd spent so much on your IBM 360 mainframe that
you were a bit strapped for operating system cash, you went for DOS rather
than OS. (Nothing to do with Tim Patterson's CP/M clone, of course. That
came about 15 years later.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,997
Latest member
mileyka

Latest Threads

Top