nil can't be coerced into Bignum - ruby

I'm trying to do Euler project 13:
Work out the first ten digits of the sum of the following one-hundred 50-digit numbers.
list = [37107287533902102798797998220837590246510135740250,
46376937677490009712648124896970078050417018260538,
74324986199524741059474233309513058123726617309629,
91942213363574161572522430563301811072406154908250,
23067588207539346171171980310421047513778063246676,
89261670696623633820136378418383684178734361726757,
28112879812849979408065481931592621691275889832738,
44274228917432520321923589422876796487670272189318,
47451445736001306439091167216856844588711603153276,
70386486105843025439939619828917593665686757934951,
62176457141856560629502157223196586755079324193331,
64906352462741904929101432445813822663347944758178,
92575867718337217661963751590579239728245598838407,
58203565325359399008402633568948830189458628227828,
80181199384826282014278194139940567587151170094390,
35398664372827112653829987240784473053190104293586,
86515506006295864861532075273371959191420517255829,
71693888707715466499115593487603532921714970056938,
54370070576826684624621495650076471787294438377604,
53282654108756828443191190634694037855217779295145,
36123272525000296071075082563815656710885258350721,
45876576172410976447339110607218265236877223636045,
17423706905851860660448207621209813287860733969412,
81142660418086830619328460811191061556940512689692,
51934325451728388641918047049293215058642563049483,
62467221648435076201727918039944693004732956340691,
15732444386908125794514089057706229429197107928209,
55037687525678773091862540744969844508330393682126,
18336384825330154686196124348767681297534375946515,
80386287592878490201521685554828717201219257766954,
78182833757993103614740356856449095527097864797581,
16726320100436897842553539920931837441497806860984,
48403098129077791799088218795327364475675590848030,
87086987551392711854517078544161852424320693150332,
59959406895756536782107074926966537676326235447210,
69793950679652694742597709739166693763042633987085,
41052684708299085211399427365734116182760315001271,
65378607361501080857009149939512557028198746004375,
35829035317434717326932123578154982629742552737307,
94953759765105305946966067683156574377167401875275,
88902802571733229619176668713819931811048770190271,
25267680276078003013678680992525463401061632866526,
36270218540497705585629946580636237993140746255962,
24074486908231174977792365466257246923322810917141,
91430288197103288597806669760892938638285025333403,
34413065578016127815921815005561868836468420090470,
23053081172816430487623791969842487255036638784583,
11487696932154902810424020138335124462181441773470,
63783299490636259666498587618221225225512486764533,
67720186971698544312419572409913959008952310058822,
95548255300263520781532296796249481641953868218774,
76085327132285723110424803456124867697064507995236,
37774242535411291684276865538926205024910326572967,
23701913275725675285653248258265463092207058596522,
29798860272258331913126375147341994889534765745501,
18495701454879288984856827726077713721403798879715,
38298203783031473527721580348144513491373226651381,
34829543829199918180278916522431027392251122869539,
40957953066405232632538044100059654939159879593635,
29746152185502371307642255121183693803580388584903,
41698116222072977186158236678424689157993532961922,
62467957194401269043877107275048102390895523597457,
23189706772547915061505504953922979530901129967519,
86188088225875314529584099251203829009407770775672,
11306739708304724483816533873502340845647058077308,
82959174767140363198008187129011875491310547126581,
97623331044818386269515456334926366572897563400500,
42846280183517070527831839425882145521227251250327,
55121603546981200581762165212827652751691296897789,
32238195734329339946437501907836945765883352399886,
75506164965184775180738168837861091527357929701337,
62177842752192623401942399639168044983993173312731,
32924185707147349566916674687634660915035914677504,
99518671430235219628894890102423325116913619626622,
73267460800591547471830798392868535206946944540724,
76841822524674417161514036427982273348055556214818,
97142617910342598647204516893989422179826088076852,
87783646182799346313767754307809363333018982642090,
10848802521674670883215120185883543223812876952786,
71329612474782464538636993009049310363619763878039,
62184073572399794223406235393808339651327408011116,
66627891981488087797941876876144230030984490851411,
60661826293682836764744779239180335110989069790714,
85786944089552990653640447425576083659976645795096,
66024396409905389607120198219976047599490197230297,
64913982680032973156037120041377903785566085089252,
16730939319872750275468906903707539413042652315011,
94809377245048795150954100921645863754710598436791,
78639167021187492431995700641917969777599028300699,
15368713711936614952811305876380278410754449733078,
40789923115535562561142322423255033685442488917353,
44889911501440648020369068063960672322193204149535,
41503128880339536053299340368006977710650566631954,
81234880673210146739058568557934581403627822703280,
82616570773948327592232845941706525094512325230608,
22918802058777319719839450180888072429661980811197,
77158542502016545090413245809786882778948721859617,
72107838435069186155435662884062257473692284509516,
20849603980134001723930671666823555245252804609722,
53503534226472524250874054075591789781264330331690]
Here is my code:
def countNumbers(list)
value = 0
(0..list.count).each { |y| value += list[y] }
return value
end
puts "#{countNumbers(list)}"
I get: *nil can't be coerced into Bignum* error when I run the code.

