100 prisoners: Difference between revisions

GDScript
(1-based index)
(GDScript)
Line 2,838:
Trials/sec: 114.9</pre>
 
 
=={{header|GDScript}}==
{{works with|Godot|4.0}}
 
<syntaxhighlight lang="gdscript">
extends MainLoop
 
 
enum Strategy {Random, Optimal}
 
const prisoner_count := 100
 
 
func get_random_drawers() -> Array[int]:
var drawers: Array[int] = []
drawers.resize(prisoner_count)
for i in range(0, prisoner_count):
drawers[i] = i + 1
drawers.shuffle()
return drawers
 
 
var random_strategy = func(drawers: Array[int], prisoner: int) -> bool:
# Randomly selecting 50 drawers is equivalent to shuffling and picking the first 50
var drawerCopy: Array[int] = drawers.duplicate()
drawerCopy.shuffle()
for i in range(50):
if drawers[drawerCopy[i]-1] == prisoner:
return true
return false
 
 
var optimal_strategy = func(drawers: Array[int], prisoner: int) -> bool:
var choice: int = prisoner
for _i in range(50):
var drawer_value: int = drawers[choice-1]
if drawer_value == prisoner:
return true
choice = drawer_value
return false
 
 
func play_all(drawers: Array[int], strategy: Callable) -> bool:
for prisoner in range(1, prisoner_count+1):
if not strategy.call(drawers, prisoner):
return false
return true
 
 
func _process(_delta: float) -> bool:
# Constant seed for reproducibility, call randomize() in real use
seed(1234)
 
const SAMPLE_SIZE: int = 10_000
 
var random_successes: int = 0
for i in range(SAMPLE_SIZE):
if play_all(get_random_drawers(), random_strategy):
random_successes += 1
 
var optimal_successes: int = 0
for i in range(SAMPLE_SIZE):
if play_all(get_random_drawers(), optimal_strategy):
optimal_successes += 1
 
print("Random play: %%%f" % (100.0 * random_successes/SAMPLE_SIZE))
print("Optimal play: %%%f" % (100.0 * optimal_successes/SAMPLE_SIZE))
 
return true # Exit
 
</syntaxhighlight>
 
{{out}}
<pre>
Random play: %0.000000
Optimal play: %31.700000
</pre>
 
=={{header|Go}}==
89

edits