Author Topic: Sailors and Coconuts Rosetta Code  (Read 3367 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Sailors and Coconuts Rosetta Code
« on: July 03, 2021, 11:04:33 pm »
http://rosettacode.org/wiki/Sailors,_coconuts_and_a_monkey_problem

With the present limit on main For loop, you can do 6 sailors:
Code: QB64: [Select]
  1. Input "Please enter number of sailors that collect coconuts "; s
  2. For i = 1 To 250000
  3.     n = i
  4.     For j = 1 To s
  5.         If n Mod s = 1 Then
  6.             n = n - Int(n / s) - 1
  7.         Else
  8.             GoTo skip
  9.         End If
  10.     Next
  11.     If n Mod s = 0 Then Print i: End
  12.     skip:
  13.  

PS for once FreeBasic follows QB64, see Word Search at RC. :)
« Last Edit: July 03, 2021, 11:08:03 pm by bplus »

Offline david_uwi

  • Newbie
  • Posts: 71
    • View Profile
Re: Sailors and Coconuts Rosetta Code
« Reply #1 on: July 04, 2021, 09:41:04 am »
What an interesting problem to attempt to code. Perhaps beginners should try it!
Anyway here's mine (of course it is set for 9 sailors) n is the number of sailors.
Code: QB64: [Select]
  1. n = 9
  2. FOR i = n TO 100000000
  3.     k = i * n + 1
  4.     m = n
  5.     DO UNTIL m = 1
  6.         m = m - 1
  7.         k = ((k - 1) * (n - 1)) / n
  8.         IF k MOD n <> 1 THEN 10
  9.     LOOP
  10.     k = ((k - 1) * (n - 1)) / n
  11.     IF k MOD n = 0 THEN PRINT i * n + 1: EXIT FOR
  12. 10 NEXT i

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sailors and Coconuts Rosetta Code
« Reply #2 on: July 05, 2021, 07:57:54 am »
@david_uwi

Interesting!

Dont have much time for study, how does this line:
Code: QB64: [Select]
  1. k = ((k - 1) * (n - 1)) / n

Compare to my:
Code: QB64: [Select]
  1. n = n - Int(n / s) - 1

I wonder if we are doing same thing or something really different?

I saw Ruby with 100 Sailors, they must have speedier way to do the tests going up through numbers.
« Last Edit: July 05, 2021, 08:00:41 am by bplus »

Offline david_uwi

  • Newbie
  • Posts: 71
    • View Profile
Re: Sailors and Coconuts Rosetta Code
« Reply #3 on: July 05, 2021, 01:43:41 pm »
Those two lines seem completely different. I started to wonder if approaching the problem from the other end is quicker - start with the final number of coconuts and work backwards. It is about 3 times quicker.
Code: QB64: [Select]
  1. tt = TIMER
  2. n = 9
  3. FOR i = n TO 20000000
  4.     k = i * n
  5.     m = n
  6.     DO UNTIL m = 0
  7.         m = m - 1
  8.         k = (k + 1) * n / (n - 1)
  9.         IF k MOD n <> 1 THEN 20
  10.     LOOP
  11.     PRINT k
  12.     EXIT FOR
  13. 20 NEXT i
  14.  
  15.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: Sailors and Coconuts Rosetta Code
« Reply #4 on: September 05, 2021, 01:50:04 am »
While working on Rosetta Code challenges I was reminded of this one and could not find my QB64 code for what I had started.

