I have a loop that takes out each word in a string using token, then I want to be able to do computations on it like this:
(1 2 add 3 4 add)
But any way you code it i keep getting
7
add
2
1
I want it to be
7
3
This is what I am working with
{ %loop
pstack
(repl> )print flush
(%lineedit)(r)file
dup bytesavailable string readstring pop
{
token
{}{exit}ifelse
exch
dup () eq {pop exec exit}if
exec
}loop
}loop
I would advise you to write stack comments at the end of each line. It really helps.
{ %loop
pstack
(repl> )print flush
(%lineedit)(r)file % f
dup bytesavailable string readstring pop % s
{
token % s t b
{}{exit}ifelse % s t
exch % t s
dup () eq {pop exec exit}if % t s
exec % t
}loop
}loop
So you're executing the remaining substring instead of the token. You need another exch in there before the exec in the inner loop. That would execute the token instead of the substring. But a problem with this is that the string is sitting there on the stack. So add won't work because it will find a string on top of the stack instead of the numbers below.
So it may be better to save the substring by name before exec-ing, and then put it back before the next iteration.
{ % s
token % s t b
{}{exit}ifelse % s t
exch % t s
dup () eq {pop exec exit}if % t s
/rem exch def % t
exec
rem % s
}loop
This portion may be more confusing than helpful to those very new to postscript. Read on at your own peril. If you get lost in the middle, be sure to see the very end where there is a final super-simple technique.
The next question a postscript hacker should ask is: "How can I do this without polluting the name space with this rem name?"
The insane trick I would use for this is to exploit the loop operator to make a procedure body with extra storage.
{ procedure body } exec
{ procedure body exit extra storage } loop
Both constructs above will execute procedure body and then return control. But using loop with an explicit exit lets us pack extra things into the array.
So, we take the inner loop from above.
token{}{exit}ifelse exch dup()eq{pop exec exit}if/rem exch def exec rem
Wrap it in an "exit-loop".
{
token{}{exit}ifelse exch dup()eq{pop exec exit}if/rem exch def exec rem
exit } loop
And we're going to store the string remainder just after exit.
{
token{}{exit}ifelse exch dup()eq{pop exec exit}if/rem exch def exec rem
exit STR } loop
Replace the /name exch def with code that stores into an array. This array will be a subarray of the loop body which just holds the [ STR ] extra storage.
/rem exch def --> ARR exch 0 exch put
rem --> ARR 0 get
{
token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec ARR 0 get
exit STR } loop
This loop is of course a straight-shot: it doesn't actually loop. So to replace the inner loop from above, we wrap it in another loop.
{ {
token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec ARR 0 get
exit STR } loop } loop
Then we need to insert the subarray where ARR is in the code. This is the subarray of the (inner) inner loop that contains the (dummy) STR token.
% 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
{ { token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec ARR 0 get exit STR } loop } loop
So we need a subarray [20, 1] to be inserted at array[10] and array[16]. And we can do this before calling loop at the outer scope.
{ {
token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec ARR 0 get
exit STR } loop }
dup 0 get % loop-body inner-loop get a copy of the exit-loop
dup 20 1 getinterval % loop-body inner-loop [STR] take a subarray of the exit-loop
2 copy 10 exch put % loop-body inner-loop [STR] insert in position 10
16 exch put % loop-body' insert in position 16
loop % call the loop operator
There, a loop with no name. :)
Notice, we still have the dummy name STR in the code, and that's ok. It will parse as a name and allocate an extra slot in the array. And it doesn't need to be defined anywhere because it never gets executed.
An improvement over the above. We really do not need the second ARR in the template code. We can store the string directly into the procedure array at the position where it is needed. Then we don't even need the "exit-loop". So the template becomes:
% 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
{ token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec STR } loop
And the fully articulated loop
{ token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec STR }
dup dup 10 exch % loop loop 10 loop prepare stack
16 1 getinterval % loop loop 10 [STR] take a subarray
put % loop insert in position 10
loop % call loop operator
An improvement of the improvement. We don't actually need a subarray either. We can store the entire loop array in the ARR position and use the index 16 instead of 0 in the storing code.
{ token not{exit}if exch dup()eq{pop exec exit}if ARR exch 16 exch put exec STR }
dup 10 1 index % loop loop 10 loop prepare stack
put % loop insert in position 10
loop % call loop operator
--
Much later...
This is way more complicated than it needs to be. We can simply make a little array to sequence the execution of these two things.
{exec rem}
Thus:
{ % s
token % s t b
not{exit}if % s t
exch % t s
dup () eq {pop exec exit}if % t s
/exec cvx exch 2 array astore cvx % t {exec s}
exec
}loop
Token simply returns the 'tokenised' object on the stack, it doesn't do anything further with it. If you want to perform the operation you will have to check the type of the returned object and 'exec' the executable ones.
Related
I'm doing some codewars and arr[index] keeps returning nil. I've done this a few different ways, and I'm sure the array exists, as well as the index. What's wrong here, is it syntax?
As I've mentioned in the title, I want to find the last digit of the array.
if arr[index] <= 0 then
return -1
end
Full Code:
local solution = {}
function solution.newAvg(arr, navg)
local currentAverage = 0
local index = 0
for i, v in pairs(arr) do
index = i
currentAverage = currentAverage + v
end
if arr[index] <= 0 then
return -1
end
return math.ceil(((index+1) * navg) - currentAverage)
end
return solution
I see two issues with your code:
Edge case: Empty array
If arr = {}, the loop for i, v in pairs(arr) do won't execute at all and index will remain at 0. Since arr is empty, arr[0] will be nil and arr[index] <= 0 will fail with an "attempt to compare a nil value" error.
Lack of ordering guarantee
You use pairs rather than ipairs to loop over what I assume is a list. This means keys & values might be traversed in any order. In practice pairs usually (but not always!) traverses the list part of a table in the same order as ipairs, but the reference manual clearly states that you can't rely on no specific order. I don't think CodeWars is this advanced but consider the possibility that pairs may be overridden to deliberately shuffle the order of traversal in order to check whether you're relying on the dreaded "undefined behavior". If this is the case, your "last index" might actually be any index that happens to be visited last, obviously breaking your algorithm.
Fixes
I'll assume arr is an "array", that is, it only contains keys from 1 to n and all values are non-nil (i.e. there are no holes). Then you can (and should!) use ipairs to loop over the "array":
for i, v in ipairs(arr) do ... end
I don't know the problem statement so it's hard to tell how an empty array should be handled. I'll assume that it should probably return 0. You could add a simply early return at the top of the function for that: if arr[1] == nil then return 0 end. Nonempty arrays will always have arr[1] ~= nil.
I want to find the last digit of the array.
If you mean the last integer (or entry/item) of the array:
local last = array[#array]
If you mean the last digit (for example array = {10, 75, 44, 62} and you want 2), then you can get the last item and then get the last digit using modulo 10:
local last = array[#array] % 10
for i, v in pairs(arr) do
index = i
currentAverage = currentAverage + v
end
Just a reminder:
#array returns the number of items in a table.
In Lua, arrays are implemented using integer-indexed tables.
There's a difference between pairs() and ipairs().
Regarding point 3 above, the following code:
local array = {
[1] = 12,
[2] = 32,
[3] = 41,
[4] = 30,
[5] = 14,
[6] = 50,
[7] = 62,
[8] = 57
}
for key, value in pairs(array) do
print(key, value)
end
produces the following output (note that the order of keys is not respected):
8 57
1 12
2 32
3 41
4 30
5 14
6 50
7 62
while the same code above with pairs() replaced with ipairs() gives:
1 12
2 32
3 41
4 30
5 14
6 50
7 62
8 57
So, this might be the cause of your problem.
I am new to programming in LUA. And I am not able to solve this question below.
Given a number N, generate a star pattern such that on the first line there are N stars and on the subsequent lines the number of stars decreases by 1.
The pattern generated should have N rows. In every row, every fifth star (*) is replaced with a hash (#). Every row should have the required number of stars (*) and hash (#) symbols.
Sample input and output, where the first line is the number of test cases
This is what I tried.. And I am not able to move further
function generatePattern()
n = tonumber(io.read())
i = n
while(i >= 1)
do
j = 1
while(j<=i)
do
if(j<=i)
then
if(j%5 == 0)
then
print("#");
else
print("*");
end
print(" ");
end
j = j+1;
end
print("\n");
i = i-1;
end
end
tc = tonumber(io.read())
for i=1,tc
do
generatePattern()
end
First, just the stars without hashes. This part is easy:
local function pattern(n)
for i=n,1,-1 do
print(string.rep("*", i))
end
end
To replace each 5th asterisk with a hash, you can extend the expression with the following substitution:
local function pattern(n)
for i=n,1,-1 do
print((string.rep("*", i):gsub("(%*%*%*%*)%*", "%1#")))
end
end
The asterisks in the pattern need to be escaped with a %, since * holds special meaning within Lua patterns.
Note that string.gsub returns 2 values, but they can be truncated to one value by adding an extra set of parentheses, leading to the somewhat awkward-looking form print((..)).
Depending on Lua version the metamethod __index holding rep for repeats...
--- Lua 5.3
n=10
asterisk='*'
print(asterisk:rep(n))
-- puts out: **********
#! /usr/bin/env lua
for n = arg[1], 1, -1 do
local char = ''
while #char < n do
if #char %5 == 4 then char = char ..'#'
else char = char ..'*'
end -- mod 5
end -- #char
print( char )
end -- arg[1]
chmod +x asterisk.lua
./asterisk.lua 15
Please do not follow this answer since it is bad coding style! I would delete it but SO won't let me. See comment and other answers for better solutions.
My Lua print adds newlines to each printout, therefore I concatenate each character in a string and print the concatenated string out afterwards.
function generatePattern()
n = tonumber(io.read())
i = n
while(i >= 1)
do
ouput = ""
j = 1
while(j<=i)
do
if(j%5 == 0)
then
ouput=ouput .. "#";
else
ouput=ouput .. "*";
end
j = j+1;
end
print(ouput);
i = i-1;
end
end
Also this code is just yours minimal transformed to give the correct output. There are plenty of different ways to solve the task, some are faster or more intuitive than others.
The following script finds prime numbers in a range from 1 to 13.
When I explicitly iterate over the table that contains the results I can see that the script works as expected. However, if I use unpack() function on the table only the first 3 numbers get printed out.
From docs: unpack is "a special function with multiple returns. It receives an array and returns as results all elements from the array, starting from index 1".
Why is it not working in the script below?
t = {}
for i=1, 13 do t[i] = i end
primes = {}
for idx, n in ipairs(t) do
local isprime = true
for i=2, n-1 do
if n%i == 0 then
isprime = false
break
end
end
if isprime then
primes[idx] = n
end
end
print('loop printing:')
for i in pairs(primes) do
print(i)
end
print('unpack:')
print(unpack(primes))
Running
$ lua5.3 primes.lua
loop printing:
1
2
3
5
7
13
11
unpack:
1 2 3
Change
primes[idx] = n
to
primes[#primes+1] = n
The reason is that idx is not sequential as not every number is a prime.
I've tried looking all over the place and haven't found a good answer for this. I'm trying to write nested foreach loops in tcl that read lines from two different text files. The inner foreach loop will run completely through but the outer foreach loop will break after just evaluating the first line in the file. The text files look something like this (except much larger).
input1.txt:
1
2
3
4
5
6
7
8
9
10
input2.txt:
a
b
c
d
e
f
g
h
i
j
and my nested foreach loops are constructed like this:
# Open file 1;
set FID1 [open input1.txt r];
# Open file 2
set FID2 [open input2.txt r];
# Open an output file to check the foreach loops;
set outFID [open outputcheck.txt w];
# Nest the foreach loops to read both files
foreach PropLine [split [read $FID1] \n] {
foreach GMprop [split [read $FID2] \n] {
puts $outFID "$PropLine $GMprop";
}
}
close $FID1;
close $FID2;
close $outFID;
and my outputcheck.txt file contains
1 a
1 b
1 c
1 d
1 e
1 f
1 g
1 h
1 i
1 j
I am running this code through the OpenSEES.exe executable on a PC with Windows 7 operating system.
Thanks in advance for any insight.
If you want to do something with file2 for every line of file1, then
foreach PropLine [split [read $FID1] \n] {
foreach GMprop [split [read $FID2] \n] {
puts $outFID "$PropLine $GMprop";
}
# jump back to the start of the file, so you can re-read it
# for the next iteration of the outer foreach loop
seek $FID2 0 start
}
But, it just looks like you want to pair the lines, so
foreach PropLine [split [read -nonewline $FID1] \n] \
GMprop [split [read -nonewline $FID2] \n] \
{
puts $outFID "$PropLine $GMprop";
}
Tcl lets you iterate over multiple lists simultaneously, very handy: http://tcl.tk/man/tcl8.6/TclCmd/foreach.htm
Although I'd be tempted to read the files line-by-line:
while {true} {
set status1 [gets $FID1 PropLine]
set status2 [gets $FID2 GMprop]
if {$status1 == -1 && $status2 == -1} break
puts $outFID "$PropLine $GMprop"
}
I am trying to understand string concatenation.
Why doesn't the fourth line give the same result as the second one?
counter = 0
"#{counter+1}. test" gives "1. test"
counter = 0
"#{++counter}. test" gives "0. test"
++ just looks like the increment operator. It's actually two unary + operators, so it's just the same as plain old counter
There is no ++ operator in Ruby. What ++counter says is "give me the positive result of the positive result of 0" which is 0.
++ is not an operator in Ruby. If you want to use a pre-increment operator then use:
counter += 1
Because, ++ is not an operator for Ruby like C or Java.
In Ruby, ++x or --x will do nothing! In fact, they behave as multiple unary prefix operators: -x == ---x == -----x == ...... or +x == +++x == +++++x == ......
To increment a number, simply write x += 1.
To decrement a number, simply write x -= 1.
Proof :
x = 1
+x == ++++++x # => true
-x == -----x # => true
x # => 1 # value of x doesn't change.
In C
++counter //Pre Increment
counter++// Post Incremet
But In Ruby ++ has no existence ,
So if you want to increment a variable then you have to simply write
counter = counter + 1
In your case you have to write just
"#{counter = counter + 1}. test" gives "1. test"
And will increment the value counter by 1