Please look at the next code, Lua.
randomNumber = {
new = function(self,o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end,
math.randomseed(os.time()),
getNum = math.random()
}
for i = 1, 10 do
x = randomNumber:new()
print(x.getNum)
end
The output results are as follows.
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
0.13782639400248
I want to get 10 different numbers. Can someone help me? Thank you in advance.
Let's take a look at your table constructor
randomNumber = {
new = function(self,o) -- this assigns a function to randomNumber["new"]
o = o or {} -- that will return a new instance of your class
setmetatable(o, self)
self.__index = self
return o
end,
math.randomseed(os.time()), -- this assigns the first of two random seed components
-- returned by math.randomseed to randomNumber[1]
getNum = math.random() -- this assings a random number [0,1) to randomNumber["getNum"]
}
In the loop
for i = 1, 10 do
x = randomNumber:new()
print(x.getNum)
end
You create a new instance named x of randomNumber 10 times.
You then print x.getNum.
x.getNum is a nil value so Lua will check wether x has a metatable with a __index field. __index refers to randomNumber so Lua will print randomNumber.getNum which is the random number [0,1) which has not changed since we constructed randomNumber.
You need to call math.random every time you want a new random number.
If you want each instance of randomNumber to be constructed with a random number you need to assign o.rn = math.random() in your new function and either access it via x.rn later or add a function getNum to randomNumber.
getNum = function (self) return self.rn end`
so you can print(x:getNum())
I'm not sure if this is more than a exercise with metatables. But having a dedicated class that just holds a single number doesn't make too much sense to me. Just use a number value.
The main problem with your code is simply...
In a very fast Lua loop os.time() is not fast enough to set a good random seed.
You have to use something that is faster, like...
-- Lua 5.3 - 5.4
for i = 1, 10 do
math.randomseed(math.random(math.mininteger, math.maxinteger)) -- Set seed before print()
print('Seed: ' .. math.randomseed(math.random(math.mininteger, math.maxinteger)), '\nRandom: ' .. math.random(math.maxinteger)) -- Set seed in print()
math.randomseed(math.random(math.mininteger, math.maxinteger)) -- Set seed after print()
end
That puts out something like...
Seed: -634325252416746990
Random: 5554602367968798340
Seed: 574322306421972413
Random: 3317370212892010822
Seed: -5465512503977683870
Random: 6616070635043877067
Seed: -2566820481734265082
Random: 2581377472505137533
Seed: -8408106760854456996
Random: 708876515734960246
Seed: 5641371185711405705
Random: 4259990225803106481
Seed: -3172432877848732304
Random: 5472223279668970440
Seed: 5842301042132325387
Random: 6912957407189525897
Seed: 2126448976574029213
Random: 6156943198274398962
Seed: 4832369017575479065
Random: 6054703131408226582
Lua 5.1
-- Lua 5.1
math.randomseed(math.random(os.time()))
for i = 1, 10 do
math.randomseed(math.random(-99999999, 999999999)) -- Set seed before print()
print('Random: ' .. tostring(math.random(-999999999, 999999999)))
math.randomseed(math.random(-999999999, 999999999)) -- Set seed after print()
end
Related
I'm trying to generate random UUID's v4 within a loop:
randomUuid =
-- TODO: find a way to generate random uuid for variableId
updatedVariables =
group.variables |> List.map (\variable -> { variable | id = randomUuid })
I read the doc of elm/random and elm/uuid but could not find how to generate an UUID without using a seed.
The only thing I could do is:
newUuid : Random.Seed -> ( String, Random.Seed )
newUuid seed =
seed
|> Random.step UUID.generator
|> Tuple.mapFirst UUID.toString
I see that elm/random as an independentSeed function but I cannot get it to generate a seed.
The node equivalent of what I'm trying to achieve with randomUuid is:
const { uuid } = require('uuidv4');
const randomUuid = uuid();
I feel like I might be missing some important concept in Elm here but cannot figure that one on my own. Any help or pointer would be greatly appreciated.
Generating random values is an effect and as such a pure language cannot just perform it.
However, there is a pure version of randomness, which is using random seeds. These have the property that every time you generate a value using the same seed, you get the same value - hence this is just a pure computation and is completely ok in a pure context.
Elm allows you to execute effects as Cmd, the thing you return from your init and update functions. So one option you have is to always return Random.generate GotANewUUID UUID.generator before you need it, then perform your computation when you handle the GotANewUUID msg.
The other option is to keep track of the random seed. You either start with a deterministic one with Random.initialSeed (probably not what you want with UUIDs, as they would be exactly the same on every run of your program), or in your init function you return Random.generate GotNewSeed Random.independentSeed. Then you store the seed in your model.
Every time you need to generate a new UUID, you use your newUuid function above, making sure to store the new seed.
Here's an example:
import Random
import UUID
type alias Thing =
{ id : String
-- , some other stuff
}
type alias Model =
{ seed : Random.Seed
, stuff : List Thing
}
type Msg
= GotNewSeed Random.Seed
| AddAThing Thing
| AddABunchOfThings (List Thing)
init : () -> (Model, Cmd Msg)
init flags =
({ seed = Random.initialSeed 567876567
-- Let's start with a deterministic seed
-- so you don't need to deal with Maybe Seed later
, stuff = []
}, Random.generate GotNewSeed Random.independentSeed
)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
GotNewSeed seed ->
({model | seed = seed}, Cmd.none)
AddAThing thing ->
let
(newId, newSeed) =
newUuid model.seed
in
({ model | stuff = { thing | id = newId } :: model.stuff
, seed = newSeed }
, Cmd.none
)
AddABunchOfThings things ->
let
(newStuff, newSeed) =
List.foldl (\thing (stuff, seed) ->
newUuid seed
|> Tuple.mapFirst (\id ->
{ thing | id = id } :: stuff
)
) (model.stuff, model.seed) things
in
({model | stuff = newStuff, seed = newSeed}, Cmd.none)
I am getting my head around the functional model in Ruby and ran into a problem. I am able to successfully pass any given number of arguments to an arbitrary function as follows:
add = ->(x, y) { return x + y }
mul = ->(x, y) { return x * y }
def call_binop(a, b, &func)
return func.call(a, b)
end
res = call_binop(2, 3, &add)
print("#{res}\n") #5
res = call_binop(3, 4, &mul)
print("#{res}\n") #12
However, I am not able to pass an arbitrary number of functions:
dbl = ->(x) { return 2 * x }
sqr = ->(x) { return x * x }
def call_funccomp(a, &func1, &func2)
return func2.call(func1.call(a))
end
res = call_funccomp(3, &dbl, &sqr)
print("#{res}\n") #Expect 36 but compiler error
The compiler error is syntax error, unexpected ',', expecting ')'
I have already added both lambdas and procs to an array and then executed elements of the array, so I know I can get around this by passing such an array as an argument, but for simple cases this seems to be a contortion for something (I hope) is legal in the language. Does Ruby actually limit the number or lambdas one can pass in the argument list? It seems to have a reasonably modern, flexible functional model (the notation is a little weird) where things can just execute via a call method.
Does Ruby actually limit the number or lambdas one can pass in the argument list?
No, you can pass as many procs / lambdas as you like. You just cannot pass them as block arguments.
Prepending the proc with & triggers Ruby's proc to block conversion, i.e. your proc becomes a block argument. And Ruby only allows at most one block argument.
Attempting to call call_funccomp(3, &dbl, &sqr) is equivalent to passing two blocks:
call_funccomp(3) { 2 * x } { x * x }
something that Ruby doesn't allow.
The fix is to omit &, i.e. to pass the procs / lambdas as positional arguments:
dbl = ->(x) { 2 * x }
sqr = ->(x) { x * x }
def call_funccomp(a, func1, func2)
func2.call(func1.call(a))
end
res = call_funccomp(3, dbl, sqr)
print("#{res}\n")
There's also Proc#>> which combines two procs:
def call_funccomp(a, func1, func2)
(func1 >> func2).call(a)
end
I just want to see a random number. So here's an example straight out of the docs for the Random library. I expect Random.generate to accept a generator and a seed and return a tuple containing a random value and a new seed, as in:
generate : Generator a -> Seed -> (a, Seed)
-- Main.elm
import Random
seed0 = Random.initialSeed 31415
randomNumber = Random.generate (Random.int 0 10) seed0
main =
-- print result of randomNumber here
The compiler errors show two type mismatches:
-- TYPE MISMATCH ---------------------------------------------------- -----------
The 2nd argument to function `generate` is causing a mismatch.
5| Random.generate (Random.int 0 10) seed0
^^^^^
Function `generate` is expecting the 2nd argument to be:
Random.Generator a
But it is:
Random.Seed
The 1st argument to function `generate` is causing a mismatch.
5| Random.generate (Random.int 0 10) seed0
^^^^^^^^^^^^^^^
Function `generate` is expecting the 1st argument to be:
a -> b
But it is:
Random.Generator Int
What am I missing here?
The version of the docs you refer to is Core 1.0.0, which is old. Current version of Core is 4.0.5. (docs for Random here)
The function with the signature you are looking for is now named step:
step : Generator a -> Seed -> (a, Seed)
So your refactored code would look something like this:
import Html exposing (text)
import Random
seed0 = Random.initialSeed 31415
(randomNumber, nextSeed) = Random.step (Random.int 0 10) seed0
main =
text <| toString randomNumber
Here is the shortest example I can think of.
Because it is giving a constant seed, it will return same boolean.
If you need random number get produced at runtime, then you
have to use Random.generate which produces Cmd
so that elm runtime can get the randomness.
In this case, some form of Platform.Program
is needed because it is the only way to run Cmd.
import Html exposing (text)
import Random exposing (..)
main =
text <| toString <| Tuple.first <| step bool (initialSeed 1)
Elm 2022 (v0.19) answer:
Here's an absolute minimal example for generating a number between 0 and 1000 in Elm 0.19.1, and a runnable Ellie, which depends on elm/random. You wouldn't usually have all the () littered throughout, and instead you'd have Msg and Model, but in the interest of minimizing code:
module Main exposing (main)
import Browser
import Html
import Random
view : () -> Html.Html ()
view model =
let
-- this generates the rng number
generator =
Random.int 0 1000
-- used to seed the generator
seed =
Random.initialSeed 12345
-- Random.step returns the generated value, and a new seed.
-- Usually you store the newSeed on your model so you don't always generate the same value
( value, newSeed ) =
Random.step
generator
seed
in
Html.text <| String.fromInt value
main : Program () () ()
main =
Browser.sandbox
{ init = ()
, view = view
, update = \msg model -> model
}
Other best practices include storing some global seed on the model:
type alias Model = { globalSeed : Random.Seed }
and then using it and updating the one on the model after:
update : Msg -> Model -> (Model, Cmd.none)
update msg model =
case msg of
GenerateValue ->
let
(newValue, newSeed) =
Random.step (Random.int 0 1000) model.globalSeed
_ =
Debug.log "generated a new value" newValue
in
( {model | globalSeed = newSeed}, Cmd.none)
I am currently just trying to wrap my head around this example question. I don't understand the syntax of it. I don't understand the point of i and how it relates to result
def pow(base, exponent)
result = 1
i = 1
while i <= exponent
result = result * base
i += 1
end
result
end
Any explanation much appreciated!!
while need a do while(i <= exponent) do
i is a counter, you can replace the while for
exponent.times { result = result * base }
this code will execute the number (exponent) times the content of { }
And the result on end is the result of function, in ruby if you don't put a return clause will return the last line executed
Hello I've been trying to get this code to work, I even cheated and added in the goal to my code and its still not accepting my answer, any suggestions?
-- Functions...
function p() -- For user imput..
print("Enter # and try to get the closest to it! (Valid range is 1-100)")
local var = tonumber(io.read())
if var == nil then
var = 0
end
return var
end
--Start main code..
-- Initialize the pseudo random number generator (I'm on windows...)
math.randomseed( os.time() )
math.random(); math.random(); math.random()
-- Setting goal
goal = math.random(1,100)
-- Guessing loop...
repeat
g = p()
print(g)
print(goal)
until g == Goal
print("YOU GUESSED THE GOAL!")
Replace the G by a lower case g.
until g == goal