Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
With below array:
[68, 205, 286, 347, 482]
I want to generate something like:
[0, 68, 68, 205, 205, 286, 286, 347, 347, 482]
What is the best way to accomplish this in Ruby?
If I am guessing right you want to iterate the array with two neighboring elements at a time. There's each_cons for that:
a = [68, 205, 286, 347, 482]
a.each_cons(2) do |x, y|
p [x, y]
end
# [68, 205]
# [205, 286]
# [286, 347]
# [347, 482]
Are you in fact looking to work through an Array of paired values, to work with ranges of values implied by "joining the dots" of the array? This is not how you have phrased the question, but is an implied property of your output:
([0]+a).each_cons(2).to_a
=> [[0, 68], [68, 205], [205, 286], [286, 347], [347, 482]]
You would then work through the start and end points like this:
([0]+a).each_cons(2) do |x,y|
# x is 0, y is 68 for first iteration
# So you could have (x...y) as a Range for example
end
Or if you really do have your example output as the desired end result, just flatten it:
([0]+a).each_cons(2).to_a.flatten
=> [0, 68, 68, 205, 205, 286, 286, 347, 347, 482]
As said by other, the logic is not really clear. I would write something like this:
array = [68, 205, 286, 347, 482]
first, *middle, last = [0], *array
p first + middle.flat_map{|x|[x,x]} << last
# => [0, 68, 68, 205, 205, 286, 286, 347, 347, 482]
a = [68, 205, 286, 347, 482]
a = a.zip(a.dup).unshift(0).flatten
a.pop
puts a
# => [0, 68, 68, 205, 205, 286, 286, 347, 347, 482]
Related
Write a program that will store the numbers from a list called random_number which are less than or equal to 300 into a new list. Print the results.
random_numbers = [100, 34, 10, 17, 111, 304, 99, 87, 55, 0, 5, 303, 399, 354, 121, 208, 267, 406, 13]
My attempt
rand_count=0
for rand_value in random_numbers:
if rand_value <=300:
print (rand_value) rand_count+=1
else:
random_numbers.append(rand_value)
in Ruby I have a string like this:
myString = "mystring"
I want to convert the string to a byte array taking only the first 16 bytes and pad with 0's if shorter.
I can do this the brute force way. But...
Care to share a 'cool' way?
Something like this? You should probably check for edge cases like multibyte chars.
"my string"[0..15].ljust(16,'0')
You can get the string as a byte array by calling bytes on it, then once you have it as a byte array, you can take the first 16 elements. Finally, you pad the array by filling it with a range as the second argument:
def padded_byte_array(string, length = 16)
bytes = string.bytes.take(length)
bytes.fill(0, bytes.length...length)
end
and then you can call it:
padded_byte_array('my string')
# => [109, 121, 32, 115, 116, 114, 105, 110, 103, 0, 0, 0, 0, 0, 0, 0]
padded_byte_array('some super long string longer than 16 bytes')
# => [115, 111, 109, 101, 32, 115, 117, 112, 101, 114, 32, 108, 111, 110, 103, 32]
padded_byte_array('本当に長いマルチバイト文字列')
# => [230, 156, 172, 229, 189, 147, 227, 129, 171, 233, 149, 183, 227, 129, 132, 227]
I assume that if arr.size < str.size, where str is the string and arr is the array to be returned, str.bytes is returned. If, in that case, str.bytes[0, [str.size, arr.size].min] is to be returned, that requires an obvious adjustment.
def padded_bytes(str, arr_size)
str_bytes = str.bytes
Array.new([arr_size, str.size].max) { |i| str_bytes.fetch(i, 0) }
end
padded_bytes("tiger", 8)
#=> [116, 105, 103, 101, 114, 0, 0, 0]
padded_bytes("tiger", 3)
#=> [116, 105, 103, 101, 114]
Thanks folks for your answers.
In the end, I implemented
ba = name[0..15].ljust(16, "\0").bytes.to_a
Aza gave the closest to what I asked.
My original looked like this:
ba = name[0..15].bytes.to_a
while ba.length < 16 do ba.push(0) end
Until I got your answers. Thanks again!
Here is a list of values in an array:
[463, 246, 216, 194, 154, 152, 147, 140, 129, 128, 123, 118, 118, 102, 102, 101, 97, 96, 93, 85]
How can I ensure/assert through RSpec that the array list is in ascending order?
The simplest way is probably:
expect(array.sort).to eq(array)
"Ascending" means "the next element is not smaller than the current". You can encode that into a predicate easily:
expect(array.each_cons(2).all? {|a, b| a <= b }).to be_truthy
Note that Array#sort is not stable, so something like
expect(array.sort).to eq(array)
does not work!
This question already has an answer here:
replacing an element in nested array ruby
(1 answer)
Closed 7 years ago.
Hello I have my following bingo code that marks X for numbers that get returned:
class BingoBoard
def initialize(board)
#bingo_board = board
end
def number_letter
#letter = ['B','I','N','G','O'].sample
#number = rand(1..100)
end
def checker
number_letter
#bingo_board.map! do |n|
if n.include?(#number) #cleaned up code from the initial solution.
n.map! { |x| x == #number ? 'X' : x}
else
n
end
end
end
end
My question is how do I change my code so that when I'm using the test code:
board = [[47, 44, 71, 8, 88],
[22, 69, 75, 65, 73],
[83, 85, 97, 89, 57],
[25, 31, 96, 68, 51],
[75, 70, 54, 80, 83]]
new_game = BingoBoard.new(board)
new_game.checker
It will appear neatly like a bingo board in irb.
Right now it looks like:
=>[[47, 44, 71, 8, 88], [22, 69, 75, 65, 73], ["X", 85, 97, 89, 57], [25, 31, 96, 68, 51], [75, 70, 54, 80, "X"]]
Append .map { |block| puts block.inspect } to the new_game.checker call.
I am attempting to write a function which takes a large number as input (upwards of 800 digits long) and returns a simple formula of no complex math as a string.
By simple math, I mean just numbers with +,-,*,/,^ and () as needed.
'4^25+2^32' = giveMeMath(1125904201809920); // example
Any language would do. I can refactor it, just looking for some help with the logic.
Bonus. The shorter the output the better. Processing time is important. Also, mathematical accuracy is a must.
Update:
to clarify, all input values will be positive integers (no decimals)
I think the entire problem can be recast to a run-length encoding problem on the binary representation of the long integer.
For example, take the following number:
17976931348623159077293051907890247336179769789423065727343008115773
26758055009631327084773224075360211201138798713933576587897688144166
22492847430639474110969959963482268385702277221395399966640087262359
69162804527670696057843280792693630866652907025992282065272811175389
6392184596904358265409895975218053120L
This looks fairly horrendous. In binary, though:
>>> bin(_)
'0b11111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111111111111111111111111111111111
11111111111111111111111111111111111111100000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000
0000000'
Which is about 500 ones, followed by 500 zeroes. This suggests an expression like:
2**1024 - 2**512
Which is how I obtained the large number in the first place.
If there are no significantly long runs in the binary representation of the integer, this won't work well at all. 101010101010101010.... is the worst case.
Here is my attempt in Python:
def give_me_math(n):
if n % 2 == 1:
n = n - 1 # we need to make every odd number even, and add back one later
odd = 1
else:
odd = 0
exps = []
while n > 0:
c = 0
num = 0
while num <= n/2:
c += 1
num = 2**c
exps.append(c)
n = n - num
return (exps, odd)
Results:
>>> give_me_math(100)
([6, 5, 2], 0) #2**6 + 2**5 + 2**2 + 0 = 100
>>> give_me_math(99)
([6, 5, 1], 1) #2**6 + 2**5 + 2**1 + 1 = 99
>>> give_me_math(103)
([6, 5, 2, 1], 1) #2**6 + 2**5 + 2**2 + 2**1 + 1 = 103
I believe the results are accurate, but I am not sure about your other criteria.
Edit:
Result: Calculates in about a second.
>>> give_me_math(10**100 + 3435)
([332, 329, 326, 323, 320, 319, 317, 315, 314, 312, 309, 306, 304, 303, 300, 298, 295, 294, 289, 288, 286, 285, 284, 283, 282, 279, 278, 277, 275, 273, 272, 267, 265, 264, 261, 258, 257, 256, 255, 250, 247, 246, 242, 239, 238, 235, 234, 233, 227, 225, 224, 223, 222, 221, 220, 217, 216, 215, 211, 209, 207, 206, 203, 202, 201, 198, 191, 187, 186, 185, 181, 176, 172, 171, 169, 166, 165, 164, 163, 162, 159, 157, 155, 153, 151, 149, 148, 145, 142, 137, 136, 131, 127, 125, 123, 117, 115, 114, 113, 111, 107, 106, 105, 104, 100, 11, 10, 8, 6, 5, 3, 1], 1)
800 digit works fast too:
>>> give_me_math(10**800 + 3452)
But the output is too long to post here, which is OPs concern of course.
Time complexity here is 0(ln(n)), so it is pretty efficient.
In java, you should take a look at the BigDecimal class in java.math package.
I'd suggest you to have a look at
The GMP library (The GNU Multiple Precision Arithmetic Library) for performing the arithmetics
Take a look at integer factorization. The link redirects to Wikipedia which should give probably a good overview. However to be a bit more scientific:
Integer factorization (PDF) by Daniel Bernstein of the University of Illinois
Integer Factorization Algorithms (PDF) by Connelly Barnes of the Department of Physics, Oregon State University