2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -3,18 +3,30 @@
|
|||
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. <br>
|
||||
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>).
|
||||
|
||||
;Task:
|
||||
Given any <big><math>n, k > 0</math></big>, find out which prisoner will be the final survivor.
|
||||
|
||||
In one such incident, there were 41 prisoners and every 3<sup>rd</sup> prisoner was being killed (<big><math>k=3</math></big>).
|
||||
|
||||
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.
|
||||
|
||||
;Extra:
|
||||
The captors may be especially kind and let <math>m</math> survivors free,
|
||||
<br>and Josephus might just have <big><math>m-1</math></big> friends to save.
|
||||
|
||||
Provide a way to calculate which prisoner is at any given position on the killing sequence.
|
||||
|
||||
'''Notes'''
|
||||
|
||||
;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.
|
||||
# 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.
|
||||
<br><br>
|
||||
|
|
|
|||
34
Task/Josephus-problem/6502-Assembly/josephus-problem.6502
Normal file
34
Task/Josephus-problem/6502-Assembly/josephus-problem.6502
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
JSEPHS: STA $D0 ; n
|
||||
STX $D1 ; k
|
||||
LDA #$FF
|
||||
LDX #$00
|
||||
SETUP: STA $1000,X ; populate array with hex FF
|
||||
INX
|
||||
CPX $D0
|
||||
BEQ KILL
|
||||
JMP SETUP
|
||||
KILL: LDA #$00 ; number killed so far
|
||||
STA $D2
|
||||
LDX #$00 ; position within array
|
||||
LDY #$01 ; counting up to k
|
||||
FIND: INY
|
||||
SCAN: INX
|
||||
CPX $D0
|
||||
BMI TEST
|
||||
LDX #$00 ; circle back around
|
||||
TEST: LDA $1000,X
|
||||
CMP #$FF
|
||||
BNE SCAN ; already been killed
|
||||
CPY $D1
|
||||
BMI FIND ; if y < k keep going round
|
||||
LDA $D2
|
||||
STA $1000,X ; mark as dead
|
||||
CLC
|
||||
ADC #$01
|
||||
STA $D2
|
||||
CMP $D0 ; have we killed all but 1?
|
||||
BPL RETURN
|
||||
LDY #$00
|
||||
JMP FIND
|
||||
RETURN: TXA ; a <- index of survivor
|
||||
RTS
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
Josephus2 =: 4 : '(| x&+)/i. - 1+y' NB. this is a direct translation of the algo from C code above.
|
||||
NB. this is a direct translation of the algo from C code above.
|
||||
Josephus2 =: 4 : '(| x&+)/i. - 1+y'
|
||||
|
||||
3 Josephus2 41
|
||||
3 Josephus2 41
|
||||
30
|
||||
|
|
|
|||
|
|
@ -1,8 +1 @@
|
|||
function j(n,k)
|
||||
p, i, seq=[0:n-1], 0, Int[]
|
||||
while !isempty(p)
|
||||
i=(i+k-1)%length(p)
|
||||
push!(seq,splice!(p,i+1))
|
||||
end
|
||||
@sprintf("Prisoner killing order: %s.\nSurvivor: %i",replace(chomp(string(seq[1:end-1])),"\n",", "),seq[end])
|
||||
end
|
||||
josephus(n, k, m=1) = n == m ? collect(0:m-1) : mod(josephus(n-1, k, m) + k, n)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
julia> 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
|
||||
julia> print(josephus(41,3))
|
||||
[30]
|
||||
julia> print(josephus(41,3,5))
|
||||
[3,15,21,30,34]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
function j2(n,k,m)
|
||||
function j(n,k)
|
||||
p, i, seq=[0:n-1], 0, Int[]
|
||||
while length(p)>m
|
||||
while !isempty(p)
|
||||
i=(i+k-1)%length(p)
|
||||
push!(seq,splice!(p,i+1))
|
||||
end
|
||||
prt_array(x)=replace(chomp(string(x)),"\n",", ")
|
||||
@sprintf("Prisoner killing order: %s.\nSurvivors: %s",prt_array(seq),"["*prt_array(p)*"]")
|
||||
@sprintf("Prisoner killing order: %s.\nSurvivor: %i",replace(chomp(string(seq[1:end-1])),"\n",", "),seq[end])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
julia> print(j2(41,3,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.
|
||||
Survivors: [15, 30, 34]
|
||||
julia> 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
|
||||
|
|
|
|||
9
Task/Josephus-problem/Julia/josephus-problem-5.julia
Normal file
9
Task/Josephus-problem/Julia/josephus-problem-5.julia
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
function j2(n,k,m)
|
||||
p, i, seq=[0:n-1], 0, Int[]
|
||||
while length(p)>m
|
||||
i=(i+k-1)%length(p)
|
||||
push!(seq,splice!(p,i+1))
|
||||
end
|
||||
prt_array(x)=replace(chomp(string(x)),"\n",", ")
|
||||
@sprintf("Prisoner killing order: %s.\nSurvivors: %s",prt_array(seq),"["*prt_array(p)*"]")
|
||||
end
|
||||
3
Task/Josephus-problem/Julia/josephus-problem-6.julia
Normal file
3
Task/Josephus-problem/Julia/josephus-problem-6.julia
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
julia> print(j2(41,3,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.
|
||||
Survivors: [15, 30, 34]
|
||||
21
Task/Josephus-problem/PowerShell/josephus-problem-1.psh
Normal file
21
Task/Josephus-problem/PowerShell/josephus-problem-1.psh
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<lang PowerShell>
|
||||
function Get-JosephusPrisoners ( [int]$N, [int]$K )
|
||||
{
|
||||
# Just for convenience
|
||||
$End = $N - 1
|
||||
|
||||
# Create circle of prisoners
|
||||
$Prisoners = New-Object System.Collections.ArrayList ( , (0..$End) )
|
||||
|
||||
# For each starting point of the reducing circle...
|
||||
ForEach ( $Start in 0..($End - 1) )
|
||||
{
|
||||
# We subtract one from K for the one we advanced by incrementing $Start
|
||||
# Then take K modulus the length of the remaining circle
|
||||
$RoundK = ( $K - 1 ) % ( $End - $Start + 1 )
|
||||
|
||||
# Rotate the remaining prisoners K places around the remaining circle
|
||||
$Prisoners.SetRange( $Start, $Prisoners[ $Start..$End ][ ( $RoundK + $Start - $End - 1 )..( $RoundK - 1 ) ] )
|
||||
}
|
||||
return $Prisoners
|
||||
}
|
||||
12
Task/Josephus-problem/PowerShell/josephus-problem-2.psh
Normal file
12
Task/Josephus-problem/PowerShell/josephus-problem-2.psh
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Get the prisoner order for a circle of 41 prisoners, selecting every third
|
||||
$Prisoners = Get-JosephusPrisoners -N 41 -K 3
|
||||
|
||||
# Display the prisoner order
|
||||
$Prisoners -join " "
|
||||
|
||||
# Display the last remaining prisoner
|
||||
"Last prisoner remmaining: " + $Prisoners[-1]
|
||||
|
||||
# Display the last three remaining prisoners
|
||||
$S = 3
|
||||
"Last $S remaining: " + $Prisoners[-$S..-1]
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
function main($n=0,$k=0,$s=0) {
|
||||
#n - number of prisoners
|
||||
#k - kill every k'th prisoner
|
||||
#s - number of survivors
|
||||
|
||||
write-host "`nn=$n k=$k s=$s" #show arguments
|
||||
|
||||
#Error Checking (Optional)
|
||||
try {
|
||||
if ([int]$n -lt 0){write-host "[n`<0] " -nonewline;$errors++}
|
||||
if ([int]$k -lt 0){write-host "[k`<0] " -nonewline;$errors++}
|
||||
if ([int]$s -lt 0){write-host "[s`<0] " -nonewline;$errors++}
|
||||
if ([int]$s -gt [int]$n){write-host "[s`>n] " -nonewline;$errors++}
|
||||
if ($errors -gt 0) {"";return}
|
||||
} catch {"Oops! I found a string input.";return}
|
||||
|
||||
$dead = @(0) * $n+1
|
||||
$nn=$n
|
||||
$p=-1
|
||||
while ($n -ne $s){
|
||||
$found=0
|
||||
while ($found -ne $k){
|
||||
if ($p++ -eq $nn) { $p=0 }
|
||||
if ($dead[$p] -ne 1) {$found++}
|
||||
}
|
||||
$dead[$p]++
|
||||
$killed+="$p "
|
||||
$n--
|
||||
}
|
||||
for($i=0;$i -le $nn-1;$i++){
|
||||
if ($dead[$i] -ne 1) {$survived+="$i "}
|
||||
}
|
||||
write-host "Killed: $killed"
|
||||
write-host "Survived: $survived"
|
||||
return
|
||||
}
|
||||
|
||||
main 5 2 1
|
||||
main 41 3 1
|
||||
main 41 3 3
|
||||
main 2 -3 4
|
||||
|
|
@ -1,25 +1,26 @@
|
|||
/*REXX program: Josephus problem: N men standing in a circle, every Kth kilt.*/
|
||||
parse arg N K Z R . /*get the optional arguments from C.L. */
|
||||
if N==',' | N=='' then N = 41 /*no #prisoners? Then use the 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 prisoner's circle (with a #)*/
|
||||
c=0 /*initial prisoner count─off number. */
|
||||
do remove=0; p=words($) /*keep removing until R are remaining*/
|
||||
c=c+K /*bump the prisoner count-off by K. */
|
||||
if c>p then do /* [↓] remove (kill) some prisoner(s)*/
|
||||
do j=1 for words(x); $=delword($,word(x,j)+1-j,1)
|
||||
if words($)==R then leave remove /*is the slaying done? */
|
||||
end /*j*/
|
||||
c=(c//p)//words($); x= /*adjust prisoner count-off and circle.*/
|
||||
/*REXX program solves Josephus problem: N men standing in a circle, every Kth kilt.*/
|
||||
/*N=men, K=kilt, Z=start, R=remaining. */
|
||||
parse arg N K Z R . /*obtain optional arguments from the CL*/
|
||||
if N=='' | N=="," then N = 41 /*Not specified? Then use the default.*/
|
||||
if K=='' | K=="," then K = 3 /* " " " " " " */
|
||||
if Z=='' | Z=="," then Z = 0 /* " " " " " " */
|
||||
if R=='' | R=="," then R = 1 /* " " " " " " */
|
||||
$=; x=; do pop=Z for N; $=$ pop; end /*pop*/ /*populate prisoner's circle (with a #)*/
|
||||
c=0 /*initial prisoner count─off number. */
|
||||
do remove=0 by 0; p=words($) /*keep removing until R are remaining*/
|
||||
c=c+K /*bump the prisoner count-off by K. */
|
||||
if c>p then do /* [↓] remove (kill) some prisoner(s)*/
|
||||
do j=1 for words(x); $=delword($, word(x, j) + 1 - j, 1)
|
||||
if words($)==R then leave remove /*is the slaying done?*/
|
||||
end /*j*/
|
||||
c=(c//p) // words($); x= /*adjust prisoner count-off and circle.*/
|
||||
end
|
||||
if c\==0 then x=x c /*the list of prisoners to be removed. */
|
||||
end /*remove*/ /*remove 'til R prisoners are left.*/
|
||||
if c\==0 then x=x c /*the list of prisoners to be removed. */
|
||||
end /*remove*/ /*remove 'til R prisoners are 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 all done. */
|
||||
/*──────────────────────────────────subroutines───────────────────────────────*/
|
||||
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1)
|
||||
th: parse arg y; return y||word('th st nd rd',1+y//10*(y//100%10\==1)*(y//10<4))
|
||||
say 'removing every ' th(K) " prisoner out of " N ' (starting at' Z") with ",
|
||||
R ' survivor's(R)", leaving prisoner"s(R)':' $
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
s: if arg(1)==1 then return arg(3); return word( arg(2) 's', 1)
|
||||
th: y=arg(1); return y || word('th st nd rd', 1+ y // 10 * (y//100%10\==1) * (y//10<4))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue