Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Ruby: Общие вопросы > задачи из викибука


Автор: aer0sm1th 7.1.2007, 04:44
Вот такие задачки по одномерным массивам:

1. Вывести индексы массива в том порядке, в котором соотвествующие им элементы образуют возрастающую последовательность.
2. В численном массиве найти сумму отрицательных элементов.
3. Найти все индексы, по которым располагается максимальный элемент.
4. В массиве переставить в начало элементы, стоящие на четной позиции, а в конец -- стоящие на нечётной.

Задачу 2 я решил, а проблемы возникли с задачами в которых что-либо зависит от индекса.
Эти задачи в учебнике находятся до асоциативных масивов и конструкций if.
Я полагаю автора имели ввиду решение типа
massiv.xxx{}.yyy{}......

Автор: SoWa 7.1.2007, 05:45
А нельзя ли создать тип данных вида
Код

type elem=record
ind: integer;
c: integer;
end;

Извини, что на Дельфи. Думаю, у вас такое тоже есть.
Так вот создаешь массив из таких элементиков, в поля каждого кладешь соответствующие значения и индексы. Упорядочиваешь массив по значениям. Выводишь индексы. Это первая задача. Остальные- тоже через тип данных решить легко.

Автор: aer0sm1th 7.1.2007, 15:58
Нет. Масив обычный(из чисел).
Я конечно могу его в асоциативный переклепать и т.д. , но я думаю должно быть другое решение.
 smile 

PS: дочитате первый пост до конца.

Автор: Void 8.1.2007, 02:00
Пришло в голову такое, может быть не самое краткое и красивое, но решение:
Код
a = [4, 7, 1, 5, 2]

a.zip((0..a.length).to_a).sort_by { |p| p[0] }.each do |p|
    puts p[1]
end

Автор: SoWa 8.1.2007, 06:22
Вести учет перестановок. Стек заюзать, еще чего нибудь. Решаемо.

Автор: Pete 8.1.2007, 16:32
1.
Код

a = gets.split.map{ |x| x.to_i }
a.each_index{ |i| a[i] = [ i, a[i] ] }
a.sort!{ |x, y| x[1] <=> y[1] }
p a.map{ |x| x[0] }


2.
Код

p gets.split.map{ |x| x.to_i }.inject( 0 ){ |s, x| s + (x < 0 ? x : 0) }


Добавлено @ 16:46 
Void, про zip не знал, спасибо!
1.
Код

a = gets.split.map{ |x| x.to_i }
p a.zip( (0 .. a.size).to_a ).sort{ |x, y| x[0] <=> y[0] }.map{ |x| x[1] }

Автор: Pete 8.1.2007, 16:49
3.
Код

a = gets.split.map{ |x| x.to_i }
b, max = [], a.max
a.each_index{ |i| b << i if a[i] == max }
p b


Добавлено @ 16:55 
4-е аналогично первому.

Автор: aer0sm1th 8.1.2007, 17:06
Спасибо огромное, ситуация проясняется smile
Но остались некоторые вопросы:
что такое zip, b << i ?

Автор: Pete 8.1.2007, 17:38
http://www.ruby-doc.org/core/classes/Array.html#M002250
b << i --- значит, добавить объект (в данном случае --- число) i к массиву b (в конец).

Автор: Rubynovich 8.1.2007, 22:38
1. 
Код

maccuB = [1,2,1,34,5,1,32,45]
p (0...maccuB.size).sort_by{ |index| maccuB[ index ] }

2. 
лучшего решения предложить не могу
3.
Код

maccuB = [1,2,1,34,5,1,32,45]
p maccuB.max.instance_eval{ |max| (0...maccuB.size).find_all{ |index| maccuB[ index ] == max } }

4.
Код

maccuB = [1,2,1,34,5,1,32,45]
p (0...maccuB.size).partition{ |index| (index&1).zero? }.inject( [] ){ |result, arr| result + arr }.map{ |index| maccuB[ index ] }


