- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
hero!
Admin
This simplifies to just
def J(n,k): return n!=1 and (J(n-1,k)+k)%n
Admin
Also +1 internets for Dave. Made me laugh.
Admin
d3matt: I've got a billion or so Hindus on the phone who don't agree
Admin
As I posted earlier its just (n is number of soldiers and k the number of skips):
1 + (n-1)k mod n
Admin
python one-liner, 1-based index using skips and not counts:
Admin
Hooray for "Scheme"
Admin
Like the braindead PHP solution, here's a rather braindead Perl solution.
Admin
Perl Golf'd:
$p[$-1]=$ for 1..$ARGV[0];splice@p,$k=($k+$ARGV[1]-1)%@p,1while@p>1;print@p
77 chars :-)
Admin
Java! There are of course more elegant ways to do this, but that would be defeating the purpose.
public class JosephusCircle {
}
Admin
Congratulations to everyone that found the very elegant solution outlined on wikipedia...
http://en.wikipedia.org/wiki/Josephus_problem
When the optimal solution for a problem for a solution gets regurgitated in less than 30 minutes, it might be a sign that you need a more unique problem to solve.
How about next week we try to find a solution to the infamous TOWER OF HANOI problem or how to find the factorial of a number!
Admin
Code in Python Instead of looking for a mathematical solution (Like Alex Mont did, I loved that solution) I opted for a more simple straightforward simulation of the process of picking.
(The solution given by this is the index of the array, thus the "real position" will be the return of the resolve function + 1)
Admin
using (5,1) we should get 3, but with your shortcut you get
Admin
A missing point of the article: The reason for such a procedure is because in the Jewish religion it is not permitted to commit suicide.
There is a story in which an entire Jewish town was about to be captured, so it was decided that the head of the family will use a knife to slay each of his family members, then all the remaining men would kill each other, but never themselves. They would take responsibility for committing murder and suffer in the afterlife as a compassion gift to their families for not having to commit suicide nor having to suffer slavery. However there was no such circle, the men would instead kill each other with the last two killing each other simultaneously.
So yea, otherwise they would all just slit their own throats.
Ok back to the programming exercise.
Admin
This should work, even with bugs ;) (cpp)
Admin
Naïve C# implementation:
Admin
You're referring to the siege of masada.
Admin
BTW, I love Josephus' books... and I think he actually only wrote those two (and Against the Greeks), and The Antiquities are almost identical to the Wars, IIRC.
Admin
Javascript solution:
// brute force method function josephus1(count, seed) { var men = new Array(count); var dead = 0; var index = 0; var passes = 0;
// 1. Loop through an array of men who's values are initially set to false to indicate they are not dead. for (var i = 0; i < count; i++) { men[i] = false; }
// 2. Keep counting men if they are not already dead and killing them if they are the nth man until the number of dead is one less than the total dead. while (dead < count - 1) { if (men[index] == false) { passes = passes >= seed ? 1 : passes + 1;
}
// 3. Return the last man standing by looping through the array of men and finding the one who is not dead for (var i = 0; i < count; i++) { // if the man has not been killed return his index plus one to indicate his position (to account for zero based arrays) if (!men[i]) return i + 1; } }
// an improved version which removes the array elements completely so we don't continually count dead men function josephus2(count, seed) { var men = new Array(count); var index = 0; var passes = 0;
// initialize the men to their position in the circle for (var i = 0; i < count; i++) { men[i] = i + 1; }
// keep killing the nth man by removing him from the array until there is only 1 man left while (men.length > 1) { passes = passes >= seed ? 1 : passes + 1; if (passes % seed == 0) { men.splice(index, 1); if (index >= men.length) index = 0; } else { index = index >= men.length - 1 ? 0 : index + 1; } }
// return the last man standing's position return men[0]; }
Admin
Admin
My own attempt at golfing this (subroutine):
40 chars. I use $_+indexes and two pops at the end because that ends up being 2 chars less than initialising $a and $b from @_ (which would have to be "my($a,$b)=@_;" <- 13 chars.) "[0][0][1]pp" (the additional chars needed to avoid initialising the vars) is just 11 chars.The mandatory one-liner (true one-liner, no semicolons)
59 chars + args.Indexed from 0. I'm certain it's possible to golf this further, though, I don't like this solution...and I'm loving those little challenges :).
Admin
The obvious solution is tell everybody else that you just need to take a quick bathroom break and they should start without you.
Admin
No it is 5 not 3 ... you fail ...
{1,2,3,4,5} => {2,3,4,5} => ... => {5}
Admin
Here's a straight forward solution in PHP. Not really a function but can be easily converted into one.
No recursivity, with 1000 soldiers or something like that PHP would probably crap out.
Admin
The shortcut, according to Josephus himself, was luck (or the hand of God). Besides, if he hadn't been the last man (or rather one of the last two) men standing, he wouldn't have been able to write about it later.
Admin
But you do realize that in order to do that you need 'The infinite improbability drive' which incidentally requires a good hot cup of tea.
But to get a good hot cup of tea is in my experience impossible, had it been coffee, then it could be done... -)
Yours Yazeran
Plan: To go to Mars one dya with a hammer
Admin
I think the disagreement is on the meaning of the 1 in 5,1. Does it mean you skip 1, or skip 0. What you have shown is skip 0, in which case you just kill 1 then 2 then 3, etc. If you skip one, you kill 2, then (skip 3) 4, then 1 (skip 5), then 5 (skip 3) leaving 3 alive. {1,2,3,4,5} => {1,3,4,5} => {1,3,5} => {3,5} => {3}
Admin
Since the recursive solution has been done quite a bit...I thought something more interesting was in order:
Admin
Yes indeed. k = 1 means "first one I point at gets the fraking axe" :) So... 1 + (n-1)k mod n
Admin
Javascript -- Trial 1
Yay! <-- apparently this allows me to submit :)
Edit: The index returned is zero-based. Add 1 to it if you want a 1-based index.
Admin
Admin
So, if you want the second letter to be the number of skips, modify the algorithm to: 1 + (n-1)(k-1) mod n
Admin
He actually wrote "Teach yourself recursion in VB.Net in 10 days", did you know?
So the "somehow managed to figure out" is a red herring???
Er... nope, it doesn't work:
33 soldiers: (1 + (33-1) * 3) mod 33 = 31 instead of 7.
Admin
From where did you get that 860 iterations?
Admin
I am taking the Schroedinger approach - instead of using an axe, have everyone climb into a box with a bottle of poison. At that point, everyone is both alive and dead. Thus, the suicide is successful (each person is dead), but our hero has survived (he is alive).
Admin
A brute force, linked-list-traversal method for the HP 48:
(Replace != with the built-in not-equals symbol.)
Admin
static int counter;
int Josephus(int n, int k) counter++; ...
Admin
In Python:
def noKill(people, skip=3): people = range(1,people + 1) skipped = 0 current = -1 while len(people) > 1: skipped += 1 current += 1 if current == len(people): current = 0 pass
if skipped == skip: print 'killing %s' % (people.pop(current)) skipped = 0 current -= 1 return people.pop()
Admin
def josephus(soliders, skip): soliders = range(1, soliders + 1) iterations = range(1, len(soliders) * skip) counter = 1 killed = 0 for i in iterations: for n in soliders: if n != 0: if counter == skip: if killed == len(soliders) - 1: return n soliders[soliders.index(n)] = 0 killed += 1 counter = 1 else: counter += 1
print josephus(41, 3)
Admin
Say we skip skip soldiers, and have num soldiers in the circle. If skip and num are coprime, then the consecutive sums will be unique, and will eventually get back to num. Thus, -1*skip mod num is the safe spot.
If they are not coprime, then there are lots of safe spots. Find their gcd, and add 1.
Admin
#!/usr/bin/perl
$k = 3; @a=(1..40); @a = grep { ++$x % $k } @a while $#a print @a, "\n";
Admin
Tabbing fail. Again, in Python:
Admin
A terrible, but working solution (more or less) in Java. The test to see if a location is safe is accomplished by running the process until that location is killed. Positions are randomly selected for testing until the safe one is found. Positions can be tested more than once. Emphasis has been placed on writing naive and poorly performing code without going overboard on obscurity.
Admin
Have you tested it?
Because I think I'm not getting the right answers from it. My own version before looking at the comments was:
def joe3(n, k): x = 0 for i in range(2, n+1): x = (x + k) % i return x
Which does seem to work. (0-indexed) I tried to eliminate more, but the lower modulos are apparently necessary.
Admin
I am humbled that the great Ben Forta visits this site. In fact, I always feel like bowing when I see or hear his name! You the man Ben!!!
Admin
33 soldiers, interval 2 (equivalent to killEveryKth 3) = 1+(33-1)(2-1) mod 33 = 0 instead of 7.
Admin
Numbering the top position as zero, in 'C': int Safe(int Soldiers, int Skip) { if (Soldiers == 1) return 0 ;
return (Safe(Soldiers - 1, Skip) + Skip) % Soldiers ; }
Admin
In php:
<?php function LifePosition($indexCount=41, $skipCount=3) { /** * Josephus' Circle calculation function * Written to identify the array index that will be selected * last in a sequence with (x) indices and (y) skip count * @author: Akoi Meexx <[email protected]> * * @attrib: http://thedailywtf.com/Articles/Programming-Praxis-Josephus-Circle.aspx */ $roulette = array_fill(1, $indexCount, 'Alive'); $increment = 1; while(count($roulette) > 1) { foreach($roulette as $arrayIndex=>$value) { if($increment == $skipCount) { unset($roulette[$value]); $increment = 1; } $increment++; } } print_r($roulette); } ?>Admin
Um, you're doing it wrong.. if you have 5 soldiers and kill every other one (not the first one in every round) you get:
{1,2,3,4,5} {1,3,5} {3}
Admin
skip = 3, soldiers = 11 (coprimes). -1*3 mod 11 = -3 on the windows calculator, although I remember the modding of negative numbers being still under debate (please do not bait...). No -3 spot.
Not coprime, skip = 3, soldiers = 18, gcd = 3, gcd + 1 = 4 instead of 14. Doesn't work either.