This commit is contained in:
Ingy döt Net 2013-06-05 21:47:54 +00:00
parent 1f1ad49427
commit 6f050a029e
2496 changed files with 37609 additions and 3031 deletions

View file

@ -0,0 +1,77 @@
#include <iostream>
#include <vector>
//--------------------------------------------------------------------------------------------------
using namespace std;
typedef unsigned long long bigint;
//--------------------------------------------------------------------------------------------------
class josephus
{
public:
bigint findSurvivors( bigint n, bigint k, bigint s = 0 )
{
bigint i = s + 1;
for( bigint x = i; x <= n; x++, i++ )
s = ( s + k ) % i;
return s;
}
void getExecutionList( bigint n, bigint k, bigint s = 1 )
{
cout << endl << endl << "Execution list: " << endl;
prisoners.clear();
for( bigint x = 0; x < n; x++ )
prisoners.push_back( x );
bigint index = 0;
while( prisoners.size() > s )
{
index += k - 1;
if( index >= prisoners.size() ) index %= prisoners.size();
cout << prisoners[static_cast<unsigned int>( index )] << ", ";
vector<bigint>::iterator it = prisoners.begin() + static_cast<unsigned int>( index );
prisoners.erase( it );
}
}
private:
vector<bigint> prisoners;
};
//--------------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
josephus jo;
bigint n, k, s;
while( true )
{
system( "cls" );
cout << "Number of prisoners( 0 to QUIT ): "; cin >> n;
if( !n ) return 0;
cout << "Execution step: "; cin >> k;
cout << "How many survivors: "; cin >> s;
cout << endl << "Survivor";
if( s == 1 )
{
cout << ": " << jo.findSurvivors( n, k );
jo.getExecutionList( n, k );
}
else
{
cout << "s: ";
for( bigint x = 0; x < s; x++ )
cout << jo.findSurvivors( n, k, x ) << ", ";
jo.getExecutionList( n, k, s );
}
cout << endl << endl;
system( "pause" );
}
return 0;
}
//--------------------------------------------------------------------------------------------------

View file

