Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -0,0 +1,150 @@
! Program to solve the coconut problem for 5 and 6 sailors
! Calculates the minimum initial pile of coconuts that satisfies the problem constraints
! Each sailor divides the pile into equal parts, gives one coconut to the monkey, hides one part,
! and combines the rest. In the morning, the final pile divides equally among sailors with no remainder.
program coconut_problem
implicit none
! Variable declarations
integer :: d ! Number of sailors (5 or 6)
integer :: x0 ! Initial guess for final morning pile size
integer :: current ! Current pile size during calculations
integer :: m ! Size of each divided pile for a sailor
integer :: i ! Loop counters
integer :: min_pile ! Stores the minimum initial pile size
integer, dimension(6) :: hidden ! Array to store number of coconuts each sailor hides (max 6 sailors)
logical :: valid ! Flag to indicate if a solution is valid
! --- Solve for 5 sailors ---
! Initialize number of sailors
d = 5
! Start with the smallest possible final pile size that divides evenly among 5 sailors
x0 = d
! Loop to find the minimum initial pile
do while (.true.)
! Start with the current guess for the final pile
current = x0
! Assume the solution is valid until proven otherwise
valid = .true.
! Simulate the process backwards for each sailor
do i = 1, d
! Check if the current pile size is divisible by (d-1)
! This checks if the pile before the sailor took their share and gave one to the monkey
! can be formed by combining (d-1) equal piles
if (mod(current, d-1) /= 0) then
valid = .false.
exit
end if
! Calculate the size of each pile the sailor made
m = current / (d-1)
! Reverse the process: compute the pile size before the sailor took their share
! If current pile is from (d-1) parts, the original pile was d*m + 1 (including monkey's coconut)
current = d * m + 1
end do
! If the process completed without issues, we found a valid initial pile
if (valid) then
min_pile = current
exit
end if
! Increment the final pile size by d to keep it divisible by d in the morning
x0 = x0 + d
end do
! Output the minimum initial pile size for 5 sailors
write(*,*) "Minimum initial pile for 5 sailors:", min_pile
! --- Simulate to find hidden amounts for 5 sailors ---
! Start with the minimum initial pile
current = min_pile
write(*,*) "Hidden amounts for 5 sailors:"
! Simulate each sailor's actions in forward order
do i = 1, d
! Verify the pile divides into d parts with 1 coconut left for the monkey
if (mod(current, d) /= 1) then
write(*,*) "Error in simulation"
stop
end if
! Calculate the size of each pile the sailor makes
m = (current - 1) / d
! Store the number of coconuts hidden by this sailor
hidden(i) = m
! Update the pile size: sailor takes one pile, leaves (d-1) piles
current = (d - 1) * m
! Output the number of coconuts hidden by this sailor
write(*,*) "Sailor", i, "hides:", hidden(i)
end do
! Output the final pile size in the morning
write(*,*) "Final pile in morning:", current
! Verify the final pile divides evenly among sailors
if (mod(current, d) /= 0) then
write(*,*) "Error in final division"
else
! Output the number of coconuts each sailor gets in the morning
write(*,*) "Each gets in morning:", current / d
end if
! --- Solve for 6 sailors ---
! Initialize number of sailors
d = 6
! Start with the smallest possible final pile size that divides evenly among 6 sailors
x0 = d
! Loop to find the minimum initial pile
do while (.true.)
! Start with the current guess for the final pile
current = x0
! Assume the solution is valid until proven otherwise
valid = .true.
! Simulate the process backwards for each sailor
do i = 1, d
! Check if the current pile size is divisible by (d-1)
if (mod(current, d-1) /= 0) then
valid = .false.
exit
end if
! Calculate the size of each pile the sailor made
m = current / (d-1)
! Reverse the process: compute the pile size before the sailor took their share
current = d * m + 1
end do
! If the process completed without issues, we found a valid initial pile
if (valid) then
min_pile = current
exit
end if
! Increment the final pile size by d to keep it divisible by d in the morning
x0 = x0 + d
end do
! Output the minimum initial pile size for 6 sailors
write(*,*) "Minimum initial pile for 6 sailors:", min_pile
! --- Simulate to find hidden amounts for 6 sailors ---
! Start with the minimum initial pile
current = min_pile
write(*,*) "Hidden amounts for 6 sailors:"
! Simulate each sailor's actions in forward order
do i = 1, d
! Verify the pile divides into d parts with 1 coconut left for the monkey
if (mod(current, d) /= 1) then
write(*,*) "Error in simulation"
stop
end if
! Calculate the size of each pile the sailor makes
m = (current - 1) / d
! Store the number of coconuts hidden by this sailor
hidden(i) = m
! Update the pile size: sailor takes one pile, leaves (d-1) piles
current = (d - 1) * m
! Output the number of coconuts hidden by this sailor
write(*,*) "Sailor", i, "hides:", hidden(i)
end do
! Output the final pile size in the morning
write(*,*) "Final pile in morning:", current
! Verify the final pile divides evenly among sailors
if (mod(current, d) /= 0) then
write(*,*) "Error in final division"
else
! Output the number of coconuts each sailor gets in the morning
write(*,*) "Each gets in morning:", current / d
end if
end program coconut_problem

View file

@ -0,0 +1,31 @@
procedure solve(integer sailors, bool bShowtakes=true)
integer m, sm1 = sailors-1
if sm1=0 then -- edge condition for solve(1) [ avoid /0 ]
m = sailors
else
integer n = 0
do
n += sailors -- morning pile divisible by #sailors
m = n
for j=1 to sailors do -- see if all of the sailors could..
if rmdr(m,sm1)!=0 then -- ..have pushed together sm1 piles
m = 0 -- (no: try a higher n)
exit
end if
m = sailors*m/sm1+1 -- add sailor j's stash and one for the monkey
end for
until m!=0
end if
printf(1,"Solution with %d sailors: %d\n",{sailors,m})
for i=1 to sailors do
m -= 1 -- one for the monkey
m /= sailors
if bShowtakes then
printf(1,"Sailor #%d takes %d, monkey gets 1, leaving %d\n",{i,m,m*sm1})
end if
m *= (sm1)
end for
printf(1,"In the morning each sailor gets %d nuts\n",m/sailors)
end procedure
for n in {1,2,3,5,6,9} do solve(n,n<=5) end for

View file

@ -0,0 +1,31 @@
with javascript_semantics
include mpfr.e
procedure solve(integer sailors)
integer sm1 = sailors-1
mpz m = mpz_init()
mpz_ui_pow_ui(m,sailors,sailors)
if odd(sailors) then
mpz_sub_si(m,m,sm1)
-- elsif sailors=2 then -- (if preferred)
-- mpz_set_si(m,11)
else
mpz_sub_si(m,m,1)
mpz_mul_si(m,m,sm1)
end if
printf(1,"Sailors:%d, Coconuts:%s\n",{sailors,mpz_get_short_str(m)})
--/*
for i=1 to sailors do
mpz_sub_si(m,m,1) -- one for the monkey
mpz_divexact_ui(m,m,sailors)
string ts = mpz_get_str(m)
printf(1,"%d%s takes %s, gives 1 to the monkey\n",{i,ord(i),ts})
mpz_mul_si(m,m,sm1)
end for
mpz_divexact_ui(m,m,sailors)
string p = iff(mpz_cmp_si(m,1)=0?"":"s")
printf(1,"In the morning each sailor gets %s nut%s\n",{mpz_get_str(m),p})
printf(1,"with none left over for the monkey\n")
--*/
end procedure
for n in tagset(15)&{100,101} do solve(n) end for

View file

@ -0,0 +1,29 @@
require "table2"
local coconuts = 11
for ns = 2, 9 do
local hidden = table.rep(ns, 0)
coconuts = (coconuts // ns) * ns + 1
while true do
local nc = coconuts
local outer = false
for s = 1, ns do
if nc % ns == 1 then
hidden[s] = nc // ns
nc -= hidden[s] + 1
if s == ns and nc % ns == 0 then
print($"{ns} sailors require a minimum of {coconuts} coconuts")
for t = 1, ns do print($"\tSailor {t} hides {hidden[t]}") end
print($"\tThe monkey gets {ns}")
print($"\tFinally, each sailor takes {nc // ns}\n")
outer = true
break
end
else
break
end
end
if outer then break end
coconuts += ns
end
end