Добавлено @ 22:50 
4. как более короткий вариант
Код

maccuB = [1,2,1,34,5,1,32,45]
p (0...maccuB.size).partition{ |index| (index&1).zero? }.flatten.map{ |index| maccuB[ index ] }

Автор: aer0sm1th 10.1.2007, 02:43
Все. Теперь все. Всем спасибо. smile 

Автор: pR13S7 10.1.2008, 16:05
2.
Код

puts b.find_all{|el| el0}.inject(0){|res,el| res+el}


3.
Код

puts (0...b.size).to_a.find_all{|el| b[el]==b.max}


4.
Код

puts (0...b.size).partition{|el| (el%2).zero?}.flatten.map{|el| b[el]}



Решить 1 и в одну-две срочки не cмог. Всё упирается в то, что методы index и find_index возвращяют ПЕРВОЕ вхождение элемента. Решение задачи #3, предложеное Rubynovich, выходит за рамки того, что было изложено в викибуке перед тем как предложены вышеуказаные упражнения (хотя там и про index даже ниего не говорилось)

Автор: pR13S7 11.1.2008, 15:03
Решил все задачи по одномерным массивам, выложу тут, авось кому-то пригодиться (сам проверял работает всё коректно)

Код

#### Вывести индексы массива в том порядке, в котором соотвествующие им элементы образуют возрастающую последовательность.
puts (0...b.size).sort_by{|el| b[el]}

######### В численном массиве найти сумму отрицательных элементов.
puts b.find_all{|el| el<0}.inject(0){|res,el| res+el}

######### Найти все индексы, по которым располагается максимальный элемент.
puts (0...b.size).to_a.find_all{|el| b[el]==b.max}

######## В массиве переставить в начало элементы, стоящие на четной позиции, а в конец -- стоящие на нечётной.
puts (0...b.size).partition{|el| (el%2).zero?}.flatten.map{|el| b[el]}

######## Найти все элементы, большие среднего арифметического элементов.
avg = b.inject(0){|res,el| res+el}/b.size.to_f
puts b.find_all{|el| el > avg}

######## К четным элементам прибавить первый элемент, а к нечетным  последний. Первый и последний элемент не изменять.
puts = b.each_index{|el| (el!=0 && el!=b.size-1) ? (((el%2).zero?)? b[el]+=b[0] : b[el]+=b[-1]) : b[el]=b[el] }

######## Заменить все положительные элементы на значение минимального.
puts b.map!{|el| (el>0) ? el=b.min : el=el}

######## Найти произведение всех четных элементов массива.
puts b.each_index{|el| (el%2).zero? }.inject(0){|res,el| res*el }

####### Найти количество минимальных элементов
puts b.inject(0){|res,el| (el == b.min) ? res+1 : res+0}

###### Вывести индексы элементов, меньших своего левого соседа.
puts (0...b.size).find_all{|el| b[el]<b[el-1] }

Автор: pR13S7 22.1.2008, 10:15
Решение задач по двумерным массивам:


Код

###### Поменять первый и последний столбец массива местами.
puts b.transpose.values_at(-1,1...-1,0).transpose

###### Упорядочить N-ый столбец
n = 2
b = b.transpose
b[n] = b[n].sort
b = b.transpose

###### Упорядочить строки, содержащие максимальный элемент
max_el = b.flatten.max
b = b.map{|el| (el.include?(max_el)) ? el.sort : el=el  }


##### Упорядочить строки, если они не отсортированы и перемешать, если они отсортированы
b = b.map{|el| (el==el.sort) ? el.sort_by{rand} : el.sort }

##### Упорядочить строки массива по значению элемента главной диагонали в каждой из строк  
#(в исходном массиве).
b = (0...b.size).sort_by{|el| b[el][el]}.map{|el| b[el]}

##### Найти номера строк, элементы которых упорядочены по возрастанию.
b = (0...b.size).find_all{|el| b[el]==b[el].sort}

