A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
10
Task/Josephus-problem/0DESCRIPTION
Normal file
10
Task/Josephus-problem/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
[[wp:Josephus problem|Josephus problem]] is a math puzzle with a grim description: <math>n</math> prisoners are standing on a circle, sequentially numbered from <math>0</math> to <math>n-1</math>. An executioner walks along the circle, starting from prisoner <math>0</math>, removing every <math>k</math>-th prisoner and killing him. As the process goes on, the circle becomes smaller and smaller, until only one prisoner remains, who is then freed. For example, if there are <math>n=5</math> prisoners and <math>k=2</math>, the order the prisoners are killed in (let's call it the "killing sequence") will be 1, 3, 0, and 4, and the survivor will be #2.
|
||||
|
||||
'''Task''' Given any <math>n, k > 0</math>, find out which prisoner will be the final survivor. In one such incident, there were 41 prisoners and every 3rd prisoner was being killed (<math>k=3</math>). Among them was a clever chap name Josephus who worked out the problem, stood at the surviving position, and lived on to tell the tale. Which number was he?
|
||||
|
||||
'''Extra''' The captors may be especially kind and let <math>m</math> survivors free, and Josephus might just have <math>m-1</math> friends to save. Provide a way to calculate which prisoner is at any given position on the killing sequence.
|
||||
|
||||
'''Notes'''
|
||||
# You can always play the executioner and follow the procedure exactly as described, walking around the circle, counting (and cutting off) heads along the way. This would yield the complete killing sequence and answer the above questions, with a complexity of probably <math>O(kn)</math>. However, individually it takes no more than <math>O(m)</math> to find out which prisoner is the <math>m</math>-th to die.
|
||||
# If it's more convenient, you can number prisoners from <math>1</math> to <math>n</math> instead. If you choose to do so, please state it clearly.
|
||||
# An alternative description has the people committing assisted suicide instead of being executed, and the last person simply walks away. These details are not relevant, at least not mathematically.
|
||||
2
Task/Josephus-problem/1META.yaml
Normal file
2
Task/Josephus-problem/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Puzzles
|
||||
43
Task/Josephus-problem/Ada/josephus-problem.ada
Normal file
43
Task/Josephus-problem/Ada/josephus-problem.ada
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
with Ada.Command_Line, Ada.Text_IO;
|
||||
|
||||
procedure Josephus is
|
||||
|
||||
function Arg(Idx, Default: Positive) return Positive is -- read Argument(Idx)
|
||||
(if Ada.Command_Line.Argument_Count >= Index
|
||||
then Positive'Value(Ada.Command_Line.Argument(Index)) else Default);
|
||||
|
||||
Prisoners: constant Positive := Arg(Idx => 1, Default => 41);
|
||||
Steps: constant Positive := Arg(Idx => 2, Default => 3);
|
||||
Survivors: constant Positive := Arg(Idx => 3, Default => 1);
|
||||
Print: Boolean := (Arg(Idx => 4, Default => 1) = 1);
|
||||
|
||||
subtype Index_Type is Natural range 0 .. Prisoners-1;
|
||||
Next: array(Index_Type) of Index_Type;
|
||||
X: Index_Type := (Steps-2) mod Prisoners;
|
||||
|
||||
begin
|
||||
Ada.Text_IO.Put_Line
|
||||
("N =" & Positive'Image(Prisoners) & ", K =" & Positive'Image(Steps) &
|
||||
(if Survivors > 1 then ", #survivors =" & Positive'Image(Survivors)
|
||||
else ""));
|
||||
for Idx in Next'Range loop -- initialize Next
|
||||
Next(Idx) := (Idx+1) mod Prisoners;
|
||||
end loop;
|
||||
if Print then
|
||||
Ada.Text_IO.Put("Executed: ");
|
||||
end if;
|
||||
for Execution in reverse 1 .. Prisoners loop
|
||||
if Execution = Survivors then
|
||||
Ada.Text_IO.New_Line;
|
||||
Ada.Text_IO.Put("Surviving: ");
|
||||
Print := True;
|
||||
end if;
|
||||
if Print then
|
||||
Ada.Text_IO.Put(Positive'Image(Next(X)));
|
||||
end if;
|
||||
Next(X) := Next(Next(X)); -- "delete" a prisoner
|
||||
for Prisoner in 1 .. Steps-1 loop
|
||||
X := Next(X);
|
||||
end loop;
|
||||
end loop;
|
||||
end Josephus;
|
||||
24
Task/Josephus-problem/AutoHotkey/josephus-problem-1.ahk
Normal file
24
Task/Josephus-problem/AutoHotkey/josephus-problem-1.ahk
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
; Since AutoHotkey is 1-based, we're numbering prisoners 1-41.
|
||||
nPrisoners := 41
|
||||
kth := 3
|
||||
|
||||
; Build a list, purposefully ending with a separator
|
||||
Loop % nPrisoners
|
||||
list .= A_Index . "|"
|
||||
|
||||
; iterate and remove from list
|
||||
i := 1
|
||||
Loop
|
||||
{
|
||||
; Step by 2; the third step was done by removing the previous prisoner
|
||||
i += kth - 1
|
||||
if (i > nPrisoners)
|
||||
i := Mod(i, nPrisoners)
|
||||
; Remove from list
|
||||
end := InStr(list, "|", 0, 1, i)
|
||||
bgn := InStr(list, "|", 0, 1, i-1)
|
||||
list := SubStr(list, 1, bgn) . SubStr(list, end+1)
|
||||
nPrisoners--
|
||||
}
|
||||
Until (nPrisoners = 1)
|
||||
MsgBox % RegExReplace(list, "\|") ; remove the final separator
|
||||
20
Task/Josephus-problem/AutoHotkey/josephus-problem-2.ahk
Normal file
20
Task/Josephus-problem/AutoHotkey/josephus-problem-2.ahk
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
nPrisoners := 41
|
||||
kth := 3
|
||||
list := []
|
||||
|
||||
; Build a list of 41 items
|
||||
Loop % nPrisoners
|
||||
list.insert(A_Index)
|
||||
|
||||
; iterate and remove from list
|
||||
i := 1
|
||||
Loop
|
||||
{
|
||||
; Step by 3
|
||||
i += kth - 1
|
||||
if (i > list.MaxIndex())
|
||||
i := Mod(i, list.MaxIndex())
|
||||
list.remove(i)
|
||||
}
|
||||
Until (list.MaxIndex() = 1)
|
||||
MsgBox % list.1 ; there is only 1 element left
|
||||
46
Task/Josephus-problem/C/josephus-problem.c
Normal file
46
Task/Josephus-problem/C/josephus-problem.c
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include <stdio.h>
|
||||
|
||||
// m-th on the reversed kill list; m = 0 is final survivor
|
||||
int jos(int n, int k, int m) {
|
||||
int a;
|
||||
for (a = m + 1; a <= n; a++)
|
||||
m = (m + k) % a;
|
||||
return m;
|
||||
}
|
||||
|
||||
typedef unsigned long long xint;
|
||||
|
||||
// same as jos(), useful if n is large and k is not
|
||||
xint jos_large(xint n, xint k, xint m) {
|
||||
if (k <= 1) return n - m - 1;
|
||||
|
||||
xint a = m;
|
||||
while (a < n) {
|
||||
xint q = (a - m + k - 2) / (k - 1);
|
||||
|
||||
if (a + q > n) q = n - a;
|
||||
else if (!q) q = 1;
|
||||
|
||||
m = (m + q * k) % (a += q);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
xint n, k, i;
|
||||
|
||||
n = 41;
|
||||
k = 3;
|
||||
printf("n = %llu, k = %llu, final survivor: %d\n", n, k, jos(n, k, 0));
|
||||
|
||||
n = 9876543210987654321ULL;
|
||||
k = 12031;
|
||||
printf("n = %llu, k = %llu, three survivors:", n, k);
|
||||
|
||||
for (i = 3; i--; )
|
||||
printf(" %llu", jos_large(n, k, i));
|
||||
putchar('\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
(defun kill (n k &aux (m 0))
|
||||
(loop for a from (1+ m) upto n do
|
||||
(setf m (mod (+ m k) a)))
|
||||
m)
|
||||
22
Task/Josephus-problem/Common-Lisp/josephus-problem-2.lisp
Normal file
22
Task/Josephus-problem/Common-Lisp/josephus-problem-2.lisp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
(defun make-circular-list (n)
|
||||
(let* ((list (loop for i below n
|
||||
collect i))
|
||||
(last (last list)))
|
||||
(setf (cdr last) list)
|
||||
list))
|
||||
|
||||
(defun kill (n d)
|
||||
(let ((list (make-circular-list n)))
|
||||
(flet ((one-element-clist-p (list)
|
||||
(eq list (cdr list)))
|
||||
(move-forward ()
|
||||
(loop repeat (1- d)
|
||||
until (eq list (cdr list))
|
||||
do (setf list (cdr list))))
|
||||
(kill-item ()
|
||||
(setf (car list) (cadr list)
|
||||
(cdr list) (cddr list))))
|
||||
(loop until (one-element-clist-p list) do
|
||||
(move-forward)
|
||||
(kill-item))
|
||||
(first list))))
|
||||
27
Task/Josephus-problem/D/josephus-problem.d
Normal file
27
Task/Josephus-problem/D/josephus-problem.d
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import std.stdio, std.algorithm, std.array, std.string, std.range;
|
||||
|
||||
T pop(T)(ref T[] items, in size_t i) pure {
|
||||
auto aux = items[i];
|
||||
items.remove(i);
|
||||
items.length--;
|
||||
return aux;
|
||||
}
|
||||
|
||||
string josephus(in int n, in int k) {
|
||||
auto p = iota(n).array();
|
||||
int i;
|
||||
int[] seq;
|
||||
while (!p.empty) {
|
||||
i = (i + k - 1) % p.length;
|
||||
seq ~= p.pop(i);
|
||||
}
|
||||
|
||||
return xformat("Prisoner killing order: %(%d, %).\nSurvivor: %d",
|
||||
seq[0 .. $-1], seq[$ - 1]);
|
||||
}
|
||||
|
||||
void main() {
|
||||
writeln(josephus(5, 2));
|
||||
writeln();
|
||||
writeln(josephus(41, 3));
|
||||
}
|
||||
49
Task/Josephus-problem/Go/josephus-problem.go
Normal file
49
Task/Josephus-problem/Go/josephus-problem.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
// basic task function
|
||||
func finalSurvivor(n, k int) int {
|
||||
// argument validation omitted
|
||||
circle := make([]int, n)
|
||||
for i := range circle {
|
||||
circle[i] = i
|
||||
}
|
||||
k--
|
||||
exPos := 0
|
||||
for len(circle) > 1 {
|
||||
exPos = (exPos + k) % len(circle)
|
||||
circle = append(circle[:exPos], circle[exPos+1:]...)
|
||||
}
|
||||
return circle[0]
|
||||
}
|
||||
|
||||
// extra
|
||||
func position(n, k, pos int) int {
|
||||
// argument validation omitted
|
||||
circle := make([]int, n)
|
||||
for i := range circle {
|
||||
circle[i] = i
|
||||
}
|
||||
k--
|
||||
exPos := 0
|
||||
for len(circle) > 1 {
|
||||
exPos = (exPos + k) % len(circle)
|
||||
if pos == 0 {
|
||||
return circle[exPos]
|
||||
}
|
||||
pos--
|
||||
circle = append(circle[:exPos], circle[exPos+1:]...)
|
||||
}
|
||||
return circle[0]
|
||||
}
|
||||
|
||||
func main() {
|
||||
// show basic task function on given test case
|
||||
fmt.Println(finalSurvivor(41, 3))
|
||||
// show extra function on all positions of given test case
|
||||
fmt.Println("Position Prisoner")
|
||||
for i := 0; i < 41; i++ {
|
||||
fmt.Printf("%5d%10d\n", i, position(41, 3, i))
|
||||
}
|
||||
}
|
||||
40
Task/Josephus-problem/Java/josephus-problem.java
Normal file
40
Task/Josephus-problem/Java/josephus-problem.java
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import java.util.ArrayList;
|
||||
|
||||
public class Josephus {
|
||||
public static int execute(int n, int k){
|
||||
int killIdx = 0;
|
||||
ArrayList<Integer> prisoners = new ArrayList<Integer>(n);
|
||||
for(int i = 0;i < n;i++){
|
||||
prisoners.add(i);
|
||||
}
|
||||
System.out.println("Prisoners executed in order:");
|
||||
while(prisoners.size() > 1){
|
||||
killIdx = (killIdx + k - 1) % prisoners.size();
|
||||
System.out.print(prisoners.get(killIdx) + " ");
|
||||
prisoners.remove(killIdx);
|
||||
}
|
||||
System.out.println();
|
||||
return prisoners.get(0);
|
||||
}
|
||||
|
||||
public static ArrayList<Integer> executeAllButM(int n, int k, int m){
|
||||
int killIdx = 0;
|
||||
ArrayList<Integer> prisoners = new ArrayList<Integer>(n);
|
||||
for(int i = 0;i < n;i++){
|
||||
prisoners.add(i);
|
||||
}
|
||||
System.out.println("Prisoners executed in order:");
|
||||
while(prisoners.size() > m){
|
||||
killIdx = (killIdx + k - 1) % prisoners.size();
|
||||
System.out.print(prisoners.get(killIdx) + " ");
|
||||
prisoners.remove(killIdx);
|
||||
}
|
||||
System.out.println();
|
||||
return prisoners;
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
System.out.println("Survivor: " + execute(41, 3));
|
||||
System.out.println("Survivors: " + executeAllButM(41, 3, 3));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
survivor[n_, k_] := Nest[Most[RotateLeft[#, k]] &, Range[0, n - 1], n - 1]
|
||||
survivor[41, 3]
|
||||
8
Task/Josephus-problem/Perl/josephus-problem.pl
Normal file
8
Task/Josephus-problem/Perl/josephus-problem.pl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
my @prisoner = 0 .. 40;
|
||||
my $k = 3;
|
||||
until (@prisoner == 1) {
|
||||
push @prisoner, shift @prisoner for 1 .. $k-1;
|
||||
shift @prisoner;
|
||||
}
|
||||
|
||||
print "Prisoner @prisoner survived.\n"
|
||||
14
Task/Josephus-problem/Python/josephus-problem.py
Normal file
14
Task/Josephus-problem/Python/josephus-problem.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
>>> def j(n, k):
|
||||
p, i, seq = list(range(n)), 0, []
|
||||
while p:
|
||||
i = (i+k-1) % len(p)
|
||||
seq.append(p.pop(i))
|
||||
return 'Prisoner killing order: %s.\nSurvivor: %i' % (', '.join(str(i) for i in seq[:-1]), seq[-1])
|
||||
|
||||
>>> print(j(5, 2))
|
||||
Prisoner killing order: 1, 3, 0, 4.
|
||||
Survivor: 2
|
||||
>>> print(j(41, 3))
|
||||
Prisoner killing order: 2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 0, 4, 9, 13, 18, 22, 27, 31, 36, 40, 6, 12, 19, 25, 33, 39, 7, 16, 28, 37, 10, 24, 1, 21, 3, 34, 15.
|
||||
Survivor: 30
|
||||
>>>
|
||||
30
Task/Josephus-problem/REXX/josephus-problem-1.rexx
Normal file
30
Task/Josephus-problem/REXX/josephus-problem-1.rexx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* REXX **************************************************************
|
||||
* 15.11.2012 Walter Pachl - my own solution
|
||||
* 16.11.2012 Walter Pachl generalized n prisoners + w killing distance
|
||||
* and s=number 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 */
|
||||
found=0 /* start looking */
|
||||
Do Until found=w /* until we have the third */
|
||||
p=p+1 /* next position */
|
||||
If p=nn Then p=0 /* wrap around */
|
||||
If dead.p=0 Then /* a prisoner who is alive */
|
||||
found=found+1 /* increment found count */
|
||||
End
|
||||
dead.p=1
|
||||
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 */
|
||||
End
|
||||
25
Task/Josephus-problem/REXX/josephus-problem-2.rexx
Normal file
25
Task/Josephus-problem/REXX/josephus-problem-2.rexx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*REXX pgm, Josephus problem: N men standing in a circle, every Kth kilt*/
|
||||
parse arg N K Z R . /*get optional arguments. */
|
||||
if N==',' | N=='' then N = 41 /*no #prisoners? Then use default*/
|
||||
if K==',' | K=='' then K = 3 /*no kill count? " " " */
|
||||
if Z==',' | Z=='' then Z = 0 /*no initial # ? " " " */
|
||||
if R==',' | R=='' then R = 1 /*no remaining#? " " " */
|
||||
$=; x=; do pop=Z for N; $=$ pop; end /*populate the prisoner's circle.*/
|
||||
c=0 /*initial prisoner count-off num.*/
|
||||
do remove=0; p=words($) /*keep removing until R are left.*/
|
||||
c=c+K /*bump prisoner count-off by K.*/
|
||||
if c>p then do /* [↓] remove some prisoner(s).*/
|
||||
do j=1 for words(x); $=delword($,word(x,j)+1-j,1)
|
||||
if words($)==R then leave remove /*slaying done yet?*/
|
||||
end /*j*/
|
||||
c=(c//p)//words($); x= /*adjust prisoner count-off &list*/
|
||||
end
|
||||
if c\==0 then x=x c /*list of prisoners to be removed*/
|
||||
end /*remove*/ /*remove 'til R prisoners left.*/
|
||||
|
||||
say 'removing every ' th(K) " prisoner out of " N ' (starting at' Z") with ",
|
||||
R ' survivor's(R)"," ; say 'leaving prisoner's(R)':' $
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────subroutines──────────────────────────*/
|
||||
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1)
|
||||
th: arg y; return y||word('th st nd rd', 1+y//10*(y//100%10\==1)*(y//10<4))
|
||||
13
Task/Josephus-problem/Ruby/josephus-problem.rb
Normal file
13
Task/Josephus-problem/Ruby/josephus-problem.rb
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
def main
|
||||
n = (ARGV[0] || 41).to_i
|
||||
k = (ARGV[1] || 3).to_i
|
||||
puts josephus(n,k)
|
||||
end
|
||||
|
||||
def josephus(n, k)
|
||||
prisoners = (0...n).to_a
|
||||
prisoners.rotate!(k-1).shift while prisoners.length > 1
|
||||
return prisoners.first
|
||||
end
|
||||
|
||||
main
|
||||
27
Task/Josephus-problem/Scala/josephus-problem.scala
Normal file
27
Task/Josephus-problem/Scala/josephus-problem.scala
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
def executed( prisonerCount:Int, step:Int ) = {
|
||||
|
||||
val prisoners = ((0 until prisonerCount) map (_.toString)).toList
|
||||
|
||||
def behead( dead:Seq[String], alive:Seq[String] )(countOff:Int) : (Seq[String], Seq[String]) = {
|
||||
val group = if( alive.size < countOff ) countOff - alive.size else countOff
|
||||
|
||||
(dead ++ alive.take(group).drop(group-1), alive.drop(group) ++ alive.take(group-1))
|
||||
}
|
||||
|
||||
def beheadN( dead:Seq[String], alive:Seq[String] ) : (Seq[String], Seq[String]) =
|
||||
behead(dead,alive)(step)
|
||||
|
||||
def execute( t:(Seq[String], Seq[String]) ) : (Seq[String], Seq[String]) = t._2 match {
|
||||
case x :: Nil => (t._1, Seq(x))
|
||||
case x :: xs => execute(beheadN(t._1,t._2))
|
||||
}
|
||||
|
||||
execute((List(),prisoners))
|
||||
}
|
||||
|
||||
val (dead,alive) = executed(41,3)
|
||||
|
||||
println( "Prisoners executed in order:" )
|
||||
print( dead.mkString(" ") )
|
||||
|
||||
println( "\n\nJosephus is prisoner " + alive(0) )
|
||||
14
Task/Josephus-problem/Tcl/josephus-problem-1.tcl
Normal file
14
Task/Josephus-problem/Tcl/josephus-problem-1.tcl
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
proc josephus {number step {survivors 1}} {
|
||||
for {set i 0} {$i<$number} {incr i} {lappend l $i}
|
||||
for {set i 1} {[llength $l]} {incr i} {
|
||||
# If the element is to be killed, append to the kill sequence
|
||||
if {$i%$step == 0} {
|
||||
lappend killseq [lindex $l 0]
|
||||
set l [lrange $l 1 end]
|
||||
} else {
|
||||
# Roll the list
|
||||
set l [concat [lrange $l 1 end] [list [lindex $l 0]]]
|
||||
}
|
||||
}
|
||||
return [lrange $killseq end-[expr {$survivors-1}] end]
|
||||
}
|
||||
2
Task/Josephus-problem/Tcl/josephus-problem-2.tcl
Normal file
2
Task/Josephus-problem/Tcl/josephus-problem-2.tcl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
puts "remaining: [josephus 41 3]"
|
||||
puts "remaining 4: [join [josephus 41 3 4] ,]"
|
||||
Loading…
Add table
Add a link
Reference in a new issue