Lua Ternary Operations (Code Golfing) - lua

I'm doing a bit of code golfing, and I've gotten to this:
for i=1,100 do for j=1,i do if i%j<1 then io.write(j.." ") end end print() end
Is there any way to get the if statement as an inline? So that it's wrapped into the io.write()

The ternary operation in lua can be mimicked with and..or operators:
a and b or c
is similar to
a ? b : c
under truthy values. For your case:
for i=1,100 do
for j=1,i do
io.write( ((i % j) < 1 and j.." " or '')
-- (i % j) < 1 and io.write(.." ")
end
print() -- why print here?
end
golfed, it is
io.write(i%j<1 and j.." "or'')
which saves you 4 characters

Related

Ruby Loop Countdown Method keeps returning "nil"

I am working on a Ruby challenge for work, and I am unable to create a working method. Every method I try keeps returning "nil".
Here is the question:
Create a method that passes an integer argument to a single parameter. If the integer is greater than 0 print the numbers from the integer to 0. If the number is less than 0 simply print the integer. Use a for loop, while loop, or unless loop to print the range of numbers from the integer to 0.
For example:
sample(4)
output = 3, 2, 1
sample(-1)
output = -1
Here is the code I tried to use
def countdown(n)
loop do
n -= 1
print "#{n}"
break if n <= 0
end
countdown(4)
A method returns the results of the last statement executed. Your loop is returning nil:
def countdown(n)
x = loop do
n -= 1
puts "#{n}"
break if n <= 0
end
x
end
countdown(4)
3
2
1
0
=> nil
Now let's return something:
def countdown(n)
loop do
puts "#{n}"
break if n <= 0
n -= 1
end
"okay we're done"
end
countdown(4)
4
3
2
1
0
=> "okay we're done"
It's not necessary to print inside the function and also outside it - this will cause duplicate printing. Also you are calling print on the positive numbers but not calling print if they are negative or zero. Additionally, you are using print "#{n}" which is the same as print n.
As far as the title of your question goes - "keeps returning nil" - you can change your approach a bit to do the print calls outside the function.
def countdown(n)
n <= 1 ? [n] : (n-1).downto(1).to_a
end
print countdown(n).join(", ")
Try this:
def countdown(n)
n.downto(n > 0 ? 0 : n) { |i| puts i }
end
countdown(4)
# 4
# 3
# 2
# 1
# 0
countdown(-4)
# -4
countdown(0)
# 0
You didn't mention what is to be done if the argument is zero. I've assumed it's treated as a positive or negative number.
Admittedly, this is cheating, as it does not "Use a for loop, while loop, or unless loop...", but Ruby is designed mainly to use iterators and blocks. This, or something like it, is the way to go. I just had a thought: treat that as a suggestion, not a requirement.
By the way, among loops, Kernel#loop was not mentioned, which is strange, as it is quite useful. As for "for loops", who uses them? I never have, not even once.
If you must use a loop, you could do the following.
def countdown(n)
while n > 0
puts n
n-= 1
end
puts n
end
countdown(4)
# 4
# 3
# 2
# 1
# 0
countdown(-4)
# -4
countdown(0)
# 0
You may try this...
def sample (a)
if a > 0
(1..a).to_a.reverse
else
a
end
end
Hope this will work for you

calling config param from another function (concatenate global error)

local otherteam = {}
function onLoad()
...
Config.aaRange.enemyrange:addParam("enemy0", otherteam[0], SCRIPT_PARAM_ONOFF, false)
Config.aaRange.enemyrange:addParam("enemy1", otherteam[1], SCRIPT_PARAM_ONOFF, false)
Config.aaRange.enemyrange:addParam("enemy2", otherteam[2], SCRIPT_PARAM_ONOFF, false)
end
function onDraw()
...
for k = 0, 3, 1 then
if hero.charName == otherteam[k] then
if (Config.aaRange.enemyrange."enemy" .. k) then
...
end
end
end
end
I get Attempt to concatenate global enemy error while running this.
I can easily fix this by just removing the for k loop and having seperate if statements with
if (Config.aaRange.enemyrange.enemy0) then
end
if (Config.aaRange.enemyrange.enemy0) then
end
if (Config.aaRange.enemyrange.enemy0) then
end
But that just seems messy (I got more than 3 configs). I even tried:
j = "enemy" .. k
and adding j instead of enemy0 in the if statement but nothing.
I'm guessing this is because I'm trying to add the string with a number? Sorry, only started using lua a few hours ago :x
Lua supports coercion, so adding a string to a number is valid. But if you write
j = "enemy" .. k
The interpreter takes Config.aaRange.enemyrange.j as Config.aaRange.enemyrange["j"], you should use Config.aaRange.enemyrange[j] instead.
Without another variable, you can write
if Config.aaRange.enemyrange["enemy" .. k] then
Or better:
if Config.aaRange.enemyrange["enemy" .. tostring(k)] then

Ruby regex puncuation

I am having trouble writing this so that it will take a sentence as an argument and perform the translation on each word without affecting the punctuation.
I'd also like to continue using the partition method.
It would be nice if I could have it keep a quote together as well, such as:
"I said this", I said.
would be:
"I aidsay histay", I said.
def convert_sentence_pig_latin(sentence)
p split_sentence = sentence.split(/\W/)
pig_latin_sentence = []
split_sentence.each do |word|
if word.match(/^[^aeiou]+/x)
pig_latin_sentence << word.partition(/^[^aeiou]+/x)[2] + word.partition(/^[^aeiou]+/x)[1] + "ay"
else
pig_latin_sentence << word
end
end
rejoined_pig_sentence = pig_latin_sentence.join(" ").downcase + "."
p rejoined_pig_sentence.capitalize
end
convert_sentence_pig_latin("Mary had a little lamb.")
Your main problem is that [^aeiou] matches every character outside that range, including spaces, commas, quotation marks, etc.
If I were you, I'd use a positive match for consonants, ie. [b-df-hj-np-tv-z] I would also put that regex in a variable, so you're not having to repeat it three times.
Also, in case you're interested, there's a way to make your convert_sentence_pig_latin method a single gsub and it will do the whole sentence in one pass.
Update
...because you asked...
sentence.gsub( /\b([b-df-hj-np-tv-z])(\w+)/i ) { "#{$2}#{$1}ay" }
# iterate over and replace regexp matches using gsub
def convert_sentence_pig_latin2(sentence)
r = /^[^aeiou]+/i
sentence.gsub(/"([^"]*)"/m) {|x| x.gsub(/\w+/) {|y| y =~ r ? "#{y.partition(r)[2]}#{y.partition(r)[1]}ay" : y}}
end
puts convert_sentence_pig_latin2('"I said this", I said.')
# define instance method: String#to_pl
class String
R = Regexp.new '^[^aeiou]+', true # => /^[^aeiou]+/i
def to_pl
self.gsub(/"([^"]*)"/m) {|x| x.gsub(/\w+/) {|y| y =~ R ? "#{y.partition(R)[2]}#{y.partition(R)[1]}ay" : y}}
end
end
puts '"I said this", I said.'.to_pl
sources:
http://www.ruby-doc.org/core-2.1.0/Regexp.html
http://ruby-doc.org/core-2.0/String.html#method-i-gsub