So I went back to Syntax Bomb and copied a couple of posts, and now I found the generalized one here in this thread and refining the presentation report for 2 to 9 sailors:
Code: QB64: [Select]
  1. _Title "Sailors, coconuts and a monkey - Rosetta Code" 'b+ discussed at Syntax Bomb 2021-07-04
  2. ' ref   https://www.syntaxbomb.com/smallbasic/sailors-and-coconuts-problem/msg347051139/#msg347051139
  3.  
  4. 'OK here is the actual problem presented at Rosetta Code:
  5. ' ref   http://rosettacode.org/wiki/Sailors,_coconuts_and_a_monkey_problem
  6.  
  7. 'So we want a special number that keeps dividing by 5 and getting 1 left over (for the monkey 5 times at night)
  8. 'subtract the 5th + the 1 leftover 5 times but not in the morning of the final divy monkey gets none because 5
  9. 'divides final number. Turns out to be 3121.
  10.  
  11. 'Before you can understand the problem it must be presented to you correctly, I didn't get the problem presented correctly.
  12.  
  13. 'Here's a case where QB64 and SmallBASIC work the same!
  14. 'For i = 1 To 4000
  15. '    If i Mod 5 = 1 Then
  16. '        i2 = i - Int(i / 5) - 1
  17. '        If i2 Mod 5 = 1 Then
  18. '            i3 = i2 - Int(i2 / 5) - 1
  19. '            If i3 Mod 5 = 1 Then
  20. '                i4 = i3 - Int(i3 / 5) - 1
  21. '                If i4 Mod 5 = 1 Then
  22. '                    i5 = i4 - Int(i4 / 5) - 1
  23. '                    If i5 Mod 5 = 1 Then
  24. '                        i6 = i5 - Int(i5 / 5) - 1
  25. '                        If i6 Mod 5 = 0 Then
  26. '                            Print i
  27. '                        End If
  28. '                    End If
  29. '                End If
  30. '            End If
  31. '        End If
  32. '    End If
  33. 'Next
  34.  
  35.  
  36. ' ref  https://www.syntaxbomb.com/smallbasic/sailors-and-coconuts-problem/msg347051141/#msg347051141
  37.  
  38.  
  39. 'OK I have it generalized for s sailors, at least this code works correctly for 5.
  40.  
  41. '   A slight difference between QB64 and SmallBASIC for label makers:
  42.  
  43. 'Input "Please enter number of sailors that collect coconuts "; s
  44. 'If s = 6 Then limit = 250000
  45. 'If s < 6 Then limit = 4000
  46. 'For i = 1 To limit
  47. '    n = i
  48. '    For j = 1 To s
  49. '        If n Mod s = 1 Then
  50. '            n = n - Int(n / s) - 1
  51. '        Else
  52. '            GoTo skip
  53. '        End If
  54. '    Next
  55. '    If n Mod s = 0 Then Print i: Exit For
  56. '    skip: ' <<< for SmallBASIC change this line to label skip
  57. 'Next
  58.  
  59. '    PS might have to put a higher limit for i in first For loop when sailors s exceed 5.
  60.  
  61. ' Now Sunday, 2021-09-05 refined the generalized version to show what each sailor takes at night
  62. ' and then the final divy.
  63. Open "Report on Sailors Coconuts and a Monkey.txt" For Output As #1
  64. monkey = 1
  65. For TotalSailors = 2 To 9
  66.     For coconuts = 1 To 500000000
  67.         n = coconuts
  68.         If n Mod 1000000 = 0 Then Cls: Print "Testing" + Str$(n) + " coconuts..."
  69.         report$ = Chr$(10) + Str$(TotalSailors) + " sailors require a minimum of " + _Trim$(Str$(coconuts)) + " coconuts." + Chr$(10)
  70.         For sailor = 1 To TotalSailors
  71.             If n Mod TotalSailors = 1 Then
  72.                 take = Int(n / TotalSailors)
  73.                 If take = 0 Then GoTo continue
  74.                 n = n - take - monkey
  75.                 report$ = report$ + Space$(5) + "Sailor" + Str$(sailor) + " takes" + Str$(take) + " and 1 goes to monkey." + Chr$(10)
  76.             Else
  77.                 GoTo continue
  78.             End If
  79.         Next
  80.         divy = n / TotalSailors
  81.         report$ = report$ + Space$(5) + "The final divy for each sailor is" + Str$(divy) + "." + Chr$(10)
  82.         If n Mod TotalSailors = 0 Then
  83.             ' print whole report for first good coconuts number
  84.             Cls
  85.             Print report$
  86.             Print #1, report$
  87.             Print #1, " "
  88.             Exit For
  89.         End If
  90.         continue:
  91.     Next
  92.     Print "Press any to continue...";
  93.     'Sleep  'comment out when writing the file
  94.  
  95.  

