Hourglass puzzle: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 34: Line 34:
println("Flip an hourglass every time it runs out of grains, and note the interval in time.")
println("Flip an hourglass every time it runs out of grains, and note the interval in time.")
i, j = euclidean_hourglassflipper([4, 7], 9)
i, j = euclidean_hourglassflipper([4, 7], 9)
println("Use hourglasses from step $i to step $j (inclusive) to sum 9")
println("Use hourglasses from step $i to step $j (inclusive) to sum 9 using [4, 7]")
i, j = euclidean_hourglassflipper([5, 7, 31], 36)
println("Use hourglasses from step $i to step $j (inclusive) to sum 36 using [5, 7, 31]")
</lang>{{out}}
</lang>{{out}}
<pre>
<pre>
Flip an hourglass every time it runs out of grains, and note the interval in time.
Flip an hourglass every time it runs out of grains, and note the interval in time.
Series: [4, 3, 1, 4, 2, 2]
Series: [4, 3, 1, 4, 2, 2]
Use hourglasses from step 3 to step 6 (inclusive) to sum 9
Use hourglasses from step 3 to step 6 (inclusive) to sum 9 using [4, 7]
Series: [5, 2, 3, 4, 1, 5, 1, 4, 3, 2, 1, 4, 5, 2, 3, 4, 1]
Use hourglasses from step 5 to step 17 (inclusive) to sum 36 using [5, 7, 31]
</pre>
</pre>



Revision as of 22:53, 29 December 2020

Hourglass puzzle is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Given two hourglass of 4 minutes and 7 minutes, the task is to measure 9 minutes.

Notes

Implemented as a 1-player game.

Julia

Implemented as a game solver rather than as a game with user input. <lang julia>function euclidean_hourglassflipper(hourglasses, target::Integer)

   gcd(hourglasses) in hourglasses && !(1 in hourglasses) && throw("Hourglasses fail sanity test (not relatively prime enough)")
   flippers, series = deepcopy(hourglasses), Int[]
   for i in 1:typemax(target)
       n = minimum(flippers)
       push!(series, n)
       flippers .-= n
       for (i, n) in enumerate(flippers)
           if n == 0
               flippers[i] = hourglasses[i]
           end
       end
       for startpoint in length(series):-1:1
           if sum(series[startpoint:end]) == target
               println("Series: $series")
               return startpoint, length(series)
           end
       end
   end

end

println("Flip an hourglass every time it runs out of grains, and note the interval in time.") i, j = euclidean_hourglassflipper([4, 7], 9) println("Use hourglasses from step $i to step $j (inclusive) to sum 9 using [4, 7]") i, j = euclidean_hourglassflipper([5, 7, 31], 36) println("Use hourglasses from step $i to step $j (inclusive) to sum 36 using [5, 7, 31]")

</lang>

Output:
Flip an hourglass every time it runs out of grains, and note the interval in time.
Series: [4, 3, 1, 4, 2, 2]
Use hourglasses from step 3 to step 6 (inclusive) to sum 9 using [4, 7]
Series: [5, 2, 3, 4, 1, 5, 1, 4, 3, 2, 1, 4, 5, 2, 3, 4, 1]
Use hourglasses from step 5 to step 17 (inclusive) to sum 36 using [5, 7, 31]

tested with FMSlogo <lang logo> to bb Make "small_capacity 4 Make "big_capacity 7 make "small 0 make "big 0 make "t 0 print "_____________decision_0_game_over print "_________decision_1_start_timing print "_______decision_2_flip_small print "____decision_3_flip_big print "__decision_4_flip_both print "_________any_other_number________________wait do.until [show list list :small :big :t print "your_decision_0_1_2_3_4 human_decision if :my_decision>1 [machine_computes] ] [:my_decision=0] print list :t "minutes_passed end

to human_decision make "my_decision readword if :my_decision=1 [print "reset_timer make "t 0] if :my_decision=2 [print "flip_small make "small :small_capacity-:small] if :my_decision=3 [print "flip_big make "big :big_capacity-:big] if :my_decision=4 [print "flip_both make "small :small_capacity-:small make "big :big_capacity-:big ] if :my_decision>4 [print "wait] end

to machine_computes ifelse :small>:big [make "my_selection :big] [make "my_selection :small] if :small=0 [make "my_selection :big] if :big=0 [make "my_selection :small] make "small :small-:my_selection make "big :big-:my_selection make "t :t+:my_selection if :small<0 [make "small 0] if :big<0 [make "big 0] end

to zzz

A. 7 minutes with 4- and 5-minute timers
B. 15 minutes with 7- and 11-minute timers
C. 14 minutes with 5- and 8-minute timers

ifelse YesNoBox [Welcome] [run / show me the code] [bb] [edall]

A is possible
Turn both the 5 and the 4. When the 4 runs out, flip it over.Now, when the 5 runs out, start timing. The 4 will run for three more minutes, after which, you can flip it over to reach 7.
B is possible
Turn both the 7 and the 11. When the 7 runs out, start timing. The 11 will run for 4 more minutes, after which it can be flipped to reach 15.
C is possible
Turn both the 5 and the 8. When the 5 runs out, flip it. The 8 will then run out after 3 minutes, leaving 2 minutes in the 5. Flip the 8 then. When the 5 runs out, start timing. There are now 6 minutes left in the 8, and flipping the 8 after those 6 minutes gives 6 + 8 = 14 minutes.

end

Make "big 0 Make "big_capacity 5 Make "my_decision " Make "my_selection 4 Make "small 0 Make "small_capacity 4 Make "startup [zzz] Make "t 0


</lang>

Python

There isn't much of a task description as I write this, but, here goes...

<lang python>def hourglass_puzzle():

   t4 = 0
   while t4 < 10_000:
       t7_left = 7 - t4 % 7
       if t7_left == 9 - 4:
           break
       t4 += 4
   else:
       print('Not found')
       return 
   print(f"""

Turn over both hour glasses at the same time and continue flipping them each when they individually run down until the 4 hour glass is flipped {t4//4} times, wherupon the 7 hour glass is immediately placed on its side with {t7_left} hours of sand in it. You can measure 9 hours by flipping the 4 hour glass once, then flipping the remaining sand in the 7 hour glass when the 4 hour glass ends.

""")

hourglass_puzzle()</lang>

Output:
Turn over both hour glasses at the same time and continue flipping them each
when they individually run down until the 4 hour glass is flipped 4 times,
wherupon the 7 hour glass is immediately placed on its side with 5 hours 
of sand in it.
You can measure 9 hours by flipping the 4 hour glass once, then
flipping the remaining sand in the 7 hour glass when the 4 hour glass ends.