Why do system objects like nil, true or false have a fixed object id in Ruby. Also I tried printing out the object ids of numbers, they are the same and follow an odd number sequence pattern. Any explanation for this?
[nil,true,false].each { |o| print o.object_id, ' '}
4 2 0 => [nil, true, false]
>> (0..50).each { |i| print i.object_id, ' ' }
1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99 101 => 0..50
The following two links explain the concept behind Ruby's object IDs:
http://www.oreillynet.com/ruby/blog/2006/01/the_ruby_value_1.html
http://www.oreillynet.com/ruby/blog/2006/02/ruby_values_and_object_ids.html
The object ID is calculated from the objects value plus some additional information. From that calculation you can derive the values you are seeing in your examples.
Related
I was trying to assist with a (deleted) question, here at SO, about how to define an Hive external table over data generated by teragen.
According to the teragen code's comments, each 100 bytes of data (=row) should end with \r \n, however, It seems that it ends with 4 characters with hex values of cc dd ee ff
The full demo is down below.
Any thoughts?
Thanks
/** * Generate the official terasort input data set. * The user
specifies the number of rows and the output directory and this *
class runs a map/reduce program to generate the data. * The format of
the data is: * * (10 bytes key) (10 bytes rowid) (78 bytes
filler) \r \n * The keys are random characters from the set ' '
.. '~'. * The rowid is the right justified row id as a int. *
The filler consists of 7 runs of 10 characters from 'A' to 'Z'. *
* *
https://github.com/facebookarchive/hadoop-20/blob/master/src/examples/org/apache/hadoop/examples/terasort/TeraGen.java
Using teragen to generate 7 records
hadoop jar /usr/jars/hadoop-examples.jar teragen 7 /user/hive/warehouse/teragen
As expected, we get files with total data volume of 700 bytes
hdfs dfs -ls /user/hive/warehouse/teragen
Found 3 items
-rw-r--r-- 1 cloudera supergroup 0 2017-03-03 22:38 /user/hive/warehouse/teragen/_SUCCESS
-rw-r--r-- 1 cloudera supergroup 400 2017-03-03 22:38 /user/hive/warehouse/teragen/part-m-00000
-rw-r--r-- 1 cloudera supergroup 300 2017-03-03 22:38 /user/hive/warehouse/teragen/part-m-00001
Moving the files to local directory and checking the HEX values.
hdfs dfs -get /user/hive/warehouse/teragen/part-m-00001
od -v -Anone -w20 -tx1
At this point I was expecting to see 0a 0d (\r\n) as the last 2 characters of each 100 bytes, but instead I see ee ff.
There are no newline at the end of the "rows".
5c 90 ab 38 ae 52 89 62 15 d7 00 11 30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
30 30 30 34 88 99 aa bb 41 41 41 41 42 42 42 42 42 42 42 42
32 32 32 32 34 34 34 34 34 34 34 34 39 39 39 39 35 35 35 35
42 42 42 42 31 31 31 31 38 38 38 38 44 44 44 44 cc dd ee ff <--
72 dc 0c a5 1e 33 3f 32 4b 7a 00 11 30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
30 30 30 35 88 99 aa bb 38 38 38 38 33 33 33 33 42 42 42 42
38 38 38 38 38 38 38 38 34 34 34 34 37 37 37 37 32 32 32 32
37 37 37 37 39 39 39 39 30 30 30 30 32 32 32 32 cc dd ee ff <--
10 43 1a f6 a0 d8 47 b8 c5 5f 00 11 30 30 30 30 30 30 30 30
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30
30 30 30 36 88 99 aa bb 39 39 39 39 37 37 37 37 34 34 34 34
41 41 41 41 37 37 37 37 45 45 45 45 44 44 44 44 41 41 41 41
41 41 41 41 39 39 39 39 38 38 38 38 42 42 42 42 cc dd ee ff <--
I'm not sure that the output of your terasort is relative to that TeraGen which you are referencing in your link. If you open the terasort content from some other source you'll be able to see:
Generate the official GraySort input data set. The user specifies the number of rows and the output directory and this class runs a map/reduce program to generate the data. The format of the data is:
(10 bytes key) (constant 2 bytes) (32 bytes rowid) (constant 4 bytes) (48 bytes filler) (constant 4 bytes)
The rowid is the right justified row id as a hex number.
Following this description I compare it with your first link:
5c 90 ab 38 ae 52 89 62 15 d7 - 10 bytes key
00 11 - constant 2 bytes
30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 34 - 32 bytes rowid
88 99 aa bb - constant 4 bytes
41 41 41 41 42 42 42 42 42 42 42 42 32 32 32 32 34 34 34 34 34 34 34 34 39 39 39 39 35 35 35 35 42 42 42 42 31 31 31 31 38 38 38 38 44 44 44 44 - 8 bytes filler
cc dd ee ff - constant 4 bytes
So it is not the newline but just a constant 4 bytes produced by generator for every record.
In the GNU make file, need to have run_options30=Pkts=30. but it's not working.
list = 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
$(foreach var, $(list),$(eval run_options$(var)=Pkts=$(var) ) )
I am trying to solve the Projecteuler #11 but I am running into an error when I'm trying to create a function to calculate the multiplication of every 4 numbers in a column. I am getting an error:
Project11.rb:59:in `sumvertical': undefined method `[]' for nil:NilClass (NoMeth
odError)
I feel like there is something I am easily overlooking here. I appreciate the help!
#project #11 http://projecteuler.net/problem=11
grid="08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48"
grid=grid.split()
grid=grid.collect {|s| s.to_i}
multiarray=[]
i = 0
e = 19
until e > 400
multiarray << grid[i..e]
i+= 20
e+= 20
end
def sumhorizontal(x) #checks sum of all horizontal 4 elements
sum = 0
x.each {|a|
i=0
e=3
while e < a.length
if a[i..e].inject(:*) > sum
sum = a[i..e].inject(:*)
i += 1
e += 1
else
i += 1
e += 1
end
end
}
return sum
end
def sumvertical(x)
sum = 0
i=0
e=0
while e < x.length #Will break once the end point is longer than the length of an array
until i > 20 #Checks the first column
if x[i][e]*x[i+1][e]*x[i+2][e]*x[i+3][e] > sum #Error is here
sum = x[i][e]*x[i+1][e]*x[i+2][e]*x[i+3][e]
i += 1
else
i += 1
end
end
e += 1 #once you are out of the until statement, it increases e by 1 to check the next column
i = 0 #resets i so it can go back to the zero
end
return sum
end
print sumvertical(multiarray)
The grid has 20 rows. Your loop is actually trying to reach all the way to a 24rd row; that's because it goes through 21 iterations (i starts at 0, and goes until it equals 21), and each iteration reaches 3 beyond the current value of i (when you call x[i+3]). When i is 17, your code will break, because x[i+3][e] is trying to index into the 21st row of x. i+3 is 20, but the highest available index is 19. So what happens is, x[20] returns nil, and then the [] method is called on nil, which generates your error.
Also, the standard library has a transpose method that you can call on your array. If you use it, you just need one method (sumhorizontal). You can get the column sums with sumhorizontal(multiarray.transpose).
One more thing... it looks like you're coming from a procedural language. Ruby has an extensive standard library and coding constructs that can save you a lot of time and keystrokes. There is typically no need to iterate with while loops and index variables in Ruby. sumhorizontal, for instance, can be written like this (it should really be called producthorizontal, though if you're trying to solve Project Euler #11:
def sumhorizontal(x)
x.map { |r| r.each_slice(4).map { |s| s.reduce(:*) }.max }.max
end
Good luck with the rest of your Ruby learning journey!
I have a hard time converting this string into an array holding each line as an element.
string =
"03 54 56 34 34
34 54 56 43 34 56
43 56 67 34 34"
I tried string_array= [string.split(/$/)]. However, string_array then only holds one element (the whole string). What am I missing?
Side note: The individual numbers in the string are seperated by one whitespace, however, each end of a line does not contain a whitespace.
You could also use method lines:
string.lines.to_a # => ["03 54 56 34 34\n", "34 54 56 43 34 56\n", "43 56 67 34 34"]
And, you could also use chomp would like to have the new line characters removed:
string.lines.map(&:chomp) # => ["03 54 56 34 34", "34 54 56 43 34 56", "43 56 67 34 34"]
string_array = string.split(/\n/) should do the job.
I'm reviewing for an exam, one of the practice questions is as follows:
give the contents of the array after two iterations of the bubble sort (assume the lowest values are selected first to the left of the array
43 16 99 12 48 14 62
The given answer is:
12 14 43 16 99 48 62
I have been reviewing my notes trying to figure out why this is the correct answer, but I have no idea why. I have found examples of the bubble sort on google and wikipedia and while those make sense to me, they are also very simple, this is more difficult.
Can someone please explain how 12 14 43 16 99 48 62 is the answer?
I puzzled about this for a minute because indeed, it was hard to see, but once you realize how they're doing it, it's simple enough. Still, it's dumb.
We're sorting so that the lowest numbers are on the left, but we're iterating from the right. So the very first test is comparing 14 and 62, and not swapping; then comparing 48 and 14, and swapping; then 12 and 14, and doing nothing, etc. Once you get to the left end, go back to the right end and do a second pass, and you'll end up with the given solution.
Ok, this does not give the same answer as your teacher, but this is (I hope) a clear explanation of a bubble sort:
Because a picture is often a lot better than words: http://www.algolist.net/Algorithms/Sorting/Bubble_sort
In your case, after the first iteration:
43 > 16 => 16 43 99 12 48 14 62
43 < 99 => 16 43 99 12 48 14 62
99 > 12 => 16 43 12 99 48 14 62
99 > 48 => 16 43 12 48 99 14 62
99 > 14 => 16 43 12 48 14 99 62
99 > 62 => 16 43 12 48 14 62 99
Second Iteration:
16 < 43 => 16 43 12 48 14 62 99
43 > 12 => 16 12 43 48 14 62 99
43 < 48 => 16 12 43 48 14 62 99
48 > 14 => 16 12 43 14 48 62 99
48 < 62 => 16 12 43 14 48 62 99
62 < 99 => 16 12 43 14 48 62 99