I am creating a Sudoku solver in C++ while implementing Lua scripting for the actual solving of the puzzle. I have created the following Lua code, but get a
PANIC: unprotected error in call to Lua API (attempt to call a nil value)
error whenever my C++ code reaches the first instance of lua_call.
When compiling the code in SciTE, I get the following error:
lua: SudokuSolver.lua:99: 'end' expected (to close 'for' at line 61)
near ''
Adding three 'end's to the end of the function that has the for loop at line 61 clears that error, but causes errors in the C++ program. Can someone please look at my Lua and see if there's any syntax errors or other issues which may be causing this? Thank you
CODE
-- Table Declaration
SudokuGrid = {}
function RecieveGrid ( _Pos, _Value )
-- Recives the cell value at _Pos position from C++
SudokuGrid[_Pos] = _Value
end
function SolveSudoku ( _Pos )
-- Recursive function which solves the sudoku puzzle
local iNewValue = 1
-- If Position is 82+, all cells are solved
if( _Pos >= 82 ) then
return true
end
-- If Position already has a value
if( SudokuGrid[_Pos] ~= 0) then
return SolveSudoku( _Pos + 1 )
else
while(true) do
SudokuGrid[_Pos] = iNewValue
iNewValue = iNewValue + 1
-- If the new value of the cell is higher than 9 its not valid
if( SudokuGrid[_Pos] > 9 ) then
--Reset value
SudokuGrid[_Pos] = 0
return false
end
if( IsValid( _Pos ) and SolveSudoku( _Pos + 1 ) ) then
return true
end
end
end
end
function IsValid ( _Pos )
-- Calculate Column and Row in Grid
x = _Pos % 9
if( x == 0 ) then
x = 9
end
y = math.ceil(_Pos / 9)
-- Check Rows
for i=1, 9 do
CheckVal = ((y - 1) * 9) + i
if( CheckVal == _Pos ) then
-- Do nothing
else if ( SudokuGrid[_Pos] == SudokuGrid[CheckVal]and SudokuGrid[_Pos] ~= 0 ) then
return false
else
-- Do nothing
end
end
-- Check Columns
for i=1, 9 do
CheckVal = ((i - 1) * 9) + x
if( CheckVal == _Pos ) then
-- Do nothing
else if ( SudokuGrid[_Pos] == SudokuGrid[CheckVal] and SudokuGrid[_Pos] ~= 0 ) then
return false
else
-- Do nothing
end
end
-- Check 3X3 Grid
SquareCol = math.ceil(x/3)
SquareRow = math.ceil(y/3)
StartVal = (SquareCol - 1) * 27 + (SquareRow * 3) -2
for j=0, 2 do
for i=0, 2 do
CheckVal = StartVal + i
if( CheckVal == _Pos ) then
-- Do nothing
else if ( SudokuGrid[_Pos] == SudokuGrid[CheckVal] and SudokuGrid[_Pos] ~= 0 ) then
return false
else
-- Do nothing
end
end
StartVal = StartVal + 9
end
return true
end
function SendGrid ( _Pos )
-- Sends the value at _Pos to C++
return SudokuGrid[_Pos]
end
The syntax error is in all lines containing else if:
else if ( SudokuGrid[_Pos] == SudokuGrid[CheckVal]and SudokuGrid[_Pos] ~= 0 ) then
In Lua, use elseif instead. Using else if would need more closing end.
elseif SudokuGrid[_Pos] == SudokuGrid[CheckVal] and SudokuGrid[_Pos] ~= 0 then
Related
I'd like to incorporate if they currently have mmsa or jmmsa. MMMSA is balance over 2500 and JMMSA is balance over 100,000.
combined_2 = (
combined
.withColumn('mmsa_eligible',
F.when(
(F.col('min_bal_0_90_days') >= 2500) & (F.col('current_bal') >= 2500), 1
).otherwise(0)
)
.withColumn('jmmsa_eligible' ,
F.when(
(F.col('min_bal_0_90_days') >= 100000) & (F.col('current_bal') >= 100000), 1
).otherwise(0)
)
if jmmsa_eligible == 1 and jmmsa_current_flag == 0:
print ('Y')
else:
print ('N')
I want to create an if code to check if variable x is a member of a defined group of constant named a, for example a = { 1 , 2 , 3 , 4 }, then use something like if (x != a).
I only know to use it like this
if ( ( x != 1 ) || ( x != 2 ) || ( x != 3 ) || ( x != 4 ) )
You can use functions like this
bool exist_in_group(int value, const int* group,int group_size)
{
bool res{false};
for(int i=0;i<group_size;i++)
{
if(group[i] == value)
res = true;
}
return res;
}
This function check if value exist in your array(group) or not
I am using Qt Creator to develop a C++ application and the debugger to examine the code, I am trying to understand some very odd results reported by the debugger.
if ( intDelimiter == -1
&& (intOpB = strProcessed.indexOf("[")) >= 0
&& (intClB = strProcessed.indexOf("]", ++intOpB) >= 0) ) {
strRef = strProcessed.mid(intOpB, intClB - intOpB);
if ( pobjNode != NULL ) {
strProcessed.replace(strRef, pobjNode->strGetAttr(strRef));
}
I have a breakpoint on the line:
strRef = strProcessed.mid(intOpB, intClB - intOpB);
In the code snippet above strProcessed contains:
"1079-[height]"
When the breakpoint is hit, intClB contains 1 and intOpB contains 6.
intOpB is correct because the returned value from indexOf is 5 then its incremented before the search for "]", but intClB is not correct, why is the debugger reporting it as 1? This makes no sense to me.
I am using:
Qt Creator 3.6.0
Based on Qt 5.5.1 (GCC 4.9.1 20140922 (Red Hat 4.9.1-10), 64bit)
Built On Dec 15 2015 01:01:12
Revision: b52c2f91f5
As spotted by king_nak, the corrected code should read:
if ( intDelimiter == -1
&& ((intOpB = strProcessed.indexOf("[")) >= 0
&& (intClB = strProcessed.indexOf("]", ++intOpB)) >= 0) ) {
strRef = strProcessed.mid(intOpB, intClB - intOpB);
if ( pobjNode != NULL ) {
strProcessed.replace(strRef, pobjNode->strGetAttr(strRef));
}
}
You have misplaced a brace:
(intClB = strProcessed.indexOf("]", ++intOpB) >= 0)
This assigns the result of strProcessed.indexOf("]", ++intOpB) >= 0 to intClB, interpreted as int. As this statement is true, intClB = 1.
You want:
(intClB = strProcessed.indexOf("]", ++intOpB) ) >= 0
^ Brace here
I have a list of timestamp tuples of the form List((startTime,endTime)), which are basically denoting periods of time throughout the day.
For example:
(("2016-03-28 14:00:00","2016-03-28 15:00:00"),
("2016-03-28 17:00:00","2016-03-28 21:00:00"),
("2016-03-28 01:00:00","2016-03-28 13:00:00"))
I want to get a list of the durations which are not included in this list.
So the output should be:
(("2016-03-28 00:00:00","2016-03-28 01:00:00"),
("2016-03-28 13:00:00","2016-03-28 14:00:00"),
("2016-03-28 15:00:00","2016-03-28 17:00:00"),
("2016-03-28 17:00:00","2016-03-28 24:00:00"))
Can anyone suggest a good and efficient way of doing that in Scala?
The naive solution that I've tried so far is as follows:
import java.sql.Timestamp
import scala.collection.mutable.ListBuffer
def comparator(first: (Timestamp,Timestamp), second: (Timestamp, Timestamp)) = first._2.getTime <= second._1.getTime
val data = List((Timestamp.valueOf("2016-03-28 00:00:00"),Timestamp.valueOf("2016-03-28 10:00:00")),
(Timestamp.valueOf("2016-03-28 12:00:00"),Timestamp.valueOf("2016-03-28 15:00:00")),
(Timestamp.valueOf("2016-03-28 23:00:00"),Timestamp.valueOf("2016-03-28 23:59:59")),
(Timestamp.valueOf("2016-03-28 16:00:00"),Timestamp.valueOf("2016-03-28 21:00:00"))
).sortWith(comparator)
var emptySlots = new ListBuffer[(Timestamp,Timestamp)]()
var currTime = Timestamp.valueOf("2016-03-28 00:00:00")
var index = 0
var cond = 0
while(cond == 0){
if (currTime.compareTo(Timestamp.valueOf("2016-03-28 23:59:59")) < 0 && index >= data.size){
emptySlots += ((currTime,Timestamp.valueOf("2016-03-28 23:59:59") ))
cond = 1
}
else if(index >= data.size)
{
cond = 1
}
else if(currTime.compareTo(data(index)._1) < 0) {
emptySlots += ((currTime, data(index)._1))
currTime = data(index)._2
index += 1
}
else if(currTime.compareTo(data(index)._1) >= 0 && currTime.compareTo(data(index)._2) < 0 ) {
currTime = data(index)._2
index += 1
}
else if(currTime.compareTo(data(index)._1) > 0 && currTime.compareTo(data(index)._2) > 0 ) {
index += 1
}
}
emptySlots.toList
Just a basic Casaer Cipher. I've tested all of the sub functions, just encryptChar() does not particularly work. I get an infinite loop. It's supposed to be recursive. Here's the all code:
fun replace (str : string, index : int, newChar : char) : string = String.substring(str,0,index) ^ String.str(newChar) ^ String.substring(str,index+1,(size str) - index - 1;
fun encryptChar (msgStr : string, shiftAmnt : int, index : int) : string =
let val asciiCode = 0
in
if (not (String.sub(msgStr, index) = #" ")) then
(
asciiCode = ord( String.sub(msgStr, index) ) + shiftAmnt;
if (asciiCode < ord(#"A")) then asciiCode = asciiCode + 26
else if (asciiCode > ord(#"Z")) then asciiCode = asciiCode - 26
else asciiCode = asciiCode;
msgStr = replace(msgStr, index, chr(asciiCode))
)
else asciiCode = asciiCode;
index = index + 1;
if (index < (size msgStr - 1)) then encryptChar(msgStr, shiftAmnt, index)
else msgStr
end
;
fun encrypt(msgStr : string, shiftAmnt : int) : string = encryptChar (String.map Char.toUpper msgStr, shiftAmnt mod 26, 0);
The problem here is that you're misusing =. Outside of a variable definition, = is simply a boolean function which checks its arguments for equality. So if you do for example asciiCode = ord( String.sub(msgStr, index) ) + shiftAmnt;, it will simply return false (because asciiCode is not equal to ord( String.sub(msgStr, index) ) + shiftAmnt) and then throw that result away (because you have additional expressions after the ;). It will not reassign asciiCode.
Variables in SML are immutable. If you want to emulate mutable variables you can use refs and the := operator. However I would not recommend that approach as it is generally not good functional style and not necessary in this case. The preferable approach would be to rewrite the code in a way that each variable is only assigned once.
This is very basic indeed, and it's surprising that you ran into it in such a complicated situation.
Did you port this from some other language?
You need to forget everything you know about programming using assignments.
let val x = y in something
means more or less "within 'something', replace the identifier 'x' with the value of 'y'".
There is no way for you to change the value of x.
Do the substitution (this is not the actual evaluation order or anything, but it should give you an idea of what's going on):
encryptChar("THIS", amount, 0)
=>
let val asciiCode = 0
in
if (not (String.sub("THIS", 0) = #" ")) then
(
asciiCode = ord( String.sub("THIS", 0) ) + amount;
if (asciiCode < ord(#"A")) then asciiCode = asciiCode + 26
else if (asciiCode > ord(#"Z")) then asciiCode = asciiCode - 26
else asciiCode = asciiCode;
"THIS" = replace("THIS", 0, chr(asciiCode))
)
else asciiCode = asciiCode;
0 = 0 + 1;
if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)
else str
end ;
=>
if (not (String.sub("THIS", 0) = #" ")) then
(
0 = ord( String.sub("THIS", 0) ) + amount;
if (0 < ord(#"A")) then 0 = 0 + 26
else if (0 > ord(#"Z")) then 0 = 0 - 26
else 0 = 0;
"THIS" = replace("THIS", 0, chr(0))
)
else 0 = 0;
0 = 0 + 1;
if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)
else str
=>
if (not (String.sub("THIS", 0) = #" ")) then
(
0 = ord( String.sub("THIS", 0) ) + amount;
if true then false
else if false then false
else true;
false
)
else true;
false;
if (0 < (size "THIS" - 1)) then encryptChar("THIS", amount, 0)
else "this"
->
if (not false) then
(
false;
false;
false
)
else true;
false;
if true then encryptChar("THIS", amount, 0)
else "THIS"
=>
(
false;
false;
false
)
false;
encryptChar("THIS", amount, 0)
=>
encryptChar("THIS", amount, 0)
Which is where your infinite loop came from.
You would do well to get hold of an introductory text about ML programming.