Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
4
Task/Sailors-coconuts-and-a-monkey-problem/00-META.yaml
Normal file
4
Task/Sailors-coconuts-and-a-monkey-problem/00-META.yaml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category:
|
||||
- Puzzles
|
||||
from: http://rosettacode.org/wiki/Sailors,_coconuts_and_a_monkey_problem
|
||||
29
Task/Sailors-coconuts-and-a-monkey-problem/00-TASK.txt
Normal file
29
Task/Sailors-coconuts-and-a-monkey-problem/00-TASK.txt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
Five sailors are shipwrecked on an island and collect a large pile of coconuts during the day.
|
||||
|
||||
That night the first sailor wakes up and decides to take his first share early so tries to divide the pile of coconuts equally into five piles but finds that there is one coconut left over, so he tosses it to a monkey and then hides "his" one of the five equally sized piles of coconuts and pushes the other four piles together to form a single visible pile of coconuts again and goes to bed.
|
||||
|
||||
To cut a long story short, each of the sailors in turn gets up once during the night and performs the same actions of dividing the coconut pile into five, finding that one coconut is left over and giving that single remainder coconut to the monkey.
|
||||
|
||||
In the morning (after the surreptitious and separate action of each of the five sailors during the night), the remaining coconuts are divided into five equal piles for each of the sailors, whereupon it is found that the pile of coconuts divides equally amongst the sailors with no remainder. (Nothing for the monkey in the morning.)
|
||||
|
||||
|
||||
;The task:
|
||||
# Calculate the minimum possible size of the initial pile of coconuts collected during the first day.
|
||||
# Use a method that assumes an answer is possible, and then applies the constraints of the tale to see if it is correct. (I.e. no applying some formula that generates the correct answer without integer divisions and remainders and tests on remainders; but constraint solvers ''are'' allowed.)
|
||||
# Calculate the size of the initial pile of coconuts if six sailors were marooned and went through a similar process (but split into six piles instead of five of course).
|
||||
# Show your answers here.
|
||||
|
||||
|
||||
;Extra credit (optional):
|
||||
* Give some indication of the number of coconuts each sailor hides during the night.
|
||||
|
||||
|
||||
;Note:
|
||||
* Of course the tale is told in a world where the collection of any amount of coconuts in a day and multiple divisions of the pile, etc can occur in time fitting the story line, so as not to affect the mathematics.
|
||||
* The tale is also told in a version where the monkey also gets a coconut in the morning. This is ''not'' that tale!
|
||||
|
||||
|
||||
;C.f:
|
||||
* [https://www.youtube.com/watch?v=U9qU20VmvaU Monkeys and Coconuts - Numberphile] (Video) Analytical solution.
|
||||
* [[oeis:A002021|A002021: Pile of coconuts problem]] The On-Line Encyclopedia of Integer Sequences. (Although some of its references may use the alternate form of the tale).
|
||||
<br><br>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
F monkey_coconuts(sailors = 5)
|
||||
V nuts = sailors
|
||||
L
|
||||
V n0 = nuts
|
||||
[(Int, Int, Int)] wakes
|
||||
L(sailor) 0..sailors
|
||||
V (portion, remainder) = divmod(n0, sailors)
|
||||
wakes.append((n0, portion, remainder))
|
||||
I portion <= 0 | remainder != (I sailor != sailors {1} E 0)
|
||||
nuts++
|
||||
L.break
|
||||
n0 = n0 - portion - remainder
|
||||
L.was_no_break
|
||||
R (nuts, wakes)
|
||||
|
||||
L(sailors) [5, 6]
|
||||
V (nuts, wake_stats) = monkey_coconuts(sailors)
|
||||
print("\nFor #. sailors the initial nut count is #.".format(sailors, nuts))
|
||||
print("On each waking, the nut count, portion taken, and monkeys share are:\n "wake_stats.map(ws -> String(ws)).join(",\n "))
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# syntax: GAWK -f SAILORS_COCONUTS_AND_A_MONKEY_PROBLEM.AWK
|
||||
# converted from LUA
|
||||
BEGIN {
|
||||
for (n=2; n<=9; n++) {
|
||||
x = 0
|
||||
while (!valid(n,x)) {
|
||||
x++
|
||||
}
|
||||
printf("%d %d\n",n,x)
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
function valid(n,nuts, k) {
|
||||
k = n
|
||||
while (k != 0) {
|
||||
if ((nuts % n) != 1) {
|
||||
return(0)
|
||||
}
|
||||
k--
|
||||
nuts = nuts - 1 - int(nuts / n)
|
||||
}
|
||||
return((nuts != 0) && (nuts % n == 0))
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
loop, 2
|
||||
{
|
||||
sailor := A_Index+4
|
||||
while !result := Coco(sailor, A_Index)
|
||||
continue
|
||||
; format output
|
||||
remain := result["Coconuts"]
|
||||
output := sailor " Sailors, Number of coconuts = " result["Coconuts"] "`n"
|
||||
loop % sailor {
|
||||
x := result["Sailor_" A_Index]
|
||||
output .= "Monkey gets 1, Sailor# " A_Index " hides (" remain "-1)/" sailor " = " x ", remainder = " (remain -= x+1) "`n"
|
||||
}
|
||||
output .= "Remainder = " result["Remaining"] "/" sailor " = " floor(result["Remaining"] / sailor)
|
||||
MsgBox % output
|
||||
}
|
||||
return
|
||||
|
||||
Coco(sailor, coconut){
|
||||
result := [], result["Coconuts"] := coconut
|
||||
loop % sailor {
|
||||
if (Mod(coconut, sailor) <> 1)
|
||||
return
|
||||
result["Sailor_" A_Index] := Floor(coconut/sailor)
|
||||
coconut -= Floor(coconut/sailor) + 1
|
||||
}
|
||||
if Mod(coconut, sailor) || !coconut
|
||||
return
|
||||
result["Remaining"] := coconut
|
||||
return result
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
define coconuts(sailors, monkeys) {
|
||||
print "coconuts(", sailors, ", ", monkeys, ") = "
|
||||
if (sailors < 2 || monkeys < 1 || sailors <= monkeys) {
|
||||
return 0
|
||||
}
|
||||
blue_cocos = sailors-1
|
||||
pow_bc = blue_cocos^sailors
|
||||
x_cocos = pow_bc
|
||||
while ((x_cocos-blue_cocos)%sailors || (x_cocos-blue_cocos)/sailors < 1) {
|
||||
x_cocos += pow_bc
|
||||
}
|
||||
return (x_cocos/pow_bc*(sailors^sailors)-blue_cocos)*monkeys
|
||||
}
|
||||
scale = 0
|
||||
coconuts(1, 1)
|
||||
coconuts(2, 1)
|
||||
coconuts(3, 1)
|
||||
coconuts(3, 2)
|
||||
coconuts(4, 1)
|
||||
coconuts(5, 1)
|
||||
coconuts(5, 4)
|
||||
coconuts(6, 1)
|
||||
coconuts(101, 1)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
>2+:01p9>`#@_00v
|
||||
nvg10*g10:+>#1$<
|
||||
#>\:01g1-%#^_:0v
|
||||
-|:-1\+1<+/-1g1<
|
||||
1>$01g.">-",,48v
|
||||
^g10,+55<.,9.,*<
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
( ( divmod
|
||||
= a b
|
||||
. !arg:(?a.?b)&(div$(!a.!b).mod$(!a.!b))
|
||||
)
|
||||
& ( overnight
|
||||
= ns nn result s q r
|
||||
. !arg:(?ns.?nn)
|
||||
& :?result
|
||||
& 0:?s
|
||||
& whl
|
||||
' ( !s+1:?s:~>!ns
|
||||
& divmod$(!nn.!ns):(?q.?r)
|
||||
& !r:1
|
||||
& !q*(!ns+-1):?nn
|
||||
& !result (!s.!q.!r.!nn):?result
|
||||
)
|
||||
& !s:>!ns
|
||||
& divmod$(!nn.!ns):(?q.0)
|
||||
& !result
|
||||
)
|
||||
& ( minnuts
|
||||
= nsailors nnuts result sailor takes gives leaves
|
||||
. !arg:?nsailors
|
||||
& 0:?nnuts
|
||||
& whl
|
||||
' ( 1+!nnuts:?nnuts
|
||||
& ~(overnight$(!nsailors.!nnuts):?result)
|
||||
)
|
||||
& out$(!nsailors ": " !nnuts)
|
||||
& whl
|
||||
' ( !result:(?sailor.?takes.?gives.?leaves) ?result
|
||||
& out
|
||||
$ ( str
|
||||
$ ( " Sailor #"
|
||||
!sailor
|
||||
" takes "
|
||||
!takes
|
||||
", giving "
|
||||
!gives
|
||||
" to the monkey and leaves "
|
||||
!leaves
|
||||
)
|
||||
)
|
||||
)
|
||||
& out
|
||||
$ ( str
|
||||
$ ("In the morning, each sailor gets " !leaves*!nsailors^-1 " nuts")
|
||||
)
|
||||
)
|
||||
& 4:?n
|
||||
& whl
|
||||
' ( 1+!n:~>6:?n
|
||||
& out$("Solution with " !n " sailors:")
|
||||
& minnuts$!n
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#include <iostream>
|
||||
|
||||
bool valid(int n, int nuts) {
|
||||
for (int k = n; k != 0; k--, nuts -= 1 + nuts / n) {
|
||||
if (nuts % n != 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return nuts != 0 && (nuts % n == 0);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int x = 0;
|
||||
for (int n = 2; n < 10; n++) {
|
||||
while (!valid(n, x)) {
|
||||
x++;
|
||||
}
|
||||
std::cout << n << ": " << x << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
class Test
|
||||
{
|
||||
static bool valid(int n, int nuts)
|
||||
{
|
||||
for (int k = n; k != 0; k--, nuts -= 1 + nuts / n)
|
||||
{
|
||||
if (nuts % n != 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return nuts != 0 && (nuts % n == 0);
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
int x = 0;
|
||||
for (int n = 2; n < 10; n++)
|
||||
{
|
||||
while (!valid(n, x))
|
||||
x++;
|
||||
System.Console.WriteLine(n + ": " + x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int valid(int n, int nuts)
|
||||
{
|
||||
int k;
|
||||
for (k = n; k; k--, nuts -= 1 + nuts/n)
|
||||
if (nuts%n != 1) return 0;
|
||||
return nuts && !(nuts%n);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int n, x;
|
||||
for (n = 2; n < 10; n++) {
|
||||
for (x = 0; !valid(n, x); x++);
|
||||
printf("%d: %d\n", n, x);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#include <stdio.h>
|
||||
|
||||
// calculates if everyone got some nuts in the end, what was the original pile
|
||||
// returns 0 if impossible
|
||||
int total(int n, int nuts)
|
||||
{
|
||||
int k;
|
||||
for (k = 0, nuts *= n; k < n; k++) {
|
||||
if (nuts % (n-1)) return 0;
|
||||
nuts += nuts / (n-1) + 1;
|
||||
}
|
||||
return nuts;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int n, x, t;
|
||||
for (n = 2; n < 10; n++) {
|
||||
for (x = 1, t = 0; !(t = total(n, x)); x++);
|
||||
printf("%d: %d\t%d\n", n, t, x);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
(defn solves-for? [sailors initial-coconut-count]
|
||||
(with-local-vars [coconuts initial-coconut-count, hidings 0]
|
||||
(while (and (> @coconuts sailors) (= (mod @coconuts sailors) 1)
|
||||
(var-set coconuts (/ (* (dec @coconuts) (dec sailors)) sailors))
|
||||
(var-set hidings (inc @hidings)))
|
||||
(and (zero? (mod @coconuts sailors)) (= @hidings sailors))))
|
||||
|
||||
(doseq [sailors (range 5 7)]
|
||||
(let [start (first (filter (partial solves-for? sailors) (range)))]
|
||||
(println (str sailors " sailors start with " start " coconuts:"))
|
||||
(with-local-vars [coconuts start]
|
||||
(doseq [sailor (range sailors)]
|
||||
(let [hidden (/ (dec @coconuts) sailors)]
|
||||
(var-set coconuts (/ (* (dec @coconuts) (dec sailors)) sailors))
|
||||
(println (str "\tSailor " (inc sailor) " hides " hidden " coconuts and gives 1 to the monkey, leaving " @coconuts "."))))
|
||||
(println
|
||||
(str "\tIn the morning, each sailor gets another " (/ @coconuts sailors) " coconuts."))
|
||||
(println "\tThe monkey gets no more.\n"))))
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
import std.stdio;
|
||||
|
||||
void main() {
|
||||
auto coconuts = 11;
|
||||
|
||||
outer:
|
||||
foreach (ns; 2..10) {
|
||||
int[] hidden = new int[ns];
|
||||
coconuts = (coconuts / ns) * ns + 1;
|
||||
while (true) {
|
||||
auto nc = coconuts;
|
||||
foreach (s; 1..ns+1) {
|
||||
if (nc % ns == 1) {
|
||||
hidden[s-1] = nc/ns;
|
||||
nc -= hidden[s-1] + 1;
|
||||
if (s==ns && nc%ns==0) {
|
||||
writeln(ns, " sailors require a minimum of ", coconuts, " coconuts");
|
||||
foreach (t; 1..ns+1) {
|
||||
writeln("\tSailor ", t, " hides ", hidden[t - 1]);
|
||||
}
|
||||
writeln("\tThe monkey gets ", ns);
|
||||
writeln("\tFinally, each sailor takes ", nc / ns);
|
||||
continue outer;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
coconuts += ns;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
defmodule RC do
|
||||
def valid?(sailor, nuts), do: valid?(sailor, nuts, sailor)
|
||||
|
||||
def valid?(sailor, nuts, 0), do: nuts > 0 and rem(nuts,sailor) == 0
|
||||
def valid?(sailor, nuts, _) when rem(nuts,sailor)!=1, do: false
|
||||
def valid?(sailor, nuts, i) do
|
||||
valid?(sailor, nuts - div(nuts,sailor) - 1, i-1)
|
||||
end
|
||||
end
|
||||
|
||||
Enum.each([5,6], fn sailor ->
|
||||
nuts = Enum.find(Stream.iterate(sailor, &(&1+1)), fn n -> RC.valid?(sailor, n) end)
|
||||
IO.puts "\n#{sailor} sailors => #{nuts} coconuts"
|
||||
Enum.reduce(0..sailor, nuts, fn _,n ->
|
||||
{d, r} = {div(n,sailor), rem(n,sailor)}
|
||||
IO.puts " #{inspect [n, d, r]}"
|
||||
n - 1 - d
|
||||
end)
|
||||
end)
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
defmodule Sailor do
|
||||
def coconuts(sailor), do: coconuts(sailor, sailor)
|
||||
defp coconuts(sailor, nuts) do
|
||||
if n = do_coconuts(sailor, nuts, sailor), do: n, else: coconuts(sailor, nuts+sailor)
|
||||
end
|
||||
|
||||
defp do_coconuts(_sailor, nuts, 0), do: nuts
|
||||
defp do_coconuts(sailor, nuts, _) when rem(nuts, sailor-1) != 0, do: nil
|
||||
defp do_coconuts(sailor, nuts, i) do
|
||||
do_coconuts(sailor, nuts + div(nuts, sailor-1) + 1, i-1)
|
||||
end
|
||||
end
|
||||
|
||||
Enum.each(2..9, fn sailor ->
|
||||
IO.puts "#{sailor}: #{Sailor.coconuts(sailor)}"
|
||||
end)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
: total
|
||||
over * over 1- rot 0 ?do
|
||||
over over mod if dup xor swap leave else over over / 1+ rot + swap then
|
||||
loop drop
|
||||
;
|
||||
|
||||
: sailors
|
||||
1+ 2 ?do
|
||||
1 begin i over total dup 0= while drop 1+ repeat cr i 0 .r ." : " . .
|
||||
loop
|
||||
;
|
||||
|
||||
9 sailors
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
Dim As Integer cocos = 11
|
||||
|
||||
For ns As Integer = 2 To 9
|
||||
Dim As Integer oculta(ns)
|
||||
cocos = Int(cocos / ns) * ns + 1
|
||||
Do
|
||||
Dim As Integer nc = cocos
|
||||
For s As Integer = 1 To ns+1
|
||||
If nc Mod ns = 1 Then
|
||||
oculta(s-1) = Int(nc / ns)
|
||||
nc = nc - (oculta(s-1) + 1)
|
||||
If s = ns And Not (nc Mod ns) Then
|
||||
Print ns; " marineros requieren un m¡nimo de"; cocos; " cocos"
|
||||
For t As Integer = 1 To ns
|
||||
Print !"\tEl marinero"; t; " se esconde"; oculta(t - 1)
|
||||
Next t
|
||||
Print !"\tEl mono obtiene"; ns
|
||||
Print !"\tFinalmente, cada marinero se lleva"; Int(nc / ns); !"\n"
|
||||
Exit Do
|
||||
End If
|
||||
Else
|
||||
Exit For
|
||||
End If
|
||||
Next s
|
||||
cocos += ns
|
||||
Loop
|
||||
Next ns
|
||||
Sleep
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
coconuts := 11
|
||||
outer:
|
||||
for ns := 2; ns < 10; ns++ {
|
||||
hidden := make([]int, ns)
|
||||
coconuts = (coconuts/ns)*ns + 1
|
||||
for {
|
||||
nc := coconuts
|
||||
for s := 1; s <= ns; s++ {
|
||||
if nc%ns == 1 {
|
||||
hidden[s-1] = nc / ns
|
||||
nc -= hidden[s-1] + 1
|
||||
if s == ns && nc%ns == 0 {
|
||||
fmt.Println(ns, "sailors require a minimum of", coconuts, "coconuts")
|
||||
for t := 1; t <= ns; t++ {
|
||||
fmt.Println("\tSailor", t, "hides", hidden[t-1])
|
||||
}
|
||||
fmt.Println("\tThe monkey gets", ns)
|
||||
fmt.Println("\tFinally, each sailor takes", nc/ns, "\b\n")
|
||||
continue outer
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
coconuts += ns
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import Control.Monad ((>=>))
|
||||
import Data.Maybe (mapMaybe)
|
||||
import System.Environment (getArgs)
|
||||
|
||||
-- Takes the number of sailors and the final number of coconuts. Returns
|
||||
-- Just the associated initial number of coconuts and Nothing otherwise.
|
||||
tryFor :: Int -> Int -> Maybe Int
|
||||
tryFor s = foldr (>=>) pure $ replicate s step
|
||||
where
|
||||
step n
|
||||
| n `mod` (s - 1) == 0 = Just $ n * s `div` (s - 1) + 1
|
||||
| otherwise = Nothing
|
||||
|
||||
-- Gets the number of sailors from the first command-line argument and
|
||||
-- assumes 5 as a default if none is given. Then uses tryFor to find the
|
||||
-- smallest solution.
|
||||
main :: IO ()
|
||||
main = do
|
||||
args <- getArgs
|
||||
let n =
|
||||
case args of
|
||||
[] -> 5
|
||||
s:_ -> read s
|
||||
a = head . mapMaybe (tryFor n) $ [n,2 * n ..]
|
||||
print a
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
I.(=<.)%&5 verb def'4*(y-1)%5'^:5 i.10000
|
||||
3121
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
I.(=<.)%&6 verb def'5*(y-1)%6'^:6 i.1000000
|
||||
233275 513211 793147
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
public class Test {
|
||||
|
||||
static boolean valid(int n, int nuts) {
|
||||
for (int k = n; k != 0; k--, nuts -= 1 + nuts / n)
|
||||
if (nuts % n != 1)
|
||||
return false;
|
||||
return nuts != 0 && (nuts % n == 0);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int x = 0;
|
||||
for (int n = 2; n < 10; n++) {
|
||||
while (!valid(n, x))
|
||||
x++;
|
||||
System.out.printf("%d: %d%n", n, x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
(function () {
|
||||
|
||||
// wakeSplit :: Int -> Int -> Int -> Int
|
||||
function wakeSplit(intNuts, intSailors, intDepth) {
|
||||
var nDepth = intDepth !== undefined ? intDepth : intSailors,
|
||||
portion = Math.floor(intNuts / intSailors),
|
||||
remain = intNuts % intSailors;
|
||||
|
||||
return 0 >= portion || remain !== (nDepth ? 1 : 0) ?
|
||||
null : nDepth ? wakeSplit(
|
||||
intNuts - portion - remain, intSailors, nDepth - 1
|
||||
) : intNuts;
|
||||
}
|
||||
|
||||
// TEST for 5, 6, and 7 intSailors
|
||||
return [5, 6, 7].map(function (intSailors) {
|
||||
var intNuts = intSailors;
|
||||
|
||||
while (!wakeSplit(intNuts, intSailors)) intNuts += 1;
|
||||
|
||||
return intNuts;
|
||||
});
|
||||
})();
|
||||
|
|
@ -0,0 +1 @@
|
|||
[3121, 233275, 823537]
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
(() => {
|
||||
"use strict";
|
||||
|
||||
// wakeSplit :: Int -> Int -> Int -> Int
|
||||
const wakeSplit = intSailors =>
|
||||
(intNuts, intDepth) => {
|
||||
const
|
||||
nDepth = intDepth !== undefined ? (
|
||||
intDepth
|
||||
) : intSailors,
|
||||
portion = Math.floor(intNuts / intSailors),
|
||||
remain = intNuts % intSailors;
|
||||
|
||||
return 0 >= portion || remain !== (
|
||||
nDepth ? (
|
||||
1
|
||||
) : 0
|
||||
) ? (
|
||||
null
|
||||
) : nDepth ? (
|
||||
wakeSplit(
|
||||
intSailors
|
||||
)(
|
||||
intNuts - portion - remain,
|
||||
nDepth - 1
|
||||
)
|
||||
) : intNuts;
|
||||
};
|
||||
|
||||
// ---------------------- TEST -----------------------
|
||||
const main = () =>
|
||||
// TEST for 5, 6, and 7 Sailors
|
||||
[5, 6, 7].map(intSailors => {
|
||||
const intNuts = intSailors;
|
||||
|
||||
return until(
|
||||
wakeSplit(intNuts)
|
||||
)(x => 1 + x)(intNuts);
|
||||
});
|
||||
|
||||
|
||||
// --------------------- GENERIC ---------------------
|
||||
|
||||
// until :: (a -> Bool) -> (a -> a) -> a -> a
|
||||
const until = p =>
|
||||
// The value resulting from repeated applications
|
||||
// of f to the seed value x, terminating when
|
||||
// that result returns true for the predicate p.
|
||||
f => x => {
|
||||
let v = x;
|
||||
|
||||
while (!p(v)) {
|
||||
v = f(v);
|
||||
}
|
||||
|
||||
return v;
|
||||
};
|
||||
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
|
|
@ -0,0 +1 @@
|
|||
[3121, 233275, 823537]
|
||||
|
|
@ -0,0 +1 @@
|
|||
def until(cond; next): def _until: if cond then . else (next|_until) end; _until;
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# If n (the input) is an admissible number of coconuts with respect to
|
||||
# the night-time squirreling away of the coconuts by "sailors" sailors, then give 1 to the
|
||||
# monkey, let one sailor squirrel away (1/sailors) coconuts, and yield the remaining number;
|
||||
# otherwise, return false:
|
||||
def squirrel(sailors):
|
||||
def admissible: if . then (. % sailors) == 1 else . end;
|
||||
|
||||
if admissible then . - ((. - 1) / sailors) - 1
|
||||
else false
|
||||
end;
|
||||
|
||||
def nighttime(sailors):
|
||||
reduce range(0; sailors) as $i (.; squirrel(sailors));
|
||||
|
||||
def morning(sailors):
|
||||
if . then (. % sailors) == 0
|
||||
else false
|
||||
end;
|
||||
|
||||
# Test whether the input is a valid number of coconuts with respect to the story:
|
||||
def valid(sailors): nighttime(sailors) | morning(sailors);
|
||||
|
|
@ -0,0 +1 @@
|
|||
1 | until( valid(5); . + 1)
|
||||
|
|
@ -0,0 +1 @@
|
|||
1 | until( valid(6); . + 1)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# If n (the input) is the number of coconuts remaining after
|
||||
# the surreptitious squirreling away by one sailor,
|
||||
# then emit the number of coconuts which that sailor originally
|
||||
# saw if n is admissible, otherwise emit false:
|
||||
def unsquirrel(sailors):
|
||||
if . and (. % (sailors - 1) == 0)
|
||||
then 1 + (sailors * (. / (sailors - 1)))
|
||||
else false
|
||||
end;
|
||||
|
||||
# If in the end each sailor received n coconuts (where n is the input), how many coconuts
|
||||
# were there initially?
|
||||
def backwards(sailors):
|
||||
reduce range(0; sailors) as $i (. * sailors; unsquirrel(sailors));
|
||||
|
||||
def solve:
|
||||
. as $sailors
|
||||
# state: [ final_number_per_sailor, original_number_of_coconuts]
|
||||
| [-1] | until( .[1]; .[0] += 1 | .[1] = (.[0] | backwards($sailors)) )
|
||||
| "With \($sailors) sailors, there were originally \(.[1]) coconuts,"+
|
||||
" and each sailor finally ended up with \(.[0])." ;
|
||||
|
||||
range(2;9) | solve
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
With 2 sailors, there were originally 3 coconuts, and each sailor finally ended up with 0.
|
||||
With 3 sailors, there were originally 25 coconuts, and each sailor finally ended up with 2.
|
||||
With 4 sailors, there were originally 765 coconuts, and each sailor finally ended up with 60.
|
||||
With 5 sailors, there were originally 3121 coconuts, and each sailor finally ended up with 204.
|
||||
With 6 sailors, there were originally 233275 coconuts, and each sailor finally ended up with 13020.
|
||||
With 7 sailors, there were originally 823537 coconuts, and each sailor finally ended up with 39990.
|
||||
With 8 sailors, there were originally 117440505 coconuts, and each sailor finally ended up with 5044200.
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
function validnutsforsailors(sailors, finalpile)
|
||||
for i in sailors:-1:1
|
||||
if finalpile % sailors != 1
|
||||
return false
|
||||
end
|
||||
finalpile -= Int(floor(finalpile/sailors) + 1)
|
||||
end
|
||||
(finalpile != 0) && (finalpile % sailors == 0)
|
||||
end
|
||||
|
||||
function runsim()
|
||||
println("Sailors Starting Pile")
|
||||
for sailors in 2:9
|
||||
finalcount = 0
|
||||
while validnutsforsailors(sailors, finalcount) == false
|
||||
finalcount += 1
|
||||
end
|
||||
println("$sailors $finalcount")
|
||||
end
|
||||
end
|
||||
|
||||
runsim()
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// version 1.1.2
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
var coconuts = 11
|
||||
outer@ for (ns in 2..9) {
|
||||
val hidden = IntArray(ns)
|
||||
coconuts = (coconuts / ns) * ns + 1
|
||||
while (true) {
|
||||
var nc = coconuts
|
||||
for (s in 1..ns) {
|
||||
if (nc % ns == 1) {
|
||||
hidden[s - 1] = nc / ns
|
||||
nc -= hidden[s - 1] + 1
|
||||
if (s == ns && nc % ns == 0) {
|
||||
println("$ns sailors require a minimum of $coconuts coconuts")
|
||||
for (t in 1..ns) println("\tSailor $t hides ${hidden[t - 1]}")
|
||||
println("\tThe monkey gets $ns")
|
||||
println("\tFinally, each sailor takes ${nc / ns}\n")
|
||||
continue@outer
|
||||
}
|
||||
}
|
||||
else break
|
||||
}
|
||||
coconuts += ns
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
function valid(n,nuts)
|
||||
local k = n
|
||||
local i = 0
|
||||
while k ~= 0 do
|
||||
if (nuts % n) ~= 1 then
|
||||
return false
|
||||
end
|
||||
k = k - 1
|
||||
nuts = nuts - 1 - math.floor(nuts / n)
|
||||
end
|
||||
return nuts ~= 0 and (nuts % n == 0)
|
||||
end
|
||||
|
||||
for n=2, 9 do
|
||||
local x = 0
|
||||
while not valid(n, x) do
|
||||
x = x + 1
|
||||
end
|
||||
print(n..": "..x)
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
ClearAll[SequenceOk]
|
||||
SequenceOk[n_, k_] := Module[{m = n, q, r, valid = True},
|
||||
Do[
|
||||
{q, r} = QuotientRemainder[m, k];
|
||||
If[r != 1,
|
||||
valid = False;
|
||||
Break[];
|
||||
];
|
||||
m -= q + 1
|
||||
,
|
||||
{k}
|
||||
];
|
||||
If[Mod[m, k] != 0,
|
||||
valid = False
|
||||
];
|
||||
valid
|
||||
]
|
||||
i = 1;
|
||||
While[! SequenceOk[i, 5], i++]
|
||||
i
|
||||
|
||||
i = 1;
|
||||
While[! SequenceOk[i, 6], i++]
|
||||
i
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
MODULE Coconuts;
|
||||
FROM FormatString IMPORT FormatString;
|
||||
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
|
||||
|
||||
CONST MAX_SAILORS = 9;
|
||||
|
||||
PROCEDURE Scenario(coconuts,ns : INTEGER);
|
||||
VAR
|
||||
buf : ARRAY[0..63] OF CHAR;
|
||||
hidden : ARRAY[0..MAX_SAILORS-1] OF INTEGER;
|
||||
nc,s,t : INTEGER;
|
||||
BEGIN
|
||||
IF ns>MAX_SAILORS THEN RETURN END;
|
||||
|
||||
coconuts := (coconuts DIV ns) * ns + 1;
|
||||
LOOP
|
||||
nc := coconuts;
|
||||
FOR s:=1 TO ns DO
|
||||
IF nc MOD ns = 1 THEN
|
||||
hidden[s-1] := nc DIV ns;
|
||||
nc := nc - hidden[s-1] - 1;
|
||||
IF (s=ns) AND (nc MOD ns = 0) THEN
|
||||
FormatString("%i sailors require a minimum of %i coconuts\n", buf, ns, coconuts);
|
||||
WriteString(buf);
|
||||
|
||||
FOR t:=1 TO ns DO
|
||||
FormatString("\tSailor %i hides %i\n", buf, t, hidden[t-1]);
|
||||
WriteString(buf)
|
||||
END;
|
||||
|
||||
FormatString("\tThe monkey gets %i\n", buf, ns);
|
||||
WriteString(buf);
|
||||
FormatString("\tFinally, each sailor takes %i\n", buf, nc DIV ns);
|
||||
WriteString(buf);
|
||||
RETURN
|
||||
END
|
||||
ELSE
|
||||
BREAK
|
||||
END
|
||||
END;
|
||||
INC(coconuts,ns)
|
||||
END
|
||||
END Scenario;
|
||||
|
||||
VAR
|
||||
ns : INTEGER;
|
||||
BEGIN
|
||||
FOR ns:=2 TO MAX_SAILORS DO
|
||||
Scenario(11,ns);
|
||||
END;
|
||||
|
||||
ReadChar
|
||||
END Coconuts.
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import strformat
|
||||
|
||||
var coconuts = 11
|
||||
|
||||
for ns in 2..9:
|
||||
var hidden = newSeq[int](ns)
|
||||
coconuts = (coconuts div ns) * ns + 1
|
||||
block Search:
|
||||
while true:
|
||||
var nc = coconuts
|
||||
for sailor in 1..ns:
|
||||
if nc mod ns == 1:
|
||||
hidden[sailor-1] = nc div ns
|
||||
dec nc, hidden[sailor-1] + 1
|
||||
if sailor == ns and nc mod ns == 0:
|
||||
echo &"{ns} sailors require a minimum of {coconuts} coconuts."
|
||||
for t in 1..ns:
|
||||
echo &"\tSailor {t} hides {hidden[t-1]}."
|
||||
echo &"\tThe monkey gets {ns}."
|
||||
echo &"\tFinally, each sailor takes {nc div ns}.\n"
|
||||
break Search # Done. Continue with more sailors or exit.
|
||||
else:
|
||||
break # Failed. Continue search with more coconuts.
|
||||
inc coconuts, ns
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
class Program {
|
||||
function : Total(n : Int, nuts : Int) ~ Int {
|
||||
k := 0;
|
||||
for(nuts *= n; k < n; k++;) {
|
||||
if(nuts % (n-1) <> 0) { return 0; };
|
||||
nuts += nuts / (n-1) + 1;
|
||||
};
|
||||
|
||||
return nuts;
|
||||
}
|
||||
|
||||
function : Main(args : String[]) ~ Nil {
|
||||
for(n := 2; n < 10; n++;) {
|
||||
x := 0; t := 0;
|
||||
do {
|
||||
x++;
|
||||
t := Total(n, x);
|
||||
}
|
||||
while(t = 0);
|
||||
"{$n}: {$t}, {$x}"->PrintLine();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
use bigint;
|
||||
|
||||
for $sailors (1..15) { check( $sailors, coconuts( 0+$sailors ) ) }
|
||||
|
||||
sub is_valid {
|
||||
my($sailors, $nuts) = @_;
|
||||
return 0, 0 if $sailors == 1 and $nuts == 1;
|
||||
my @shares;
|
||||
for (1..$sailors) {
|
||||
return () unless ($nuts % $sailors) == 1;
|
||||
push @shares, int ($nuts-1)/$sailors;
|
||||
$nuts -= (1 + int $nuts/$sailors);
|
||||
}
|
||||
push @shares, int $nuts/$sailors;
|
||||
return @shares if !($nuts % $sailors);
|
||||
}
|
||||
|
||||
sub check {
|
||||
my($sailors, $coconuts) = @_;
|
||||
my @suffix = ('th', 'st', 'nd', 'rd', ('th') x 6, ('th') x 10);
|
||||
my @piles = is_valid($sailors, $coconuts);
|
||||
if (@piles) {
|
||||
print "\nSailors $sailors: Coconuts $coconuts:\n";
|
||||
for my $k (0..-1 + $#piles) {
|
||||
print $k+1 . $suffix[$k+1] . " takes " . $piles[$k] . ", gives 1 to the monkey.\n"
|
||||
}
|
||||
print "The next morning, each sailor takes " . $piles[-1] . "\nwith none left over for the monkey.\n";
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
sub coconuts {
|
||||
my($sailors) = @_;
|
||||
if ($sailors % 2 == 0 ) { ($sailors ** $sailors - 1) * ($sailors - 1) }
|
||||
else { $sailors ** $sailors - $sailors + 1 }
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">sailors</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">sm1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sailors</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">sm1</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- edge condition for solve(1) [ avoid /0 ]</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sailors</span>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">sailors</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1_000_000_000</span> <span style="color: #008080;">by</span> <span style="color: #000000;">sailors</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- morning pile divisible by #sailors</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">sailors</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- see if all of the sailors could..</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sm1</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- ..have pushed together sm1 piles</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- (no: try a higher n)</span>
|
||||
<span style="color: #008080;">exit</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sailors</span><span style="color: #0000FF;">*</span><span style="color: #000000;">m</span><span style="color: #0000FF;">/</span><span style="color: #000000;">sm1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #000080;font-style:italic;">-- add sailor j's stash and one for the monkey</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">m</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Solution with %d sailors: %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">sailors</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">sailors</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span> <span style="color: #000080;font-style:italic;">-- one for the monkey</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">/=</span> <span style="color: #000000;">sailors</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Sailor #%d takes %d, giving 1 to the monkey and leaving %d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">*</span><span style="color: #000000;">sm1</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">*=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">sm1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"In the morning each sailor gets %d nuts\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">m</span><span style="color: #0000FF;">/</span><span style="color: #000000;">sailors</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">6</span><span style="color: #0000FF;">)</span>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
main ?=>
|
||||
between(2,9,N), % N: number of sailors
|
||||
once s(N),
|
||||
fail.
|
||||
main => true.
|
||||
|
||||
s(N) =>
|
||||
next_candidate(N+1,N,C), % C: original number of coconuts
|
||||
divide(N,N,C,Cr), % Cr: remainder
|
||||
printf("%d: original = %d, remainder = %d, final share = %d\n",N,C,Cr,Cr div N).
|
||||
|
||||
next_candidate(From,_Step,X) ?=> X = From.
|
||||
next_candidate(From,Step,X) => next_candidate(From+Step,Step,X).
|
||||
|
||||
divide(N,0,C,Cr) => C > 0, C mod N == 0, Cr = C.
|
||||
divide(N,I,C,Cr) =>
|
||||
(C-1) mod N == 0,
|
||||
Q = (C-1) div N,
|
||||
C1 = Q*(N-1),
|
||||
divide(N,I-1,C1,Cr).
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
def monkey_coconuts(sailors=5):
|
||||
"Parameterised the number of sailors using an inner loop including the last mornings case"
|
||||
nuts = sailors
|
||||
while True:
|
||||
n0, wakes = nuts, []
|
||||
for sailor in range(sailors + 1):
|
||||
portion, remainder = divmod(n0, sailors)
|
||||
wakes.append((n0, portion, remainder))
|
||||
if portion <= 0 or remainder != (1 if sailor != sailors else 0):
|
||||
nuts += 1
|
||||
break
|
||||
n0 = n0 - portion - remainder
|
||||
else:
|
||||
break
|
||||
return nuts, wakes
|
||||
|
||||
if __name__ == "__main__":
|
||||
for sailors in [5, 6]:
|
||||
nuts, wake_stats = monkey_coconuts(sailors)
|
||||
print("\nFor %i sailors the initial nut count is %i" % (sailors, nuts))
|
||||
print("On each waking, the nut count, portion taken, and monkeys share are:\n ",
|
||||
',\n '.join(repr(ws) for ws in wake_stats))
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
def wake_and_split(n0, sailors, depth=None):
|
||||
if depth is None:
|
||||
depth = sailors
|
||||
portion, remainder = divmod(n0, sailors)
|
||||
if portion <= 0 or remainder != (1 if depth else 0):
|
||||
return None
|
||||
else:
|
||||
return n0 if not depth else wake_and_split(n0 - portion - remainder, sailors, depth - 1)
|
||||
|
||||
|
||||
def monkey_coconuts(sailors=5):
|
||||
"Parameterised the number of sailors using recursion including the last mornings case"
|
||||
nuts = sailors
|
||||
while True:
|
||||
if wake_and_split(n0=nuts, sailors=sailors) is None:
|
||||
nuts += 1
|
||||
else:
|
||||
break
|
||||
return nuts
|
||||
|
||||
if __name__ == "__main__":
|
||||
for sailors in [5, 6]:
|
||||
nuts = monkey_coconuts(sailors)
|
||||
print("For %i sailors the initial nut count is %i" % (sailors, nuts))
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# gives one solution of (x,y) for a x + by = c
|
||||
def dioph(a, b, c):
|
||||
aa,bb,x,y = a, b, 0, 1
|
||||
|
||||
while True:
|
||||
q,a,b = a//b, b, a%b
|
||||
x,y = y - q*x, x
|
||||
if abs(a) == 1: break
|
||||
|
||||
if y*aa % bb != 1: y = -y
|
||||
x,y = y*c, (c - aa*y*c)//bb
|
||||
#assert(x*aa + y*bb == c)
|
||||
return x,y
|
||||
|
||||
# rems: what monkey got each turn
|
||||
# min_share: each sailor needs to get at least this many in the final round
|
||||
def calcnuts(rems, min_share = 0):
|
||||
n, r = len(rems) - 1, 0
|
||||
c = (n - 1)**n
|
||||
for x in rems: r,c = r + x*c, c//(n-1)*n
|
||||
|
||||
a, b = (n-1)**n, n**(n+1)
|
||||
x, y = dioph(a, -b, r)
|
||||
k = (min_share - y + a - 1)//a
|
||||
return x + k*b, y + k*a
|
||||
|
||||
def distribute(nuts, monkey_nuts):
|
||||
n = len(monkey_nuts) - 1
|
||||
print("\n%d sailors, %d nuts:"%(n, nuts))
|
||||
for r in monkey_nuts[:-1]:
|
||||
p = (nuts - r)//n
|
||||
print("\tNuts %d, hide %d, monkey gets %d" % (nuts, p, r))
|
||||
nuts = p*(n - 1)
|
||||
|
||||
r = monkey_nuts[-1]
|
||||
p = (nuts - r)//n
|
||||
print("Finally:\n\tNuts %d, each share %d, monkey gets %d" % (nuts, p, r))
|
||||
|
||||
for sailors in range(2, 10):
|
||||
monkey_loot = [1]*sailors + [0]
|
||||
distribute(calcnuts(monkey_loot, 1)[0], monkey_loot)
|
||||
|
||||
# many sailors, many nuts
|
||||
#for i in range(1, 5): print(10**i, calcnuts([1]*10**i + [0])[0])
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
coconutsProblem <- function(sailorCount)
|
||||
{
|
||||
stopifnot(sailorCount > 1) #Problem makes no sense otherwise
|
||||
initalCoconutCount <- sailorCount
|
||||
repeat
|
||||
{
|
||||
initalCoconutCount <- initalCoconutCount + 1
|
||||
coconutCount <- initalCoconutCount
|
||||
for(i in seq_len(sailorCount))
|
||||
{
|
||||
if(coconutCount %% sailorCount != 1) break
|
||||
coconutCount <- (coconutCount - 1) * (sailorCount - 1)/sailorCount
|
||||
if(i == sailorCount && coconutCount > 0 && coconutCount %% sailorCount == 0) return(initalCoconutCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
print(data.frame("Sailors" = 2:8, "Coconuts" = sapply(2:8, coconutsProblem)))
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
/*REXX program solves a riddle of 5 sailors, a pile of coconuts, and a monkey. */
|
||||
parse arg L H .; if L=='' then L= 5 /*L not specified? Then use default.*/
|
||||
if H=='' then H= 6 /*H " " " " default.*/
|
||||
/*{Tars is an old name for sailors.} */
|
||||
do n=L to H /*traipse through a number of sailors. */
|
||||
do $=0 while \valid(n, $) /*perform while not valid coconuts. */
|
||||
end /*$*/
|
||||
say 'sailors='n " coconuts="$ /*display number of sailors & coconuts.*/
|
||||
end /*n*/
|
||||
exit 0 /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
valid: procedure; parse arg n,nuts /*obtain the number sailors & coconuts.*/
|
||||
do k=n by -1 for n /*step through the possibilities. */
|
||||
if nuts//n \== 1 then return 0 /*Not one coconut left? No solution. */
|
||||
nuts=nuts - (1 + nuts % n) /*subtract number of coconuts from pile*/
|
||||
end /*k*/
|
||||
return (nuts \== 0) & \(nuts//n \== 0) /*see if number coconuts>0 & remainder.*/
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/*REXX program solves a riddle of 5 sailors, a pile of coconuts, and a monkey. */
|
||||
|
||||
do n=2 to 9 /*traipse through number of sailors. */
|
||||
do $=0; nuts= $ /*perform while not valid # coconuts. */
|
||||
do k=n by -1 for n /*step through the possibilities. */
|
||||
if nuts//n\==1 then iterate $ /*Not one coconut left? No solution.*/
|
||||
nuts= nuts - (1 + nuts % n) /*subtract number of coconuts from pile*/
|
||||
end /*k*/
|
||||
if (nuts\==0) & \(nuts//n\==0) then leave /*is this a solution to the riddle ? */
|
||||
end /*$*/
|
||||
say 'sailors='n " coconuts="$ /*display number of sailors & coconuts.*/
|
||||
end /*n*/ /*stick a fork in it, we're all done. */
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/*REXX program solves a riddle of 5 sailors, a pile of coconuts, and a monkey. */
|
||||
parse arg L H .; if L=='' then L= 2 /*L not specified? Then use default.*/
|
||||
if H=='' then H= 9 /*H " " " " " */
|
||||
do n=L to H /*traipse through the number of sailors*/
|
||||
do $=1 until t\==0; t= total(n, $) /*perform while number coconuts not 0. */
|
||||
end /*$*/
|
||||
say 'sailors='n " coconuts="t ' share='$
|
||||
end /*n*/
|
||||
exit 0 /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
total: procedure; parse arg n,nuts /*obtain the number sailors & coconuts.*/
|
||||
nuts= nuts * n /*multiple # nuts by number of sailors.*/
|
||||
nn= n - 1 /*NN is used as calculation shortcut. */
|
||||
do k=0 for n /*step through the possibilities. */
|
||||
if nuts//nn\==0 then return 0 /*Not one coconut left? No solution. */
|
||||
nuts= nuts + 1 + nuts % nn /*bump the number coconuts to the pile.*/
|
||||
end /*k*/
|
||||
return nuts /*see if number coconuts>0 & remainder.*/
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#lang racket
|
||||
|
||||
(define (wake-and-split nuts sailors depth wakes)
|
||||
(define-values (portion remainder) (quotient/remainder nuts sailors))
|
||||
(define monkey (if (zero? depth) 0 1))
|
||||
(define new-wakes (cons (list nuts portion remainder) wakes))
|
||||
(and (positive? portion)
|
||||
(= remainder monkey)
|
||||
(if (zero? depth)
|
||||
new-wakes
|
||||
(wake-and-split (- nuts portion remainder) sailors (sub1 depth) new-wakes))))
|
||||
|
||||
(define (sleep-and-split nuts sailors)
|
||||
(wake-and-split nuts sailors sailors '()))
|
||||
|
||||
(define (monkey_coconuts (sailors 5))
|
||||
(let loop ([nuts sailors])
|
||||
(or (sleep-and-split nuts sailors)
|
||||
(loop (add1 nuts)))))
|
||||
|
||||
(for ([sailors (in-range 5 7)])
|
||||
(define wakes (monkey_coconuts sailors))
|
||||
(printf "For ~a sailors the initial nut count is ~a\n" sailors (first (last wakes)))
|
||||
(map displayln (reverse wakes))
|
||||
(newline))
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
my @ones = flat 'th', 'st', 'nd', 'rd', 'th' xx 6;
|
||||
my @teens = 'th' xx 10;
|
||||
my @suffix = lazy flat (@ones, @teens, @ones xx 8) xx *;
|
||||
|
||||
# brute force the first six
|
||||
for 1 .. 6 -> $sailors { for $sailors .. * -> $coconuts { last if check( $sailors, $coconuts ) } }
|
||||
|
||||
# finesse 7 through 15
|
||||
for 7 .. 15 -> $sailors { next if check( $sailors, coconuts( $sailors ) ) }
|
||||
|
||||
sub is_valid ( $sailors is copy, $nuts is copy ) {
|
||||
return 0, 0 if $sailors == $nuts == 1;
|
||||
my @shares;
|
||||
for ^$sailors {
|
||||
return () unless $nuts % $sailors == 1;
|
||||
push @shares, ($nuts - 1) div $sailors;
|
||||
$nuts -= (1 + $nuts div $sailors);
|
||||
}
|
||||
push @shares, $nuts div $sailors;
|
||||
return @shares if !?($nuts % $sailors);
|
||||
}
|
||||
|
||||
sub check ($sailors, $coconuts) {
|
||||
if my @piles = is_valid($sailors, $coconuts) {
|
||||
say "\nSailors $sailors: Coconuts $coconuts:";
|
||||
for ^(@piles - 1) -> $k {
|
||||
say "{$k+1}@suffix[$k+1] takes @piles[$k], gives 1 to the monkey."
|
||||
}
|
||||
say "The next morning, each sailor takes @piles[*-1]\nwith none left over for the monkey.";
|
||||
return True;
|
||||
}
|
||||
False;
|
||||
}
|
||||
|
||||
multi sub coconuts ( $sailors where { $sailors % 2 == 0 } ) { ($sailors - 1) * ($sailors ** $sailors - 1) }
|
||||
multi sub coconuts ( $sailors where { $sailors % 2 == 1 } ) { $sailors ** $sailors - $sailors + 1 }
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
# Project : Sailors, coconuts and a monkey problem
|
||||
|
||||
scm(5)
|
||||
scm(6)
|
||||
|
||||
func scm(sailors)
|
||||
sm1 = sailors-1
|
||||
if sm1 = 0
|
||||
m = sailors
|
||||
else
|
||||
for n=sailors to 1000000000 step sailors
|
||||
m = n
|
||||
for j=1 to sailors
|
||||
if m % sm1 != 0
|
||||
m = 0
|
||||
exit
|
||||
ok
|
||||
m = sailors*m/sm1+1
|
||||
next
|
||||
if m != 0
|
||||
exit
|
||||
ok
|
||||
next
|
||||
ok
|
||||
see "Solution with " + sailors + " sailors: " + m + nl
|
||||
for i=1 to sailors
|
||||
m = m - 1
|
||||
m = m / sailors
|
||||
see "Sailor " + i + " takes " + m + " giving 1 to the monkey and leaving " + m*sm1 + nl
|
||||
m = m * sm1
|
||||
next
|
||||
see "In the morning each sailor gets " + m/sailors + " nuts" + nl + nl
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
def valid?(sailor, nuts)
|
||||
sailor.times do
|
||||
return false if (nuts % sailor) != 1
|
||||
nuts -= 1 + nuts / sailor
|
||||
end
|
||||
nuts > 0 and nuts % sailor == 0
|
||||
end
|
||||
|
||||
[5,6].each do |sailor|
|
||||
n = sailor
|
||||
n += 1 until valid?(sailor, n)
|
||||
puts "\n#{sailor} sailors => #{n} coconuts"
|
||||
(sailor+1).times do
|
||||
div, mod = n.divmod(sailor)
|
||||
puts " #{[n, div, mod]}"
|
||||
n -= 1 + div
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
def coconuts(sailor)
|
||||
sailor.step(by:sailor) do |nuts|
|
||||
flag = sailor.times do
|
||||
break if nuts % (sailor-1) != 0
|
||||
nuts += nuts / (sailor-1) + 1
|
||||
end
|
||||
return nuts if flag
|
||||
end
|
||||
end
|
||||
|
||||
(2..9).each do |sailor|
|
||||
puts "#{sailor}: #{coconuts(sailor)}"
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
def ng (sailors)
|
||||
def _ng (sailors, iter, start) #a method that given a possible answer applies the constraints of the tale to see if it is correct
|
||||
n, g = [start], [start/sailors]
|
||||
(1..iter).each{|s|
|
||||
g[s],rem = n[s-1].divmod(sailors-1)
|
||||
rem > 0 ? (return false) : n[s] = g[s]*sailors + 1
|
||||
}
|
||||
return [n,g]
|
||||
end
|
||||
n, start, step = [], sailors*(sailors-1), 1
|
||||
(2..sailors).each{|s|
|
||||
g=0; until n=_ng(sailors,s,start + g*step*sailors*(sailors-1)) do g+=1 end
|
||||
start,step = n[0][0], step*(sailors-1)
|
||||
}
|
||||
return n
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
(3..10).each{|sailors| puts "Number of sailors = #{sailors}"; p ng(sailors)}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
n = ng(100)
|
||||
(0..100).each{|g| puts "#{n[0][100-g]}:#{n[1][100-g]}"}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
object Sailors extends App {
|
||||
var x = 0
|
||||
|
||||
private def valid(n: Int, _nuts: Int): Boolean = {
|
||||
var nuts = _nuts
|
||||
for (k <- n until 0 by -1) {
|
||||
if (nuts % n != 1) return false
|
||||
nuts -= 1 + nuts / n
|
||||
}
|
||||
nuts != 0 && (nuts % n == 0)
|
||||
}
|
||||
|
||||
for (nSailors <- 2 until 10) {
|
||||
while (!valid(nSailors, x)) x += 1
|
||||
println(f"$nSailors%d: $x%d")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
func coconuts(sailors, monkeys=1) {
|
||||
if ((sailors < 2) || (monkeys < 1) || (sailors <= monkeys)) {
|
||||
return 0
|
||||
}
|
||||
var blue_cocos = sailors-1
|
||||
var pow_bc = blue_cocos**sailors
|
||||
var x_cocos = pow_bc
|
||||
while ((x_cocos-blue_cocos)%sailors || ((x_cocos-blue_cocos)/sailors < 1)) {
|
||||
x_cocos += pow_bc
|
||||
}
|
||||
return monkeys*(x_cocos / pow_bc * sailors**sailors - blue_cocos)
|
||||
}
|
||||
|
||||
2.to(9).each { |sailor|
|
||||
say "#{sailor}: #{coconuts(sailor)}";
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
proc assert {expr {msg ""}} { ;# for "static" assertions that throw nice errors
|
||||
if {![uplevel 1 [list expr $expr]]} {
|
||||
if {$msg eq ""} {
|
||||
catch {set msg "{[uplevel 1 [list subst -noc $expr]]}"}
|
||||
}
|
||||
throw {ASSERT ERROR} "{$expr} $msg"
|
||||
}
|
||||
}
|
||||
|
||||
proc divmod {a b} {
|
||||
list [expr {$a / $b}] [expr {$a % $b}]
|
||||
}
|
||||
|
||||
proc overnight {ns nn} {
|
||||
set result {}
|
||||
for {set s 0} {$s < $ns} {incr s} {
|
||||
lassign [divmod $nn $ns] q r
|
||||
assert {$r eq 1} "Incorrect remainder in round $s (expected 1, got $r)"
|
||||
set nn [expr {$q*($ns-1)}]
|
||||
lappend result $s $q $r $nn
|
||||
}
|
||||
lassign [divmod $nn $ns] q r
|
||||
assert {$r eq 0} "Incorrect remainder at end (expected 0, got $r)"
|
||||
return $result
|
||||
}
|
||||
|
||||
proc minnuts {nsailors} {
|
||||
while 1 {
|
||||
incr nnuts
|
||||
try {
|
||||
set result [overnight $nsailors $nnuts]
|
||||
} on error {} {
|
||||
# continue
|
||||
} on ok {} {
|
||||
break
|
||||
}
|
||||
}
|
||||
puts "$nsailors: $nnuts"
|
||||
foreach {sailor takes gives leaves} $result {
|
||||
puts " Sailor #$sailor takes $takes, giving $gives to the monkey and leaves $leaves"
|
||||
}
|
||||
puts "In the morning, each sailor gets [expr {$leaves/$nsailors}] nuts"
|
||||
}
|
||||
|
||||
|
||||
foreach n {5 6} {
|
||||
puts "Solution with $n sailors:"
|
||||
minnuts $n
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
Option Explicit
|
||||
Public Sub coconuts()
|
||||
Dim sailors As Integer
|
||||
Dim share As Long
|
||||
Dim finalshare As Integer
|
||||
Dim minimum As Long, pile As Long
|
||||
Dim i As Long, j As Integer
|
||||
Debug.Print "Sailors", "Pile", "Final share"
|
||||
For sailors = 2 To 6
|
||||
i = 1
|
||||
Do While True
|
||||
pile = i
|
||||
For j = 1 To sailors
|
||||
If (pile - 1) Mod sailors <> 0 Then Exit For
|
||||
share = (pile - 1) / sailors
|
||||
pile = pile - share - 1
|
||||
Next j
|
||||
If j > sailors Then
|
||||
If share Mod sailors = 0 And share > 0 Then
|
||||
minimum = i
|
||||
finalshare = pile / sailors
|
||||
Exit Do
|
||||
End If
|
||||
End If
|
||||
i = i + 1
|
||||
Loop
|
||||
Debug.Print sailors, minimum, finalshare
|
||||
Next sailors
|
||||
End Sub
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
var coconuts = 11
|
||||
for (ns in 2..9) {
|
||||
var hidden = List.filled(ns, 0)
|
||||
coconuts = (coconuts/ns).floor * ns + 1
|
||||
while (true) {
|
||||
var nc = coconuts
|
||||
var outer = false
|
||||
for (s in 1..ns) {
|
||||
if (nc%ns == 1) {
|
||||
hidden[s-1] = (nc/ns).floor
|
||||
nc = nc - hidden[s-1] - 1
|
||||
if (s == ns && nc%ns == 0) {
|
||||
System.print("%(ns) sailors require a minimum of %(coconuts) coconuts")
|
||||
for (t in 1..ns) System.print("\tSailor %(t) hides %(hidden[t-1])")
|
||||
System.print("\tThe monkey gets %(ns)")
|
||||
System.print("\tFinally, each sailor takes %((nc/ns).floor)\n")
|
||||
outer = true
|
||||
break
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if (outer) break
|
||||
coconuts = coconuts + ns
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
coconuts = 11
|
||||
|
||||
for ns = 2 to 9
|
||||
dim hidden(ns)
|
||||
coconuts = int(coconuts / ns) * ns + 1
|
||||
do
|
||||
nc = coconuts
|
||||
for s = 1 to ns+1
|
||||
if mod(nc, ns) = 1 then
|
||||
hidden(s-1) = int(nc / ns)
|
||||
nc = nc - (hidden(s-1) + 1)
|
||||
if s = ns and not mod(nc, ns) then
|
||||
print ns, " sailors require a minimum of ", coconuts, " coconuts"
|
||||
for t = 1 to ns
|
||||
print "\tSailor ", t, " hides ", hidden(t - 1)
|
||||
next
|
||||
print "\tThe monkey gets ", ns
|
||||
print "\tFinally, each sailor takes ", int(nc / ns), "\n"
|
||||
break 2
|
||||
end if
|
||||
else
|
||||
break
|
||||
end if
|
||||
next
|
||||
coconuts = coconuts + ns
|
||||
loop
|
||||
next
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
fcn monkey_coconuts(sailors=5){
|
||||
nuts,wakes:=sailors,List();
|
||||
while(True){
|
||||
n0:=nuts; wakes.clear();
|
||||
foreach sailor in (sailors + 1){
|
||||
portion, remainder := n0.divr(sailors);
|
||||
wakes.append(T(n0, portion, remainder));
|
||||
if(portion <= 0 or remainder != (sailor != sailors).toInt()){
|
||||
nuts += 1;
|
||||
break;
|
||||
}
|
||||
n0 = n0 - portion - remainder;
|
||||
}
|
||||
fallthrough{ break }
|
||||
}
|
||||
|
||||
return(nuts, wakes)
|
||||
}
|
||||
foreach sailors in ([5..6]){
|
||||
nuts, wake_stats := monkey_coconuts(sailors);
|
||||
println("For %d sailors the initial nut count is %,d".fmt(sailors, nuts));
|
||||
println("On each waking, the nut count, portion taken, and monkeys share are:\n ",
|
||||
wake_stats.concat("\n "));
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
fcn total(n, nuts){
|
||||
nuts *= n;
|
||||
foreach k in (n){
|
||||
if (nuts % (n-1)) return(0);
|
||||
nuts += nuts / (n-1) + 1;
|
||||
}
|
||||
nuts;
|
||||
}
|
||||
|
||||
println("sailers: original pile, final share");
|
||||
foreach n,x in ([2..9],[1..]){
|
||||
if(t := total(n, x)){
|
||||
print("%d: %d\t%d\n".fmt(n, t, x));
|
||||
break;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue