- 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
assuming there are only two people (indices 0 and 1) and killing every third person the safe spot would be 1:
0 1 0 (kill)
people safespot 2 1
if you can't add the nth number to the safe spot without equaling or going over the total number of people you reset the safe spot to 0 or 1 depending on the outcome of the previous results difference as even or odd:
people = 2 safespot = 1 n = 3
for people = 3 1 + 3 >= 3 reset safe spot to 1 because (2-1)mod2 = 1 (odd)
so: people safespot 2 1 3 1
for people = 4 1 + 3 >= 4 (reset to 0) (3-1)mod2 = event
so: people safespot 2 1 3 1 4 0
for people = 5 0 + 3 = 3 (less than 5 so keep it)
people safespot 2 1 3 1 4 0 5 3
people = 6 3 + 3 >= 6 reset to 0 (5-3)mod2 = even
people safespot 2 1 3 1 4 0 5 3 6 0 7 3 8 6
6+3 >= 9... and so on
Admin
Kudos but screw you for putting that in my head now...
Admin
#include <stdio.h> #include <stdlib.h> int getLastStanding(int num, int step) { int i,j; for(i=1,j=0;i<=num;i++) {j+=step; if(j>=i) j%=i; } return j+1; }
int main(int argc, char *argv[]) { int num=41, step=3; if(argc>1) num=atoi(argv[1]); if(argc>2) step=atoi(argv[2]); printf("You want to be solder %d of %d for a step of %d\n",getLastStanding(num,step),num,step); return(0); }
The trick is that it is a step function which repeats when the total exceds N on a modulo basis...
Admin
That's easy to make iterative.
# Recursive sub J { my ($n, $k) = @_; return 0 if $n == 1; return ( J($n-1, $k) + $k ) % $n; } # Iterative sub J { my ($n, $k) = @_; my $j = 0; $j = ($j + $k) % $_ for 2..$n; return $j; }Admin
I love a good perl golf challenge!
perl -E '$k=pop;$s=($s+$k)%$_ for 1..pop;say$s+1' 12 3 10
39 characters between the quotes; 54 on the whole command line.
Admin
Since the sexy one-line mathematical solution has been exposed, I felt I had no other choice than going for the brain dead solution. But since my language of choice is Ruby, I'll also go for the iterator and a bit of "dynamycally modifying a core object class". Just for the fun of it.
#!/usr/bin/ruby class Array def kill!(i) count = 1 while self.size > 1 if count.modulo(i) == 0 yield self.shift else self << self.shift end count += 1 end end end ARGV.map! { |x| x.to_i } puts "Slaughtering #{ARGV[0]} soldiers, chopping one head every #{ARGV[1]}." print "Chopping head off of " soldiers = (1..ARGV[0]).to_a soldiers.kill!(3) { |dead_soldier| print dead_soldier, " " } puts puts "The last standing is #{soldiers[0]}."Code which gives...
Admin
Of course... that's 1-based. If you allow 0-based counting, it's two characters shorter.
Admin
to many posts to look through so I'm sorry if somebody already posted this but if you read the wiki on this there are two versions and each one comes up with a different answer!
Admin
Being the author of the linked solution, do I qualify for a TDWTF sticker? That'd be awesome!
[email protected]
Admin
Here's the fast way, in Java, based on the Wikipedia article Josephus problem:
public static int circleSurvivorRecursive(int men, int countTo) { return (men == 1) ? 0 : (circleSurvivorRecursive(men - 1, countTo) + countTo) % men; }Unfortunately, this is deficient, since it provides no means to identify the best place for the surviving accomplice. So I decided to go to the even more general function that determines the kill order. The requested survivor is, of course, the last man in the array (and his accomplice next to last):
public static int[] circleKillOrder(int men, int countTo) { boolean dead[] = new boolean[men]; int kills[] = new int[men]; int pos = men; for (int i=0; i < men; i++) { int steps = countTo; while (steps > 0) { pos = (pos + 1 >= men) ? 0 : pos + 1; if (!dead[pos]) steps--; } dead[pos] = true; kills[i] = pos; } return kills; }This next function then uses the above to determine the survival positions for any number of conspriators:
public static int[] circleConspiringSurvivors(int men, int countTo, int conspirators) { int kills[] = circleKillOrder(men,countTo); int where[] = new int[conspirators]; for (int i = 0; i < conspirators; i++) { where[i] = kills[--men]; } return where; }Finally, this next is the most useful function of all. It describes where to put the bright boy who had this stupid idea so he's the first to get the axe. Everyone else survives.
public static int whereToPutBrightBoy(int men, int countTo) { //return circleKillOrder(men,countTo)[0]; return (countTo + men - 1) % men; }Admin
Here's my python one-liner again :)
def joph(n): return int(bin(n)[2:][1:] + bin(n)[2:][0], 2)Hopefully the next 'praxis' won't be available in Concrete Mathematics ;)
Next challenge is trying it without it being solved with string manipulation.
Admin
Maybe he worked it out beforehand. Maybe it was his idea... if so, everyone else wound up with an earful of cider.
Admin
Admin
I wrote a weirdo erlang solution which I think works. I am a functional programming noob and I started looking at erlang yesterday.
Admin
Matlab, using inbuilt circular shift function:
function alive = josephus(n, k) alive =(1:n)'; shift = 1-k; for h = 1:(n-1) alive = circshift(alive, shift); alive(1) = []; endAdmin
When you remove the recursion from j(1,k) = 1 j(n,k) = (j(n-1,k)+k) mod n
its ( (k mod 2) + k ) mod 3 ) + k ) mod 4 ) ... ) + k mod n )
can that be further simplified ?
Admin
This version uses a form and posts the result back to the form.
Edit1 contains mans Edit2 contains mansToSkip Edit3 gets the result (base 1 result, base 0 calculations) Using an array and a I'm dead indicator (to lazy to use a boolean array)
procedure TForm1.Button1Click(Sender: TObject); var i, j, noMen, noMenToSkip: integer; circleRepresentation: array of integer; begin noMen := strToInt(edit1.text); noMenToSkip := strToInt(edit2.text); Edit3.text := ''; SetLength(circleRepresentation,noMen); i := 0; while noMen <> 1 do begin j := noMenToSkip; while j <> 0 do //steps to the next to die begin if circleRepresentation[i] = 0 then begin j := j-1; end; if j <> 0 then i := (i+1) mod length(circleRepresentation); end; circleRepresentation[i] := 1; //kill the current man that is alive noMen := noMen - 1; end; while circleRepresentation[i] = 1 do i := (i+1) mod length(circleRepresentation);//go to the last man alive Edit3.Text := intToStr(i + 1); end;Admin
AppleScript :
on run set num_soldiers to 0 repeat until num_soldiers is greater than 0 display dialog "Number of soldiers" default answer 12 set text_entered to text returned of the result try set num_soldiers to text_entered as integer end try end repeat set num_to_skip to 0 repeat until num_to_skip is greater than 0 display dialog "Soldiers to skip" default answer 3 set text_entered to text returned of the result try set num_to_skip to text_entered as integer end try end repeat display dialog "Result: " & Josephus(num_soldiers, num_to_skip) & " (from 0 to " & (num_soldiers - 1) & ")" buttons {"WTF?!"} default button 1 end run on Josephus(num, skip) if num is 1 then return 0 return (Josephus(num - 1, skip) + skip) mod num end JosephusAdmin
This doesn't seem to work if the answer is equal to the number of soldiers...
Admin
Same brute force, just using BitSet instead:
import java.util.BitSet; public final class JosephusCircle { public static void main(String[] args) { JosephusCircle c = new JosephusCircle(); c.bruteForce(12, 3); } private int bruteForce(int size, int numSkip) { BitSet s = new BitSet(size); int axeCounter = 1; while (s.cardinality() < size - 1) { for (int i = s.nextClearBit(0); i < size; i = s.nextClearBit(i + 1)) { if (0 == axeCounter % numSkip) { s.set(i); } ++axeCounter; } } int live = s.nextClearBit(0) + 1; System.out.println("When axing every " + numSkip + ", you want " + live + " of " + size); return live; } }Admin
My Perl-solution. No recusion, just one loop. But I have to confess it's not totally straight forward ;)
#/usr/bin/perl use strict; use warnings; if ((@ARGV != 2) || ($ARGV[0]!~m/[1-9]/) || ($ARGV[1]!~m/[1-9]/)) { print "Missing or wrong arguments! Need two integers\n"; exit(0); } my ($soldiers,$count_val)=@ARGV; my @survivors; my $initiate=1; my $died_this_round=0; for (my $i=0;(@survivors>1 || $initiate==1);(($i<$soldiers && $initiate==1)?($i++):($i+=$count_val))) { if ($i<$soldiers && $initiate==1) { $survivors[$i]=$i+1; } elsif ($i==$soldiers && $initiate==1) { $initiate=0; $i=0; } else { if ($i>(@survivors+$died_this_round)) { $i-=(@survivors+$died_this_round); $died_this_round=0; } my $delete; if ($i-$died_this_round-1>$#survivors) { $delete=$i-$died_this_round-@survivors-1; } else{ $delete=$i-$died_this_round-1; } splice(@survivors,$delete,1); $died_this_round++; } } print "Lucky one: $survivors[0]\n"; # perl Josephus.pl 12 3 Lucky one: 10Admin
public class DeathLinkage { static int _Soldiers; static int _Skip; int dead = 0; int index = 0; Person[] jews;
}
Admin
A perhaps not very clean but working solution in F#
(Just discovered F# while reading through the comments to the previous programming problem.)
Admin
This is probably a WTF solution in itself. I've purposely not checked other comments so as not to spoil it. Here's my solution in C#:
//assuming index 0 is top of circle public static int saveMe(int numOfSoldiers, int skip) {
Admin
Since 2 people have beaten me to it already....
unit Josephus;
interface uses Generics.Collections, SysUtils;
type BoolP = ^Boolean;
function GetJosephusLoc(Soldiers: Integer; Skip: Integer): Integer;
implementation
function GetJosephusLoc(Soldiers: Integer; Skip: Integer): Integer; var AliveList: TList<BoolP>; I: Integer; SkipI: Integer; Alive: BoolP; AliveCount: Integer; Found: Boolean; begin SkipI := 1; Found := False; AliveList := TList<BoolP>.Create(); for I := 1 to Soldiers do begin new(Alive); Alive^ := True; AliveList.Add(Alive); end; AliveList.TrimExcess; I:= 0; AliveCount := AliveList.Count; while AliveCount > 1 do begin if I = AliveList.Count then I := 0; Alive := AliveList[I]; if Alive^ then begin if SkipI = Skip then begin Alive^ := False; dec(AliveCount); SkipI := 1; end else inc(SkipI); end; inc(I) end; I:= 0; while (I < AliveList.Count) and (not Found) do begin Alive := AliveList[I]; if Alive^ then Found := True else inc(I); end; if Found then Result := I + 1 else I := -1;
for I := 0 to AliveList.Count - 1 do begin Alive := AliveList[0]; Dispose(Alive); AliveList.Delete(0); end; FreeAndNil(AliveList); end;
end.
Admin
To me, listening to static is indeed mysterious!
Admin
The index starting at 0. Seems i've been beaten to the short iterative answer but who cares :P
Admin
A brute force Python version...
menCount = 40 men = ["duck"] * menCount goose = 0
while men.count("goose") < menCount - 1: chopper = ["duck", "duck", "goose"] while chopper != [] and men.count("goose") < (menCount - 1): if men[goose] != "goose": men[goose] = chopper.pop(0) goose = (goose + 1) % menCount print men
print "Survivor: %s" %(men.index("duck") + 1)
Admin
I hate formatting issues... here's a brute-forced Python one:
menCount = 40 men = ["duck"] * menCount goose = 0 while men.count("goose") < menCount - 1: chopper = ["duck", "duck", "goose"] while chopper != [] and men.count("goose") < (menCount - 1): if men[goose] != "goose": men[goose] = chopper.pop(0) goose = (goose + 1) % menCount print men print "Survivor: %s" %(men.index("duck") + 1)Admin
Are we going to need a GodFactory, which returns an array of God pointers? Horrible pseudocode follows:
GodFactory.getGods(GodFactory.JEWISH) = [God] GodFactory.getGods(GodFactory.CHRISTIAN) = [God, God, God] GodFactory.getGods(GodFactory.ATHIEST) = null GodFactory.getGods(GodFactory.ROMAN) = [Zeus, ...] GodFactory.getGods(GodFactory.PASTAFARIAN) = [FSM]
and so on
Admin
Too much recursion in here for my taste.
Okay... first some ruby code (boring)
And here C with double linked list awesomeness:
#include <stdio.h> #include <stdlib.h> typedef struct circle_t { unsigned int nr; struct circle_t* next; struct circle_t* prev; } circle; void add(unsigned int nr, struct circle_t* prev) { struct circle_t* a; a=(struct circle_t*)malloc(sizeof(struct circle_t)); a->nr=nr; a->prev=prev; prev->next=a; } void del(struct circle_t* ptr) { ptr->prev->next=ptr->next; ptr->next->prev=ptr->prev; free(ptr); } unsigned int jc(unsigned int men, unsigned int skip) { struct circle_t* p; struct circle_t* start; start=malloc(sizeof(struct circle_t)); p=start; start->next=start; start->prev=start; start->nr=0; int i=1; int d=skip; while (i<men) { add(i,p); p=p->next; i++; } p->next=start; start->prev=p; p=start; while (p != p->prev) { d--; if (d==0) { printf("killed nr. %-4u\n",p->nr,p); p=p->next; del(p->prev); d=skip; } else { p=p->next; } } printf("\n\n"); return p->nr; } int main(int argc, char** argv) { if (argc < 3) { printf("usage: %s men skip\n",argv[0]); return 1; } printf("safe spot: %u\n",jc(atoi(argv[1]),atoi(argv[2]))); return 0; }Admin
The only way I can see for him to succeed in this is for him to have known about the arrangements before-hand so he could prepare. Let's assume that this method of surrender was discussed and agreed-upon before the battle. There would be no way to know how many soldiers were left, so he would have made up the same table we made earlier at the bottom of Page 1 of the comments. He could have memorized this, but could also have used the algorithm that many people here found (but I did not :( ) I am using the one quoted. The important line is "i = (i + k) % c;" This gives us a table that looks kind of like this: (1 + 3) % 2 (2 + 3) % 3 { 3 soldiers, stand at position 2} (2 + 3) % 4 (1 + 3) % 5 (4 + 3) % 6 { 6 soldiers, stand at position 1 } ... ...
Refer to the comment at the bottom of page 1 of comments for a bigger table. You can see that it resets to 1, 0( which becomes 2), or 2 every now and then. The series on the right climbs by 3 until it "catches up" to the series on the left. So you can jump from one reset straight to the next. (2 + 3) % 15 for 15 is one reset, the next is 6 steps up: (2 + 3 + (3 * 6)) % (15 + 6), or 23 % 21 for 21. This means that if there are 21 soldiers, he should stand as the second. The next jump takes you straight to (2 + 3 + (3 * 9)) % (22 + 9). This resets to 32 % 31 for 31 soldiers. You can now jump straight to (1 + 3 + (3 * 9)) % (32 + 9) which is 31 % 41 for 41 soldiers.
So as long as he remembered the resetting values i.e. 1 .. 7 1 .. 10 2 .. 15 2 .. 22 1 .. 32 2 .. 48, etc. he would be able to calculate the appropriate position in seconds. So for 41, he would know to use the entry corresponding to 32 since it is less than the next reset at 48. 41 - 32 = 9; and the position he needed to stand on would be (1 + 3) {corresponding to 32 in that table} added to 3 * 9. This would be 31.
Admin
Admin
Here's my solution in Matlab (only language I really know that well.): function safe_index = josephus(num_soldiers,num_skip)
survivor_mat=[];
for i=1:num_soldiers survivor_mat(i)=i;; end
count = 0; while length(survivor_mat) > 1 count = count + num_skip; while count > length(survivor_mat) count= count-length(survivor_mat); survivor_mat(survivor_mat == 0) = []; end if length(survivor_mat) > 1 survivor_mat(count)=0; end end safe_index = survivor_mat;
Admin
C#, using regex and strings - for fun.
private static int GetJosephusSafeSpot(int nSoliderCount, int nSkipValue) { var sbRegexSkips = new StringBuilder("L"); nSkipValue--; for (int i = 0; i < nSkipValue; i++) sbRegexSkips.Append("D*L"); Regex regKill = new Regex(sbRegexSkips.ToString(), RegexOptions.Compiled); string strCircleOfDeath = new string('L', nSoliderCount); int nIndex = 0; while (strCircleOfDeath.Substring(strCircleOfDeath.Length - nSoliderCount).Count(c => c == 'L') > 1) { Match match = regKill.Match(strCircleOfDeath, nIndex); strCircleOfDeath = regKill.Replace(strCircleOfDeath, m => { return m.Value.Remove(m.Value.Length - 1) + "D"; }, 1, nIndex); nIndex = match.Index+match.Value.Length; while (strCircleOfDeath.Substring(nIndex).Count(c => c == 'L') <= nSkipValue) strCircleOfDeath += strCircleOfDeath.Substring(strCircleOfDeath.Length - nSoliderCount); } return strCircleOfDeath.Substring(strCircleOfDeath.Length - nSoliderCount).LastIndexOf('L'); }Admin
Solution in F#:
let josephus numberOfMen skip = let men = [1..numberOfMen] let rec doTurn men position = match men with | hd :: [] -> hd | _ -> let newPosition = (position + skip) % men.Length doTurn (List.mapi (fun i man -> if i = newPosition then 0 else man) men |> List.filter(fun man -> man > 0)) (newPosition - 1) doTurn men -1Admin
OK, so here's another solution to the problem, this time in BabyTalk :
Josephus - Eenie Meenie Miiii...(skip himself)...iiiny Moe.
Admin
Here's a brute force solution in Java that I don't think anyone else has posted. It follows the problem description by treating a Vector as a circular buffer. Each vector element is the initial index of each soldier.
int josephus(Vector<Integer> v) { if (v.size() == 1) return v.elementAt(0).intValue(); v.add(v.remove(0)); v.add(v.remove(0)); v.remove(0); return josephus(v); }Admin
Admin
This is such a simple algorithm I am not sure how to make my solution THAT much more complicated. I did manage to use two subroutines, not counting josephus(), as well as recursion. And I broke LOTS of Perl Best Practices. Maybe tomorrow I'll try to figure this one out using only Regexes.
sub josephus { my ($circle, $skip) = @_; return 1 + calc_j(0, $skip, 0 .. $circle-1); } sub calc_j { sub array_except { my $except = pop @_; my @array = @_; splice @array, $except, 1; return @array; } ($idx, $skip, @array) = @_; return @array == 1 ? $array[0] : calc_j($new_idx=($idx+$skip-1) % @array, $skip, array_except(@array, $new_idx)); } print "josephus(12, 3) = ", josephus(12, 3), "\n";Admin
Zeus is Greek not Roman... that would be Jupiter
Admin
*v,n;main(s,f){for(n=1;atoi(1[v=f])-s;n=(n+atoi(2[v=f]))%++s);printf("%d\n",n);}
Admin
So 39 soldiers were done for, but Titus escaped.
All these comments, and not one pointing out the irony of using Python to show... erm... the Romans didn't do for Titus.
Admin
I'd say the safe spot is in the middle, as only the people in the circle get killed :P
Admin
Looking at the table of reset values idea that is discussed in earlier comments, I see that finding those helpful values is quite easy.
Pseudocode:
X is a placeholder for the last reset value, starts at 1 Y is a placeholder for what you have to reset to at X, starts at 0 function is called with variables S(oldiors) and C(ount)
-startloop distanceToNextX = ( (X-Y)/(C-1) rounded up )
if S is less than nextX return Y + (S-X)*c else X = nextX Y = (Y + (distance to next X * C)) mod x -endloop
Batch file:
@echo off rem - argument 1 is number of soldiers, argument 2 is the number to count to each time
call :josephus %1 %2
echo the servivor is at index %j%
exit /b
:josephus set s=%1 set c=%2 set x=1 set y=0
:loopbegin echo begin loop set /a z="(((2*(x-y))/(c-1))+1)/2" set /a xn="x+z" if %s% lss %xn% ( set /a j="y+((s-x)c)" ) else ( set x=%xn% set /a y="(y+(zc))%%x" goto :loopbegin )
exit /b
This algoritem is more efficient than any of the other looping or recursion alborithems I have seen implemented thus far. Even as a (ineficient) batch file it finds the servivor in a group of 32727 (#6132) in the blink of an eye while looping only two dozen times.
Trying that will overflow the stack on any of the recursive programs. Go ahead and try it with any of the other looping ones. I'll wait.
Admin
Monotheist, ey?
Admin
find and replace "servivor" with "survivor". How embarrassing.
Admin
I tried to go for good readability.
In Smalltalk, comments are delimited using double-quotes. Variables are declared between verticle bars. The caret returns a value from the method. Otherwise it's pretty much like Python, but with a built-in debugger.
Interestingly, if you want to give the survivors names, you can replace:
circle := OrderedCollection withAll: (1 to: n).
with:
circle := OrderedCollection withAll: #('Phillipus' 'Caesor' 'Nero' 'Josephus' 'Cactus').
and then this method will return the name of the survivor.
Admin
Really modeling the situation using Scheme message passsing OOP.
(define (make-person num) (let ((alive true) (next 'nobody)) (lambda (op) (cond ((eq? op 'alive?) alive) ((eq? op 'dead?) (not alive)) ((eq? op 'position) num) ((eq? op 'next) next) ((eq? op 'stand-next-to) (lambda (person) (set! next person))) ((eq? op 'kill) (if (not alive) (error "Cannot kill PERSON" num "-- already dead") (set! alive false))) (else (error "Unknown operation -- PERSON" num)))))) (define (make-circle n) (let ((first-person (make-person n))) (let iter ((n (- n 1)) (current-person first-person)) (if (zero? n) (begin ((first-person 'stand-next-to) current-person) current-person) (iter (- n 1) (let ((new-person (make-person n))) ((new-person 'stand-next-to) current-person) new-person)))))) (define (josephus n m) (define (skip-m-and-kill circleptr) (let iter ((i m) (cur-person circleptr)) (cond ((cur-person 'dead?) (iter i (cur-person 'next))) ((zero? i) (cur-person 'kill) cur-person) (else (iter (- i 1) (cur-person 'next)))))) (let ((circle (make-circle n))) (let iter ((number-alive n) (curpos circle)) (if (zero? number-alive) (curpos 'position) (iter (- number-alive 1) (skip-m-and-kill curpos))))))Admin
I tried to call GodFactory.getGods(GodFactory.AGNOSTIC), but the call keeps blocking.
Help?