The issue is with the range in countNumbers method.
0..list.count returns 0 to 100 with 100 included but list[100] is nil.
Change it to 0...list.count with return 0 to 99.
See the documentation to better understand using .. and ...

Related

Ruby each block, does not return value

This following Code doesn't work, the Problem is inside of the calc_fitness method, the each block does not return an value, and i dont know why
# takes an array, splices them into groups of 2 and returns a sum of values read from the matrix
def calc_fitness(hypothesis_arr)
hypothesis_arr.each_slice(2).to_a.map{|v| $distances[v.first,v.last]}
end
def main
# filling the matrix, with random values
$distances = create_sym_matrix
p calc_fitness((0..99).to_a)
end
main
# => [67,67,67,67....67,] #these should not be the same, which means i the block alway returns the same value. Why?
This happens because each returns itself (an instance of Enumerator) and each_slice return nil.
https://ruby-doc.org/core/Enumerable.html#method-i-each_slice
You could try changing the each to a map
To simplify and get a visual of what was generated, I used:
(1..99).to_a.each_slice(2).map { |v| { first: v.first, last: v.last } }
=> [{:first=>1, :last=>2}, {:first=>3, :last=>4}, {:first=>5, :last=>6}, {:first=>7, :last=>8}, {:first=>9, :last=>10}, {:first=>11, :last=>12}, {:first=>13, :last=>14}, {:first=>15, :last=>16}, {:first=>17, :last=>18}, {:first=>19, :last=>20}, {:first=>21, :last=>22}, {:first=>23, :last=>24}, {:first=>25, :last=>26}, {:first=>27, :last=>28}, {:first=>29, :last=>30}, {:first=>31, :last=>32}, {:first=>33, :last=>34}, {:first=>35, :last=>36}, {:first=>37, :last=>38}, {:first=>39, :last=>40}, {:first=>41, :last=>42}, {:first=>43, :last=>44}, {:first=>45, :last=>46}, {:first=>47, :last=>48}, {:first=>49, :last=>50}, {:first=>51, :last=>52}, {:first=>53, :last=>54}, {:first=>55, :last=>56}, {:first=>57, :last=>58}, {:first=>59, :last=>60}, {:first=>61, :last=>62}, {:first=>63, :last=>64}, {:first=>65, :last=>66}, {:first=>67, :last=>68}, {:first=>69, :last=>70}, {:first=>71, :last=>72}, {:first=>73, :last=>74}, {:first=>75, :last=>76}, {:first=>77, :last=>78}, {:first=>79, :last=>80}, {:first=>81, :last=>82}, {:first=>83, :last=>84}, {:first=>85, :last=>86}, {:first=>87, :last=>88}, {:first=>89, :last=>90}, {:first=>91, :last=>92}, {:first=>93, :last=>94}, {:first=>95, :last=>96}, {:first=>97, :last=>98}, {:first=>99, :last=>99}]
Now at this point I'm not sure what that function is doing that is assigned to $distances. You might want to provide the code for that or give some more detail on what your are attempting to accomplish.

IF, invalid syntax error

if volt.isalpha() or res.isalpha() or amp.isalpha():
What did I do wrong here? I get an INVALID SYNTAX, I am using this for a calculator program I am making. It calculates voltage, resistance, and amperage. But thats the easy part, I am just trying to make it fool proof. I have 3 variables in the code (volt, amp, res) that are inputted by the user. I just wanna make sure that they don't type in anything stupid. Like letters for e.g. ...
try:
float(volt) >= 0 and float(res) >= 0 and float(amp) >= 0
print("")
print("You put a value for everything. You don't need the calculator.")
allowed = 0
if volt.isalpha() or res.isalpha() or amp.isalpha():
print("You typed in characters for one of the values, this calculator doesn't use letters.")
allowed = 0
def find_voltage(a,b): # V = I * R
voltage = a * b
return(voltage)`
You don't have an except block after try - it is required. Do something like:
try:
float(volt) >= 0 and float(res) >= 0 and float(amp) >= 0
print("")
print("You put a value for everything. You don't need the calculator.")
allowed = 0
except ValueError:
print("Oops, you messed up.")
Additionally, the line
float(volt) >= 0 and float(res) >= 0 and float(amp) >= 0
doesn't do anything. You'll need to assign it to a variable, then check the results of the variable - if True, do one thing, if False, do something else.

Referencing array of arrays in while loop

I am trying to reference and set variables equal to specific elements within an array of arrays, shown here :
student = [["Last", "Doofus"], ["First", "Douglas"], ["Exam", "75"], ["Homework", "65"], ["Attendance", "60"]]
The ultimate goal is to find out the final grade based on these grades. for example, here is my code :
while line = gets
examRaw = student[2][1].to_i
hwRaw = student[3][1].to_i
exam = (examRaw * 0.5) / 100
hw = (hwRaw * 0.3) / 100
final = exam + hw
puts "Final Numeric Grade = " + final
end
I am receiving an error on the examRaw line. The error I am receiving is :
`<main>': undefined method [] for #<Enumerator:0x000000021059d0> (NoMethodError)`.
I have tested this in irb with the same exact array and it seems to have no problem finding the numbers that I need to be referenced. For example :
irb(main):016:0> student[2][1].to_i
=> 75
What is causing the error?

