I am busy reading the programming in lua 4th edition book and I am struggling with chapter two. The program essentially prints a chess board with 8 queens that are placed in a way that none of them can attack each other. What I am struggling to figure out is why it prints the boards multiple times.
I have went over the code step by step and once the print solution has finished printing the first board I thought it would just end the function and then jump back to the main but for some reason it keeps looping. I am also very new to lua and have just come from C so still getting used to it all.
Image of one of the boards it outputs. The Xs are the queens - https://ibb.co/KsT3R8X
N = 8 -- board size
-- check whether position (n,c) is free from attacks
function isplaceok (a, n, c)
for i = 1, n - 1 do -- for each queen already placed
if (a[i] == c) or -- same column?
(a[i] - i == c - n) or -- same diagonal?
(a[i] + i == c + n) then -- same diagonal?
return false -- place can be attacked
end
end
return true -- no attacks; place is OK
end
-- print a board
function printsolution (a)
for i = 1, N do -- for each row
for j = 1, N do -- and for each column
-- write "X" or "-" plus a space
io.write(a[i] == j and "X" or "-", " ")
end
io.write("\n")
end
io.write("\n")
end
-- add to board 'a' all queens from 'n' to 'N'
function addqueen (a, n)
if n > N then -- all queens have been placed?
printsolution(a)
else -- try to place n-th queen
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c -- place n-th queen at column 'c'
addqueen(a, n + 1)
end
end
end
end
-- run the program
addqueen({}, 1)
The program is printing all 92 possible solutions for the 8x8 chessboard.
Which is likely the intention, so it would appear to be working correctly.
To stop after we find 1 solution we can add a variable found to the program:
local found = false
-- print a board
function printsolution (a)
for i = 1, N do -- for each row
for j = 1, N do -- and for each column
-- write "X" or "-" plus a space
io.write(a[i] == j and "X" or "-", " ")
end
io.write("\n")
end
io.write("\n")
found = true
end
-- add to board 'a' all queens from 'n' to 'N'
function addqueen (a, n)
if n > N then -- all queens have been placed?
printsolution(a)
else -- try to place n-th queen
for c = 1, N do
if isplaceok(a, n, c) and found == false then
a[n] = c -- place n-th queen at column 'c'
addqueen(a, n + 1)
end
end
end
end
This found variable stops the continued recursion of the existing loops as we move back up the stack.
Now why is it that this code works this way, where are all the solutions coming from?
That has to do with the for loop in addqueen:
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c
addqueen(a, n + 1)
end
end
Each loop of the for loop sends the code deeper by recursively calling addqueen. The stack will never be deeper then 9 as that is the limit set by the N
The first solution after 114 calls to addqueen is this one:
X - - - - - - -
- - - - X - - -
- - - - - - - X
- - - - - X - -
- - X - - - - -
- - - - - - X -
- X - - - - - -
- - - X - - - -
The 5th solution is the first time we will have come back to our original call of addqueen, you can see the first X has moved from 1x1 to 1x2(n=1 c=2, second step of our original for loop):
- X - - - - - -
- - - X - - - -
- - - - - X - -
- - - - - - - X
- - X - - - - -
X - - - - - - -
- - - - - - X -
- - - - X - - -
In the end we call addqueen 1952 times for the program to check all the possible solutions.
You can adjust the code to print a value of the depth to get a better idea of how the stack looks as the program runs:
-- add to board 'a' all queens from 'n' to 'N'
function addqueen (a, n)
print(n .. "↓")
if n > N then -- all queens have been placed?
printsolution(a)
else -- try to place n-th queen
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c -- place n-th queen at column 'c'
addqueen(a, n + 1)
end
end
end
print(n - 1 .. "↑")
end
Related
I would like to convert a HSL value into an RBG so that i can easily generate random colours in Love2D, however i am having trouble finding how to do this. I did check wikipedia but really didn't understand anything, and i was browsing stack overflow but didn't find anything for Lua. If possible i would want the function to enter 3 values and return a table with table.r, table.b, table.g, so that i can then call function().r etc etc. How can i do this?
Stack overflow isn't letting me post this without adding more information so lets see, the reason i don't want to randomise RBG values is that i only to change the hue, not affecting saturation/lightness. I think HSL would be the perfect way to do this as i can just randomise a hue colour to then convert it into RBG, RBG being the way colours are defined in Love2D.
I've saw the function you want written in https://github.com/unek/loveframes-snap-theme/blob/master/color.lua
Here's the parts you want extracted from it:
-- Needed for hsl2rgb to work
local function hue2rgb(p, q, t)
if t < 0 then t = t + 1 end
if t > 1 then t = t - 1 end
if t < 1/6 then return p + (q - p) * 6 * t end
if t < 1/2 then return q end
if t < 2/3 then return p + (q - p) * (2/3 - t) * 6 end
return p
end
-- Here's the function you want --
local function hsl2rgb(h, s, l)
local r, g, b
local h = h / 360
if s == 0 then
r, g, b = l, l, l
else
local q = (l < 0.5) and l * (1 + s) or l + s - l * s
local p = l * 2 - q
r = hue2rgb(p, q, h + 1/3)
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1/3)
end
return {r=r, g=g, b=b}
end
Please note that the RGB values will be in range [0-1]
I'm using Maxima to print stuff into a web page in an educational context. Most of the time everything works smoothly, but I'm having problems with binomials such as -x + 1, which Maxima simplifies as 1 - x. I quess that this is because this form takes less characters.
But in educational context this is often not desired, as in the standard form the term with x should always be before constant.
So is there any option to prevent this kind of simplification?
I have tried using ratvars(x), totaldisrep(-x+1) and declare(x,mainvar), none of those did what I was looking for.
Outputs:
x + 1;
x+1
x - 1;
x-1
-x - 1;
-x-1
-x + 1;
1-x
I wish to find a way to get this last one to output -x+1.
Try setting negsumdispflag to false. See: ? negsumdispflag
I get these results, maybe this is acceptable.
(%i12) negsumdispflag:false;
(%o12) false
(%i13) x + 1;
(%o13) x + 1
(%i14) x - 1;
(%o14) x - 1
(%i15) 1 - x;
(%o15) (- x) + 1
(%i16) - 1 - x;
(%o16) (- x) - 1
I'm trying to translate a code from C to Lua and I'm facing a problem.
How can I translate a Bitwise AND in Lua?
The source C code contains:
if ((command&0x80)==0)
...
How can this be done in Lua?
I am using Lua 5.1.4-8
Implementation of bitwise operations in Lua 5.1 for non-negative 32-bit integers
OR, XOR, AND = 1, 3, 4
function bitoper(a, b, oper)
local r, m, s = 0, 2^31
repeat
s,a,b = a+b+m, a%m, b%m
r,m = r + m*oper%(s-a-b), m/2
until m < 1
return r
end
print(bitoper(6,3,OR)) --> 7
print(bitoper(6,3,XOR)) --> 5
print(bitoper(6,3,AND)) --> 2
Here is a basic, isolated bitwise-and implementation in pure Lua 5.1:
function bitand(a, b)
local result = 0
local bitval = 1
while a > 0 and b > 0 do
if a % 2 == 1 and b % 2 == 1 then -- test the rightmost bits
result = result + bitval -- set the current bit
end
bitval = bitval * 2 -- shift left
a = math.floor(a/2) -- shift right
b = math.floor(b/2)
end
return result
end
usage:
print(bitand(tonumber("1101", 2), tonumber("1001", 2))) -- prints 9 (1001)
Here's an example of how i bitwise-and a value with a constant 0x8000:
result = (value % 65536) - (value % 32768) -- bitwise and 0x8000
In case you use Adobe Lightroom Lua, Lightroom SDK contains LrMath.bitAnd() method for "bitwise AND" operation:
-- x = a AND b
local a = 11
local b = 6
local x = import 'LrMath'.bitAnd(a, b)
-- x is 2
And there are also LrMath.bitOr(a, b) and LrMath.bitXor(a, b) methods for "bitwise OR" and "biwise XOR" operations.
This answer is specifically for Lua 5.1.X
you can use
if( (bit.band(command,0x80)) == 0) then
...
in Lua 5.3.X and onwards it's very straight forward...
print(5 & 6)
hope that helped 😉
I've been working on a project that renders a Mandelbrot fractal. For those of you who know, it is generated by iterating through the following function where c is the point on a complex plane:
function f(c, z) return z^2 + c end
Iterating through that function produces the following fractal (ignore the color):
When you change the function to this, (z raised to the third power)
function f(c, z) return z^3 + c end
the fractal should render like so (again, the color doesn't matter):
(source: uoguelph.ca)
However, when I raised z to the power of 3, I got an image extremely similar as to when you raise z to the power of 2. How can I make the fractal render correctly? This is the code where the iterations are done: (the variables real and imaginary simply scale the screen from -2 to 2)
--loop through each pixel, col = column, row = row
local real = (col - zoomCol) * 4 / width
local imaginary = (row - zoomRow) * 4 / width
local z, c, iter = 0, 0, 0
while math.sqrt(z^2 + c^2) <= 2 and iter < maxIter do
local zNew = z^2 - c^2 + real
c = 2*z*c + imaginary
z = zNew
iter = iter + 1
end
So I recently decided to remake a Mandelbrot fractal generator, and it was MUCH more successful than my attempt last time, as my programming skills have increased with practice.
I decided to generalize the mandelbrot function using recursion for anyone who wants it. So, for example, you can do f(z, c) z^2 + c or f(z, c) z^3 + c
Here it is for anyone that may need it:
function raise(r, i, cr, ci, pow)
if pow == 1 then
return r + cr, i + ci
end
return raise(r*r-i*i, 2*r*i, cr, ci, pow - 1)
end
and it's used like this:
r, i = raise(r, i, CONSTANT_REAL_PART, CONSTANT_IMAG_PART, POWER)
Forgive my lack of code but I can't quite figure out the best way to achieve the following:
two strings (stored as strings because of the leading 0 - they are phone numbers) :
a = '0123456700'
b = '0123456750'
I am trying to find a way to write them as a range as follows
0123456700 - 750
rather than
0123456700 - 0123456750
which I currently have.
It's not as straightforward as getting the last 3 digits of b since the range can vary and perhaps go up to 4 digits so I'm trying to find the best way of being able to do this.
I'd look up the index of the first unequal pair of characters:
a = '0123456700'
b = '0123456750'
index = a.chars.zip(b.chars).index { |x, y| x != y }
#=> 8
And extract the suffix with:
"#{a} - #{b[index..-1]}" if index
#=> "0123456700 - 50"
Here's a method that returns the range:
def my_range(a, b)
a = a.delete(" ") # remove all spaces from string
b = b.delete(" ")
a, b = b, a if a.to_i > b.to_i # a is always smaller than b
ai, bi = a.to_i, b.to_i
pow = 1
while ai > 1
pow += 1
len = pow if ai % 10 != bi % 10
ai /= 10
bi /= 10
end
a + " - " + b[-len..-1]
end
puts my_range("0123456700", "0123456750") # 0123456700 - 750
puts my_range("0123456669", "0123456675") # 0123456669 - 675
puts my_range("0123400200", "0123500200") # 0123400200 - 3500200
puts my_range("012 345 678", "01 235 0521") # 012345678 - 350521
From my personal library (simplified):
def common_prefix first, second
i = 0
loop{break unless first[i] and second[i] == first[i]; i += 1}
first[0, i]
end
a = "0123456700"
b = "0123456750"
c = "0123457750"
common_prefix(a, b)
# => "01234567"
"#{a} - #{b.sub(common_prefix(a, b), "")}"
# => "0123456700 - 50"
"#{a} - #{c.sub(common_prefix(a, c), "")}"
# => "0123456700 - 7750"
Note. This will work correctly only under the assumption that all strings are right padded with 0 to be the same length.