I know how for loops work and I use them quite often but also seem to often come across a # in others' code and I want to know what it is for and how to use it. An example of this would be:
for i = 1, #npc do local v = npc[i]
I cant seem to find anything online regarding this, maybe my searches just aren't good but it would be nice if someone could explain it for me, thanks.
In Lua, # is the length operator. for i = 1, #npc essentially loops from 1 to the length of the npc array.
As was already pointed out, it gets the length of a list. However, there's another thing worth pointing out: that for loop is suboptimal and unidiomatic. It would be better written as for i, v in ipairs(npc) do. In general, using # in a for loop is almost always the wrong thing to do.
Related
I am kinda of new in Mathematica and there are lots of appendto in my code which I think take up a look of time. I know there are some other ways optimize but I cannot really know exactly how to achieve. I think getBucketShocks can be improved a lot? Anyone?
getBucketShocks[BucketPivots_,BucketShock_,parallelOffset_:0]:=
Module[{shocks,pivotsNb},
shocks={};
pivotsNb=Length[BucketPivots];
If[pivotsNb>1,
AppendTo[shocks,LinearFunction[{0,BucketShock},{BucketPivots[[1]],BucketShock},{BucketPivots[[2]],0},BucketPivots[[2]],0},parallelOffset]];
Do[AppendTo[shocks,LinearFunction[{BucketPivots[[i-1]],0},{BucketPivots[[i]],BucketShock},{BucketPivots[[i+1]],0},{BucketPivots[[i+1]],0},parallelOffset]],{i,2,pivotsNb-1}];
AppendTo[shocks,LinearFunction[{BucketPivots[[pivotsNb-1]],0},{BucketPivots[[pivotsNb]],BucketShock},{BucketPivots[[pivotsNb]],BucketShock},{BucketPivots[[pivotsNb]],BucketShock},parallelOffset]],
If[pivotsNb==1,AppendTo[shocks,BucketShock+parallelOffset&]];
];
shocks];
LinearInterpolation[x_,{x1_,y1_},{x2_,y2_},parallelOffset_:0]:=parallelOffset+y1+(y2-y1)/(x2-x1)*(x-x1);
LinearFunction[p1_,p2_,p3_,p4_,parallelOffset_:0]:=Which[
#<=p1[[1]],parallelOffset+p1[[2]],
#<=p2[[1]],LinearInterpolation[#,p1,p2,parallelOffset],
#<=p3[[1]],LinearInterpolation[#,p2,p3,parallelOffset],
#<=p4[[1]],LinearInterpolation[#,p3,p4,parallelOffset],
#>p4[[1]],parallelOffset+p4[[2]]]&;
I think you can optimize the middle Do loop a lot by using some form of Map one way or another. At every iteration, you're trying to access 3 adjacent elements of BucketPivots. This seems like this would be the easiest to do with MovingMap, but you need to jump through a few hoops to get the arguments in the right place. This one is probably the easiest solution:
shocks = MovingMap[
LinearFunction[
{#[[1]], 0},
{#[[2]], BucketShock},
{#[[3]], 0},
{#[[3]], 0},
parallelOffset
]&,
BucketPivots,
2
]
As a general principle: if you want to do a Do or For loop in Mathematica that runs over the Length of another list, try to find a way you can do it with a function from the Map family (Map, MapIndexed, MapAt, MapThread, etc.) and get familiar with those. They are great substitutions for iterations!
After this, the first and last elements of shocks you can then add with AppendTo.
BTW: here's a free tip. I recommend that in Mathematica you avoid giving variables and functions names that start with a capital (like you did with BucketPivots). All of Mathematica's own symbols start with capitals, so if you avoid starting with them yourself, you'll never clash with a build-in function.
Years ago in college,I tinkered with some prolog, but that's long forgotten, so I count as a complete beginnner again (humbling!)
Anyway, I was playing with some of Bruce Tate's code, and came up with what I thought was a sudoku solver for the full (9x9) game. But, when I run it, it generates some very odd output:
Solution = [_#3(2..3),_#24(2:7),_#45(2..3:5:7),_#66(2..3:8),_#87(2..3:5..6:8),4,_#121(2:5..6),1,9,6,8,_#194(2..5:7:9),_#215(1..3:9),_#236(2..3:5:9),_#257(1..2:5:9),_#278(2:4..5),_#299(4:7),_#320(5:7),_#341(1..2),_#362(2:4),_#383(2:4..5:9),_#404(1..2:9),_#425(2:5..6:9),7,3,_#472(4:6),8,4,1,_#532(2:8),_#553(2:8),7,3,9,5,6,7,5,_#689(6:8),_#710(4:8..9),_#731(4:6:8..9),_#752(6:8..9),1,2,3,_#828(2..3),9,_#862(2..3:6),5,1,_#909(2:6),7,8,4,8,_#990(2:4:7),1,6,_#1037(2..5:9),_#1058(2:5:9),_#1079(4..5),_#1100(3..4:7),_#1121(5:7),5,_#1163(4:6..7),_#1184(4:6..7),_#1205(1:3..4:8),_#1226(3..4:8),_#1247(1:8),_#1268(4:6:8),9,2,9,3,_#1341(2:4:6),7,_#1375(2:4..5:8),_#1396(1..2:5:8),_#1417(4..6:8),_#1438(4:6),_#1459(1:5)]
yes
I was expecting ... well, frankly I was half expecting total failure :) but I thought that only numbers could show up in this output. What's it trying to tell me with those #-tagged things, and stuff in parens that looks like ranges? Is it trying to say there are many possible solutions and it's telling me all at once (seems unlikely as it's very unhelpful if it is) or is this some kind of error state (in which case, why does it compile my code and say "yes" to this query?)
Any insight gratefully received!
I think it's the result of a set of constraints not sufficiently strong to determine a solution without search. For instance, _#3(2..3) could means that a variable named _#3 could assume values in range 2..3. You could try to label the variables, something like
..., labeling([], Solution).
Syntax details depend on your solver, of course...
I am just learning ruby and KevinC's response (in this link) makes sense to me with one exception. I don't understand why the code is encompassed in the arr.each do |i| #while... end That part seems redundant to me as the 'while' loop is already hitting each of the positions? Can someone explain?
The inner loop finds a bubble and carries it up; if it finds another, lighter bubble, it switches them around and carries the lighter one. So you need several passes through the array to find all the bubbles and carry them to the correct place, since you can't float several bubbles at the same time.
EDIT:
The each is really misused in KevinC's code, since it is not used for its normal purpose: yielding elements of the collection. Instead of arr.each, it would be better to use arr.size.times - as it would be more informative to the reader. Redefining the i within the block is adding insult to injury. While none of this will cause the code to be wrong as such, it is misleading.
The other problem with the code is the fact that it does not provide the early termination condition (swapped in most other answers on that question). In theory, bubble sort could find the array sorted in the first pass; the other size - 1 steps are unnecesary. KevinC's code would still dry-hump the already sorted array, never realising it is done.
As for rewrite into block-less code, it is certainly possible, but you need to understand that blocks syntax is very idiomatic in Ruby, and non-block loops are almost unheard of in Ruby world. While Ruby has for, it is pretty much never used in Ruby. But...
arr.each do |i|
...
end
is equivalent to
for i in arr
...
end
which is, again, at least for the array case, equivalent to
index = 0
while index < arr.size
i = arr[index]
...
index += 1
end
I've studied the poignant guide and it really has helped me pick up the
language pretty fast. After that, I started solving some coding puzzles
using Ruby. It just helps a lot to get used to the language I feel.
I'm stuck with one such puzzle. I have solved it very easily since it is
pretty straight-forward, but the solution is being rejected (by the host
website) with the error 'Time Exceded'! I know that Ruby cannot compete
with the speed of C/C++ but it has got to be able to answer a tiny puzzle on a website which accepts
solutions in Ruby?
The puzzle is just a normal sort.
This is my solution
array ||= []
gets.to_i.times do
array << gets
end
puts array.sort
My question is, is there any other way I can achieve high-speed sorting with Ruby? I'm using the basic Array#sort here, but is there a way to do it faster, even though it means lot more lines of code?
I've solved that problem, and let me tell you using a nlogn algorithm to pass that is almost impossible unless you are using a very optimized C/Assembly version of it.
You need to explore other algorithms. Hint: O(n) Algorithm will do the trick, even for ruby.
Good Luck.
You're sorting strings when you should be sorting ints. Try:
array << gets.to_i
If there is no need for duplicate values to be repeated:
h = {}
gets.to_i.times{h[gets.to_i] = true}
(0..100000).each{|n| puts(n) if h[n]}
If duplicate values must be repeated:
h = Hash.new(0)
gets.to_i.times{h[gets.to_i] += 1}
(0..100000).each{|n| h[n].times{puts(n)}}
I found myself keep writing pretty long one-liner code(influenced by shell pipe), like this:
def parseranges(ranges, n):
"""
Translate ":2,4:6,9:" to "0 1 3 4 5 8 9...n-1"
== === == === ===== =========
"""
def torange(x, n):
if len(x)==1:
(x0, ) = x
s = 1 if x0=='' else int(x0)
e = n if x0=='' else s
elif len(x)==2:
(x0, x1) = x
s = 1 if x0=='' else int(x0)
e = n if x1=='' else int(x1)
else:
raise ValueError
return range(s-1, e)
return sorted(reduce(lambda x, y:x.union(set(y)), map(lambda x:torange(x, n), map(lambda x:x.split(':'), ranges.split(','))), set()))
I felt ok when I written it.
I thought long one-liner code is a functional-programming style.
But, several hours later, I felt bad about it.
I'm afraid I would be criticized by people who may maintain it.
Sadly, I've get used to writing these kind of one-liner.
I really want to know others' opinion.
Please give me some advice. Thanks
I would say that it is bad practice if you're sacrificing readability.
It is common wisdom that source code is written once but read many times by different people. Therefore it is wise to optimize source code for the common case: being read, trying to understand.
My advice: Act according to this principle. Ask yourself: Can anybody understand any piece of my code more easily? When the answer is not a 100% "No, I can't even think of a better way to express the problem/solution." then follow your gut feeling and reformat or recode that part.
Unless performance is a major consideration, readability of the code should be given high major priority. Its really important for its maintainability.
A relevant quote from the book Structure and Interpretation of Computer Programs.
"Programs should be written for people to read, and only incidentally for machines to execute."
(Update 2022-03-25: My answer refers to a previous revision of the question.)
The first and third examples are acceptable to me. They are close enough to the application domain so that I can easily see the intention of the code.
The second example is much too clever. I don't even have an idea about its purpose. Can you rewrite it in maybe five lines, giving the variables longer names?