2009-11-23 2 views
1

Мне нужно создать один массив чисел внутри одного диапазона, например:Распределить диапазон в массиве

[1..5] в 10 раз = [1,1,2,2,3,3,4, 4,5,5]

[1..5] в 5 раз = [1,2,3,4,5]

[1..5] в 3 раза = [1,3, 5]

def distribute(start_value, end_value, times, is_integer) 
    array = Array.new(times-1) 

    min_value = [end_value,start_value].min 
    max_value = [end_value,start_value].max 

    if max_value-min_value<times 
     factor = (max_value-min_value).abs/(array.size).to_f 
    else 
     factor = (max_value-min_value).abs/(array.size-1).to_f 
    end 

    for i in 0..array.size 
     v = [ [max_value, factor*(i+1)].min, min_value].max 
     is_integer ? array[i] = v.round : array[i] = v 
    end 

    start_value < end_value ? array : array.reverse 
    end 

распределения (1, 5, 10, правда) => [1, 1, 1, 2, 2, 3, 3, 4, 4, 4 ] #WRONG должно быть [1,1,2,2,3,3,4,4,5,5]

Распределить (5, 1, 5, true) => [5, 4, 3, 2, 1] #OK

распределить (1, 5, 3, правда) => [4, 5, 5] #WRONG должно быть [1, 3, 5]

ответ

0

только немного коррекции ... когда ARRAY_SIZE находится 0

def distribute(start_value, end_value, array_size, want_ints) 
    diff = 1.0 * (end_value - start_value) 
    n = [array_size-1, 1].max 

    (0..(array_size-1)).map { |i| 
     v = start_value + i * diff/n 
     want_ints ? v.round : v 
    }  
    end 
+1

Вместо того, чтобы усложнять алгоритм для специального случая, вы можете закоротить метод: 'return [], если array_size> 0'. По крайней мере, для меня это легче понять. – FMc

5

Как насчет это:

def distribute(min,max,items) 
    min,max = [min,max].sort 
    (0...items).map {|i| (min + i * (max - min)/(items-1.0)).round} 
end 

Или, если вам действительно нужно флаг INT/Float:

def distribute(min,max,items,ints) 
    min,max = [min,max].sort 
    a = (0...items).map {|i| min + i * (max - min)/(items-1.0)} 
    ints ? a.map {|i| i.round} : a 
end 

И если вам действительно это нужно идти в обратном направлении, если параметры приведены к вам задом:

def distribute(min,max,items,ints) 
    usemin,usemax = [min,max].sort 
    diff = usemax - usemin 
    a = (0...items).map {|i| usemin + i * diff/(items-1.0)} 
    a.map! {|i| i.round} if ints 
    min != usemin ? a.reverse : a 
end 
+0

И очевидно, вы можете оставить min, max = part, если знаете, что получаете параметры в правильном порядке ... –

+0

Возможно, я не понимаю проблему, но этот ответ кажется неправильным для второго OP use case: 'распределять (5, 1, 5, true) => [5, 4, 3, 2, 1]'. – FMc

+0

Правда. Я просто добавил еще один вариант в этом случае. –

Смежные вопросы