How to do lazy evaluation of Ruby arguments

I have a code to do a check of nil in ruby. So what I want to achieve is this:
for example, if I call get_score_value(nil,(nil-1)). I want ruby to delay the evaluation of nil-1 till it reaches the get_score_value function, instead of evaluate it before it got passed in the function. In another word, I want to pass a mathematical expression as an argument into a method.
What is the most elegant way to do this in ruby? Thanks very much
def get_score_value(value,value2)
value.nil? ? "NULL" : value2.round(2)
end
UPDATE:
I just realized this question is actually related to the topic of lazy and strict evaluation. ( the following is from this great site:
http://www.khelll.com/blog/ruby/ruby-and-functional-programming/
Strict versus lazy evaluation
Strict evaluation always fully evaluates function arguments before invoking the function. Lazy evaluation does not evaluate function arguments unless their values are required to be evaluated. One use of Lazy evaluation is the performance increases due to avoiding unnecessary calculations.
However as the following example shows, Ruby use Strict evaluation strategy:
print length([2+1, 3*2, 1/0, 5-4])
=>ZeroDivisionError: divided by 0
The third parameter of the passed array contains a division by zero operation and as Ruby is doing strict evaluation, the above snippet of code will raise an exception.
You might be interested in using a Proc...
func = Proc.new {|n| n -1 }
def get_score_value(value, proc)
if value.nil?
return proc.call(0)
end
end
p get_score_value(nil, func)
Your proc is like a normal method, it can still test for nil and things like that.
Or, it allows you to provide separate functions to handle those situations:
func1 = Proc.new {|n| n -1 }
func2 = Proc.new { "was nil" }
def check_for_nil(value, funcNil, funcNotNil)
if value.nil?
return funcNil.call()
else
return funcNotNil.call(value)
end
end
p check_for_nil(nil, func2, func1)
p check_for_nil(1, func2, func1)
Also note the potential use of the or keyword in cases when you simply want to convert it to an empty or default type of the input (i.e. use 0 for numbers, [] for arrays, etc.)
def get_score_value(value)
(value or 0).round(2)
end
The Ruby-ish way to do this is to put your expression in your method's block and have the method execute a conditional yield.
def f x
yield if x
end
x = nil
f x do
x - 1
end
You can use a block:
def get_score_value value
value.nil? ? "NULL" : yield
end
x = 1
puts get_score_value(x) { x-1 } #=> 0
x = nil
puts get_score_value(x) { x-1 } #=> "NULL"

Ruby shortcut for "if (number in range) then..."

Is there a Ruby shortcut for the following?
if (x > 2) and (x < 10)
do_something_here
end
I thought I saw something to that effect, but cannot find a reference to it. Of course it's hard to lookup when you don't know what operator you're looking for.
if (3..9).include? x
# whatever
end
As a sidenote, you can also use the triple equals operator for ranges:
if (3..9) === x
# whatever
end
This lets you use them in case statements as well:
case x
when 3..9
# Do something
when 10..17
# Do something else
end
do_something if (3..9).include?( x ) # inclusive
do_something if (3...10).include?( x ) # inclusive start, exclusive end
See the Range class; you can read an introduction to them hosted on my website.
Comparable#between?
do_something if x.between?(2, 10)
Something like this?
do_something if (3..9) === x
or
r = 3..9
if r === x
. . .

Resources