@ -8,7 +8,7 @@ T pop(T)(ref T[] items, in size_t i) pure {
}
string josephus(in int n, in int k) {
auto p = iota(n).array();
auto p = n.iota.array;
int i;
int[] seq;
while (!p.empty) {
@ -16,12 +16,13 @@ string josephus(in int n, in int k) {
seq ~= p.pop(i);
}
return xformat("Prisoner killing order: %(%d, %).\nSurvivor: %d",
seq[0 .. $-1], seq[$ - 1]);
return format("Prisoner killing order:\n%(%(%d %)\n%)." ~
"\nSurvivor: %d",
std.range.chunks(seq[0 .. $ - 1], 20), seq[$ - 1]);
}
void main() {
writeln(josephus(5, 2));
writeln();
writeln(josephus(41, 3));
josephus(5, 2).writeln;
writeln;
josephus(41, 3).writeln;
}

View file

@ -0,0 +1,5 @@
USING: kernel locals math math.ranges sequences ;
IN: josephus
:: josephus ( k n -- m )
n [1,b] 0 [ [ k + ] dip mod ] reduce ;

View file

@ -0,0 +1,22 @@
program josephus
implicit none
integer :: n, i, k, p
integer, allocatable :: next(:)
read *, n, k
allocate(next(0:n - 1))
do i = 0, n - 2
next(i) = i + 1
end do
next(n - 1) = 0
p = 0
do while(next(p) /= p)
do i = 1, k - 2
p = next(p)
end do
print *, "Kill", next(p)
next(p) = next(next(p))
p = next(p)
end do
print *, "Alive", p
deallocate(next)
end program

View file

@ -0,0 +1,40 @@
import Data.List ((\\))
import System.Environment (getArgs)
prisoners :: Int -> [Int]
prisoners n = [0 .. n - 1]
counter :: Int -> [Int]
counter k = cycle [k, k-1 .. 1]
killList :: [Int] -> [Int] -> ([Int], [Int], [Int])
killList xs cs = (killed, survivors, newCs)
where
(killed, newCs) = kill xs cs []
survivors = xs \\ killed
kill [] cs rs = (rs, cs)
kill (x:xs) (c:cs) rs
| c == 1 =
let ts = rs ++ [x]
in kill xs cs ts
| otherwise =
kill xs cs rs
killRecursive :: [Int] -> [Int] -> Int -> ([Int], [Int])
killRecursive xs cs m = killR ([], xs, cs)
where
killR (killed, remaining, counter)
| length remaining <= m = (killed, remaining)
| otherwise =
let (newKilled, newRemaining, newCounter) =
killList remaining counter
allKilled = killed ++ newKilled
in killR (allKilled, newRemaining, newCounter)
main :: IO ()
main = do
args <- getArgs
case args of
[n, k, m] -> print $ snd $ killRecursive (prisoners (read n))
(counter (read k)) (read m)
_ -> print $ snd $ killRecursive (prisoners 41) (counter 3) 1

View file

@ -0,0 +1,11 @@
jseq n k = f n [1 .. n] where
f 0 _ = []
f m s = x:f (m-1) (right ++ left) where
(left,x:right) = splitAt ((k-1) `mod` m) s
-- the final survivor is ((k + ...((k + ((k + 0)`mod` 1)) `mod` 2) ... ) `mod` n)
jos n k = 1 + foldl (\x->((k+x)`mod`)) 0 [2..n]
main = do
print $ jseq 41 3
print $ jos 10000 100

View file

@ -0,0 +1,2 @@
3 ([ (1 }. <:@[ |. ])^:(1 < #@])^:_ i.@]) 41
30

View file

@ -0,0 +1,7 @@
DropNext=. 1 }. <:@[ |. ]
MoreThanOne=. 1 < #@]
WhileMoreThanOne=. (^:MoreThanOne f.) (^:_)
prisoners=. i.@]
[ DropNext WhileMoreThanOne prisoners f.
[ (1 }. <:@[ |. ])^:(1 < #@])^:_ i.@]

View file

@ -0,0 +1,15 @@
Josephus =: dyad define NB. explicit form, assume executioner starts at position 0
NB. use: SKIP josephus NUMBER_OF_PRISONERS
N =: y
K =: N | x
EXECUTIONER =: 0
PRISONERS =: i. N
kill =: ] #~ (~: ([: i. #))
while. 1 (< #) PRISONERS do.
EXECUTIONER =: (# PRISONERS) | <: K + EXECUTIONER
PRISONERS =: EXECUTIONER kill PRISONERS
end.
)
3 Josephus 41
30

View file

@ -0,0 +1,4 @@
Josephus2 =: 4 : '(|x&+)/i.->:y' NB. this is a direct translation of the algo from C code above.
3 Josephus2 41
30

View file

@ -0,0 +1,50 @@
class Josephus {
function : Execute(n : Int, k : Int) ~ Int {
killIdx := 0;
prisoners := Collection.IntVector->New();
for(i := 0;i < n;i+=1;){
prisoners->AddBack(i);
};
"Prisoners executed in order:"->PrintLine();
while(prisoners->Size() > 1){
killIdx := (killIdx + k - 1) % prisoners->Size();
executed := prisoners->Get(killIdx);
"{$executed} "->Print();
prisoners->Remove(killIdx);
};
'\n'->Print();
return prisoners->Get(0);
}
function : ExecuteAllButM(n : Int, k : Int, m : Int) ~ Collection.IntVector {
killIdx := 0;
prisoners := Collection.IntVector->New();
for(i := 0;i < n;i+=1;){
prisoners->AddBack(i);
};
"Prisoners executed in order:"->PrintLine();
while(prisoners->Size() > m){
killIdx := (killIdx + k - 1) % prisoners->Size();
executed := prisoners->Get(killIdx);
"{$executed} "->Print();
prisoners->Remove(killIdx);
};
'\n'->Print();
return prisoners;
}
function : Main(args : String[]) ~ Nil {
result := Execute(41, 3);
"Survivor: {$result}"->PrintLine();
results := ExecuteAllButM(41, 3, 3);
"Survivors: "->Print();
each(i : results) {
results->Get(i)->Print();
if(i + 1 < results->Size()) {
' '->Print();
};
};
}
}

View file

@ -0,0 +1,8 @@
jose <-function(s, r,n){
y <- 0:(r-1)
for (i in (r+1):n)
y <- (y + s) %% i
return(y)
}
> jose(3,1,41) # r is the number of remained prisoner.
[1] 30

View file

@ -2,12 +2,25 @@
* 15.11.2012 Walter Pachl - my own solution
* 16.11.2012 Walter Pachl generalized n prisoners + w killing distance
* and s=number of survivors
* 09.05.2013 Walter Pachl accept arguments n w s and fix output
* thanks for the review/test
* I see no need for specifying a start count (actually a start number)
* This program should work on EVERY REXX.
* Pls report if this is not the case and let us know what's a problem.
**********************************************************************/
Parse Arg n w s .
If n='?' Then Do
Say 'Invoke the program with the following arguments:'
Say 'n number of prisoners (default 41)'
Say 'w killing count (default 3)'
Say 's number of prisoners to survive (default 1)'
Exit
End
If n='' Then n=41 /* number of alive prisoners */
If w='' Then w=3 /* killing count */
If s='' Then s=1 /* nuber of survivors */
dead.=0 /* nobody's dead yet */
n=41 /* number of alive prisoners */
nn=n /* wrap around boundary */
w=3 /* killing count */
s=1 /* nuber of survivors */
p=-1 /* start here */
killed='' /* output of killings */
Do until n=s /* until one alive prisoner */
@ -19,12 +32,15 @@ Do until n=s /* until one alive prisoner */
found=found+1 /* increment found count */
End
dead.p=1
/*
Say 'killing' p 'now'
*/
n=n-1 /* shoot the one on this pos. */
killed=killed p /* add to output */
End /* End of main loop */
Say 'killed:'subword(killed,1,20) /* output killing sequence */
Say ' 'subword(killed,21) /* output killing sequence */
Say 'Survivor(s):' /* show */
Do i=0 To 40 /* look for the surviving p's */
If dead.i=0 Then Say i /* found one */
Say 'killed:'killed /* output killing sequence */
s=''
Do i=0 To nn-1 /* look for the surviving p's */
If dead.i=0 Then s=s i /* found one */
End
Say 'Survivor(s):'s /* show */

View file

@ -0,0 +1,7 @@
#lang racket
(define (josephus n k (m 0))
(for/fold ((m (add1 m)))
((a (in-range (add1 m) (add1 n))))
(remainder (+ m k) a)))
(josephus 41 3) ; ->30

View file

@ -0,0 +1,42 @@
$ include "seed7_05.s7i";
const func array integer: executeAllButM (in integer: n, in integer: k, in integer: m) is func
result
var array integer: prisoners is [0 .. -1] times 0;
local
var integer: killIdx is 0;
var integer: prisonerNum is 0;
begin
for prisonerNum range 0 to pred(n) do
prisoners &:= prisonerNum;
end for;
writeln("Prisoners executed in order:");
while length(prisoners) > m do
killIdx := (killIdx + k - 1) rem length(prisoners);
write(prisoners[killIdx] <& " ");
ignore(remove(prisoners, killIdx));
end while;
writeln;
end func;
const func string: str (in array integer: intArr) is func
result
var string: stri is "";
local
var integer: index is 0;
begin
for key index range intArr do
if index <> minIdx(intArr) then
stri &:= ", ";
end if;
stri &:= str(intArr[index]);
end for;
end func;
enable_output(array integer);
const proc: main is func
begin
writeln("Survivor: " <& executeAllButM(41, 3, 1));
writeln("Survivors: " <& executeAllButM(41, 3, 3));
end func;