2014-11-21 8 views
-1

我有以下的數組:陣列從先前的元件扣除1以上重複一次時

輸入:

array = [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200] 

輸出繼電器:

array = [211, 200, 199, 198, 197, 196 ... ] 

我試圖each_with_index但couldn」得到期望的結果。

+1

的算法是不明確的 - 什麼期待?一個從零開始的數組,然後從211開始遞減的連續數字? – 2014-11-21 18:19:58

+0

就是這樣,我刪除了零,可能會讓人困惑。 – neo 2014-11-21 18:21:14

+1

所以你想要一個從211開始降序的數字列表?它與重複項有什麼關係? – 2014-11-21 18:22:12

回答

2

我不明白nil s要做什麼,所以我沒有解決這個問題。根據要求,讓arrarrayarray.sort.reverse。我認爲這是你想要做的? (見我對這個問題發表評論。)

def change_em(arr) 
    dup_indices = arr.each_index 
        .group_by { |i| arr[i] } 
        .values 
        .flat_map { |a| a.drop(1) } 
    puts "dup_indices = #{dup_indices}" 
    last = 0 # anything '-' responds to 
    arr.each_index.map { |i| last = dup_indices.include?(i) ? last-1 : arr[i] } 
end 

我已經包括了puts只是爲了澄清我在這裏做什麼。

change_em [10, 8, 5, 5, 7] 
    #=> dup_indices = [3] 
    #=> [10, 8, 5, 4, 7] 
change_em [10, 8, 7, 5, 5] 
    #=> dup_indices = [4] 
    #=> [10, 8, 7, 5, 4] 
change_em [10, 9, 9, 8, 8, 8] 
    #=> dup_indices = [2, 4, 5] 
    #=> [10, 9, 8, 8, 7, 6] 
change_em [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 196] 
    #=> dup_indices = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 
    #=> [211, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 196] 

注意,聲明

last = dup_indices.include?(i) ? last-1 : arr[i] 

double-duty:它更新的last值,並返回該指數i映射值。還請注意,dup_indices不能包含0

0

寫道這是一個更實用的風格。

def f(arr, dup_element = nil, dup_count = 0) 
    return generate_dup_array(dup_element, dup_count) if arr.empty? 
    if arr.head != arr.tail.head # Not duplicates 
    if dup_count == 0 # No duplicates to insert 
     [arr.head] + f(arr.tail) 
    else # There are duplicates to insert 
     generate_dup_array(dup_element, dup_count) + f(arr.tail) 
    end 
    else # Duplicate found, continue with tail of array and increase dup_count 
    f(arr.tail, arr.head, dup_count + 1) 
    end 
end 

def generate_dup_array(dup_element, dup_count) 
    return [] if dup_count == 0 
    (dup_element - dup_count..dup_element).to_a.reverse 
end 

class Array 
    def head; self.first; end 
    def tail; self[1..-1]; end 
end 

p f [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200] 
# => [211, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190] 

p f [10, 8, 5, 5, 7].sort.reverse 
# => [10, 8, 7, 5, 4] 

p f [9, 6, 6, 5, 5, 4, 4, 3, 3, 3, 2, 2, 1] 
# => [9, 6, 5, 5, 4, 4, 3, 3, 2, 1, 2, 1, 1] 
0

不知道我完全理解你的要求,但這裏是我的嘗試:

# Transforms an array of numbers into a sorted array of the same length, where 
# each successive element is always smaller than the preceding element. 
def force_descending(array) 
    array.sort.reverse.each_with_object([]) do |element, collection| 
    collection << if collection.empty? || element < collection.last 
     element 
    else 
    collection.last-1 
    end 
    end 
end 

樣品輸入/輸出:

force_descending [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200] 
#=> [211, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190] 

force_descending [10, 8, 5, 5, 7] 
#=> [10, 8, 7, 5, 4] 

force_descending [211, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 196] 
#=> [211, 200, 199, 198, 197, 196, 195, 194, 193, 192, 191, 190, 189] 
0

它已經在decsending爲了

對於單班人羣:

results = numbers.chunk {|num| num}.flat_map {|num, group| (group.length == 1) ? num : ((num - (group.length-1))..num).to_a.reverse} 

對於明智的程序員:

numbers = [211, 200, 200, 200] 
start_of_dups = "_START_" #Something not in the array 
dup_count = 0 

results = numbers.map do |num| 
    if start_of_dups == num 
    dup_count += 1 
    num - dup_count 
    else 
    dup_count = 0 
    start_of_dups = num 
    end 
end 

p results 

--output:-- 
[211, 200, 199, 198] 

但如果:

array = [10, 10, 10, 9] 

--output:-- 
[10, 9, 8, 9]