Here is the output report:
Code: [Select]

 2 sailors require a minimum of 11 coconuts.
     Sailor 1 takes 5 and 1 goes to monkey.
     Sailor 2 takes 2 and 1 goes to monkey.
     The final divy for each sailor is 1.

 

 3 sailors require a minimum of 25 coconuts.
     Sailor 1 takes 8 and 1 goes to monkey.
     Sailor 2 takes 5 and 1 goes to monkey.
     Sailor 3 takes 3 and 1 goes to monkey.
     The final divy for each sailor is 2.

 

 4 sailors require a minimum of 765 coconuts.
     Sailor 1 takes 191 and 1 goes to monkey.
     Sailor 2 takes 143 and 1 goes to monkey.
     Sailor 3 takes 107 and 1 goes to monkey.
     Sailor 4 takes 80 and 1 goes to monkey.
     The final divy for each sailor is 60.

 

 5 sailors require a minimum of 3121 coconuts.
     Sailor 1 takes 624 and 1 goes to monkey.
     Sailor 2 takes 499 and 1 goes to monkey.
     Sailor 3 takes 399 and 1 goes to monkey.
     Sailor 4 takes 319 and 1 goes to monkey.
     Sailor 5 takes 255 and 1 goes to monkey.
     The final divy for each sailor is 204.

 

 6 sailors require a minimum of 233275 coconuts.
     Sailor 1 takes 38879 and 1 goes to monkey.
     Sailor 2 takes 32399 and 1 goes to monkey.
     Sailor 3 takes 26999 and 1 goes to monkey.
     Sailor 4 takes 22499 and 1 goes to monkey.
     Sailor 5 takes 18749 and 1 goes to monkey.
     Sailor 6 takes 15624 and 1 goes to monkey.
     The final divy for each sailor is 13020.

 

 7 sailors require a minimum of 823537 coconuts.
     Sailor 1 takes 117648 and 1 goes to monkey.
     Sailor 2 takes 100841 and 1 goes to monkey.
     Sailor 3 takes 86435 and 1 goes to monkey.
     Sailor 4 takes 74087 and 1 goes to monkey.
     Sailor 5 takes 63503 and 1 goes to monkey.
     Sailor 6 takes 54431 and 1 goes to monkey.
     Sailor 7 takes 46655 and 1 goes to monkey.
     The final divy for each sailor is 39990.

 

 8 sailors require a minimum of 117440505 coconuts.
     Sailor 1 takes 14680063 and 1 goes to monkey.
     Sailor 2 takes 12845055 and 1 goes to monkey.
     Sailor 3 takes 11239423 and 1 goes to monkey.
     Sailor 4 takes 9834495 and 1 goes to monkey.
     Sailor 5 takes 8605183 and 1 goes to monkey.
     Sailor 6 takes 7529535 and 1 goes to monkey.
     Sailor 7 takes 6588343 and 1 goes to monkey.
     Sailor 8 takes 5764800 and 1 goes to monkey.
     The final divy for each sailor is 5044200.

 

 9 sailors require a minimum of 387420481 coconuts.
     Sailor 1 takes 43046720 and 1 goes to monkey.
     Sailor 2 takes 38263751 and 1 goes to monkey.
     Sailor 3 takes 34012223 and 1 goes to monkey.
     Sailor 4 takes 30233087 and 1 goes to monkey.
     Sailor 5 takes 26873855 and 1 goes to monkey.
     Sailor 6 takes 23887871 and 1 goes to monkey.
     Sailor 7 takes 21233663 and 1 goes to monkey.
     Sailor 8 takes 18874367 and 1 goes to monkey.
     Sailor 9 takes 16777215 and 1 goes to monkey.
     The final divy for each sailor is 14913080.


Now I see that david_uwi has offered an interesting new angle of approach. Sure could use a speedup for 8 and 9 sailors! ;-))

387420481 coconuts minimum in one day collected by 9 sailors, ha!, this is a theoretical math problem isn't it?!
« Last Edit: September 05, 2021, 01:55:19 am by bplus »