##### Найти максимальный элемент для каждого столбца, а затем получить произведение этих элементов.
puts b.transpose.inject(1){|res,el| res*el.max}

##### Найти минимум в двумерном массиве
puts b.map{|el| el.min}.to_a.min #(1й вариант)
puts b.flatten.min # (2й вариант)

##### Найти произведение положительных элементов.
puts b.flatten.inject(1){|res,el| el>0 ? res*el : res=res}

##### Найти сумму положительных элементов, больших К.
k = 3
puts b.flatten.inject(1){|res,el| (el>0 && el>k) ? res*el : res=res}

##### Вычислить сумму и среднее арифметическое элементов главной диагонали
puts (0...b.size).map{|el| b[el][el]}.to_a.inject(0){|res,el| res+el}
puts (0...b.size).map{|el| b[el][el]}.to_a.inject(0){|res,el| res+el}/b.size.to_f

##### Найти номера строк, все элементы которых  нули.
puts (0...b.size).find_all{|el| b[el].inject(0){|res,el| res+el}.zero? }

Автор: 130 24.1.2008, 00:23
Альтернативные решения задач из первого поста (по возможности, с использованием перечислителя).

Код

require 'enumerator'

def n1( array )
  Enumerable::Enumerator.new( array, :each_with_index ).
    sort_by { |v, _| v }.
    map { |_, idx| idx }
end

def n2( array )
  array.select { |v| v < 0 }.inject { |s, v| s + v } || 'No negative elements'
end

def n3( array )
  max = array.max
  Enumerable::Enumerator.new( array, :each_with_index ).
    select { |v, _| v == max }.
    map { |_, idx| idx }
end

def n4( array )
  Enumerable::Enumerator.new( array, :each_with_index ).
    partition { |_, idx| ( idx % 2 ).zero? }.
    inject { |evens, odds| evens + odds }.
    map { |v, _| v }
end

#----------------------------------------------------
def listed( array ); array.join ', '; end

def test( *tested_array )
  fail 'array is empty' if tested_array.empty?

  line = '-' * 40
  tasks = Object.methods.
    find_all { |v| v =~ /^n\d+$/ }.
    sort_by { |v| v.scan( /\d+/ ).first.to_i }.
    map { |name| method name }

  tasks.each do |process|
    puts line, listed( tested_array )
    result = process[tested_array]
    puts result.is_a?( Array ) ? listed( result ) : result
  end
  puts line
end

Автор: pR13S7 24.1.2008, 08:12
130, уважаемый, какие перечисления, автор топа же сказал, что задачи были выложены в разделе, где не то что перечисления, даже операторы условного перехода не были рассказаны ;-)

Автор: 130 24.1.2008, 23:58
pR13S7, действительно, я погорячился. Не удосужился прочитать оригинал (викибук). Но с другой стороны, в первом посте всё же не указано, какими конкретно методами следует решать задачи, а ассоциативные массивы и условные операторы в n1...n4 и не использовались. smile

Автор: 130 25.1.2008, 00:08
дубликат

Автор: YankovskyAndrey 23.10.2008, 15:39
##Задачи про массивы

##Одномерные

array=[1,-2,-6,4,2,8,-6,8,2,-1]

   1. Вывести индексы массива в том порядке, в котором соответствующие им элементы образуют возрастающую последовательность.
p (0..array.size-1).sort_by{|v| array[v]}

   2. В численном массиве найти сумму отрицательных элементов.
p array.find_all{|v| v<0}.inject(0){|v,result| result+v}

   3. Найти все индексы, по которым располагается максимальный элемент.
max=array.max
array.each_index{|x| if array[x]=max then puts "#{x}" end}

   4. В массиве переставить в начало элементы, стоящие на чётной позиции, а в конец — стоящие на нечётной.
even,odd=Array.new,Array.new
array.each_with_index do |element, index|
  ar = index % 2 == 0 ? even : odd
  ar << element
end
p odd+even

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)