Ruby driver tests failing for credit card with luhn algorithm

I worked up a working code to check if a credit card is valid using luhn algorithm:
class CreditCard
def initialize(num)
##num_arr = num.to_s.split("")
raise ArgumentError.new("Please enter exactly 16 digits for the credit card number.")
if ##num_arr.length != 16
#num = num
end
def check_card
final_ans = 0
i = 0
while i < ##num_arr.length
(i % 2 == 0) ? ans = (##num_arr[i].to_i * 2) : ans = ##num_arr[i].to_i
if ans > 9
tens = ans / 10
ones = ans % 10
ans = tens + ones
end
final_ans += ans
i += 1
end
final_ans % 10 == 0 ? true : false
end
end
However, when I create driver test codes to check for it, it doesn't work:
card_1 = CreditCard.new(4563960122001999)
card_2 = CreditCard.new(4563960122001991)
p card_1.check_card
p card_2.check_card
I've been playing around with the code, and I noticed that the driver code works if I do this:
card_1 = CreditCard.new(4563960122001999)
p card_1.check_card
card_2 = CreditCard.new(4563960122001991)
p card_2.check_card
I tried to research before posting on why this is happening. Logically, I don't see why the first driver codes wouldn't work. Can someone please assist me as to why this is happening?
Thanks in advance!!!
You are using a class variable that starts with ##, which is shared among all instances of CreditCard as well as the class (and other related classes). Therefore, the value will be overwritten every time you create a new instance or apply check_card to some instance. In your first example, the class variable will hold the result for the last application of the method, and hence will reflect the result for the last instance (card_2).

Radix sort not working in Lua

Firstly I should mention I've not been coding very long at all, although that much is probably obvious from my code :P
I'm having two problems, firstly the sort isn't functioning correctly but does sort the numbers by their length. Any help here would be appreciated.
Secondly it's changing both the table it grabs and the table it returns (not sure why). How do I prevent it changing the table it grabs?
I'd prefer if people didn't post a fully optisimised premade code as I'm not going to learn or understand anything that way.
function radix_sort(x)
pass, bucket, maxstring = 0, x, 2
while true do
pass = pass + 1
queue = {}
for n=#bucket,1,-1 do
key_length = string.len(bucket[n])
key = bucket[n]
if pass == 1 and key_length > maxstring then
maxstring = key_length
end
if key_length == pass then
pool = string.sub(key, 1,1)
if queue[pool + 1] == nil then
queue[pool + 1] = {}
end
table.insert(queue[pool + 1], key)
table.remove(bucket, n)
end
end
for k,v in pairs(queue) do
for n=1,#v do
table.insert(bucket, v[n])
end
end
if pass == maxstring then
break
end
end
return bucket
end
There's a lot of changes I made to get this working, so hopefully you can look through and pickup on them. I tried to comment as best I could.
function radix_sort(x)
pass, maxstring = 0, 0
-- to avoid overwriting x, copy into bucket like this
-- it also gives the chance to init maxstring
bucket={}
for n=1,#x,1 do
-- since we can, convert all entries to strings for string functions below
bucket[n]=tostring(x[n])
key_length = string.len(bucket[n])
if key_length > maxstring then
maxstring = key_length
end
end
-- not a fan of "while true ... break" when we can set a condition here
while pass <= maxstring do
pass = pass + 1
-- init both queue and all queue entries so ipairs doesn't skip anything below
queue = {}
for n=1,10,1 do
queue[n] = {}
end
-- go through bucket entries in order for an LSD radix sort
for n=1,#bucket,1 do
key_length = string.len(bucket[n])
key = bucket[n]
-- for string.sub, start at end of string (LSD sort) with -pass
if key_length >= pass then
pool = tonumber(string.sub(key, pass*-1, pass*-1))
else
pool = 0
end
-- add to appropriate queue, but no need to remove from bucket, reset it below
table.insert(queue[pool + 1], key)
end
-- empty out the bucket and reset, use ipairs to call queues in order
bucket={}
for k,v in ipairs(queue) do
for n=1,#v do
table.insert(bucket, v[n])
end
end
end
return bucket
end
Here's a test run:
> input={55,2,123,1,42,9999,6,666,999,543,13}
> output=radix_sort(input)
> for k,v in pairs(output) do
> print (k , " = " , v)
> end
1 = 1
2 = 2
3 = 6
4 = 13
5 = 42
6 = 55
7 = 123
8 = 543
9 = 666
10 = 999
11 = 9999
pool = string.sub(key, 1,1)
always looks at the first character; perhaps you meant string.sub(key, pass, 1)

Resources