Ruby correct code for nested loop for Euler 8 - ruby

Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?
https://projecteuler.net/problem=8
data = '''73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450'''
The code is:
def largest_product_series
mx = 0
arr = data.split("")
arr.map!{ |x| x.to_i}
(arr.size - 13).times do |i|
0.upto(13) do |c|
result = arr.inject() {|sum,c | sum * arr[i + c]}
puts result
if result >= mx
mx = result
end
end
end
#puts "#{mx}"
mx
end
It is actually from Euler project 8 which I am working on. please help me to correct my code and give me some advise, I keep getting a hundred digit output.

A Rubyish way of doing that is as follows.
data = '73167176531330624919225119674426574742355349194934' +
'96983520312774506326239578318016984801869478851843' +
'85861560789112949495459501737958331952853208805511' +
'12540698747158523863050715693290963295227443043557' +
'66896648950445244523161731856403098711121722383113' +
'62229893423380308135336276614282806444486645238749' +
'30358907296290491560440772390713810515859307960866' +
'70172427121883998797908792274921901699720888093776' +
'65727333001053367881220235421809751254540594752243' +
'52584907711670556013604839586446706324415722155397' +
'53697817977846174064955149290862569321978468622482' +
'83972241375657056057490261407972968652414535100474' +
'82166370484403199890008895243450658541227588666881' +
'16427171479924442928230863465674813919123162824586' +
'17866458359124566529476545682848912883142607690042' +
'24219022671055626321111109370544217506941658960408' +
'07198403850962455444362981230987879927244284909188' +
'84580156166097919133875499200524063689912560717606' +
'05886116467109405077541002256983155200055935729725' +
'71636269561882670428252483600823257530420752963450'
def prod(arr)
arr.reduce(1, :*)
end
arr = data.each_char.map(&:to_i).each_cons(13).max_by { |a| prod(a) }
#=> [5, 5, 7, 6, 6, 8, 9, 6, 6, 4, 8, 9, 5]
[arr.join, prod(arr)]
#=> ["5576689664895", 23514624000]
The steps are as follows. Suppose
data = '731671765313326'
(data.size #=> 15). Then
b = data.each_char.map(&:to_i)
#=> [7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 2, 6]
c = b.each_cons(13)
#=> #<Enumerator: [7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 2, 6]:each_cons(13)>
We can see the elements that will be generated by this enumerator by converting it to an array:
c.to_a
#=> [[7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3],
# [3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 2],
# [1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 2, 6]]
arr = c.max_by { |a| prod(a) }
#=> [7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3]
This was obtained by computing:
[prod [7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3],
prod [3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 2],
prod [1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 2, 6]].max
#=> [5_000_940, 1_428_840, 2_857_680].max
#=> 5000940
The last step is to return the array
[arr.join, prod(arr)]
#=> [[7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3].join,
#=> prod([7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3])]
#=> ["7316717653133", 5000940]

Related

What type of sorting algorithm it will be called? [duplicate]

what is the name of this sort? its just like bubble sort but its easy to write but harder in term of complexity.codes are in python language.
def sort(arr):
n = len(arr)
for i in range(n):
for j in range(n):
if arr[i] < arr[j] :
arr[j], arr[i] = arr[i], arr[j]
but bubble sort is like this :
def bubbleSort(arr):
n = len(arr)
# Traverse through all array elements
for i in range(n):
# Last i elements are already in place
for j in range(0, n-i-1):
# traverse the array from 0 to n-i-1
# Swap if the element found is greater
# than the next element
if arr[j] > arr[j+1] :
arr[j], arr[j+1] = arr[j+1], arr[j]
It is neither selection sort nor bubble sort, but an unnecessary bad sort. All of them, your sort, selection sort and bubble sort are of the same complexity, O(n^2).
Your sort sweeps over the array in two loops without consideration for if an element has reached its proper place (as in selection sort) or if an element has gained a place relative to the next (as in bubble sort). The extra code in bubble and selection sort make them far better than yours.
Compare, yourself:
def sort(arr):
print(arr)
n = len(arr)
for i in range(n):
for j in range(n):
if arr[i] < arr[j] :
arr[j], arr[i] = arr[i], arr[j]
print(arr)
def selectionsort(arr):
print(arr)
n = len(arr)
for i in range(n-1):
min_index = i
for j in range(i+1, n):
if arr[j] < arr[min_index]:
min_index = j
arr[i], arr[min_index] = arr[min_index], arr[i]
print(arr)
def bubblesort(arr):
print(arr)
n = len(arr)
for i in range(n):
for j in range(0, n-i-1):
if arr[j] > arr[j+1] :
arr[j], arr[j+1] = arr[j+1], arr[j]
print(arr)
print("sort:")
sort([4,6,3,2,7,1,8,5])
print("selectionsort:")
selectionsort([4,6,3,2,7,1,8,5])
print("bubblesort:")
bubblesort([4,6,3,2,7,1,8,5])
with the results:
sort:
[4, 6, 3, 2, 7, 1, 8, 5]
[6, 4, 3, 2, 7, 1, 8, 5]
[7, 4, 3, 2, 6, 1, 8, 5]
[8, 4, 3, 2, 6, 1, 7, 5]
[4, 8, 3, 2, 6, 1, 7, 5]
[3, 8, 4, 2, 6, 1, 7, 5]
[3, 4, 8, 2, 6, 1, 7, 5]
[2, 4, 8, 3, 6, 1, 7, 5]
[2, 3, 8, 4, 6, 1, 7, 5]
[2, 3, 4, 8, 6, 1, 7, 5]
[2, 3, 4, 6, 8, 1, 7, 5]
[1, 3, 4, 6, 8, 2, 7, 5]
[1, 2, 4, 6, 8, 3, 7, 5]
[1, 2, 3, 6, 8, 4, 7, 5]
[1, 2, 3, 4, 8, 6, 7, 5]
[1, 2, 3, 4, 6, 8, 7, 5]
[1, 2, 3, 4, 6, 7, 8, 5]
[1, 2, 3, 4, 5, 7, 8, 6]
[1, 2, 3, 4, 5, 6, 8, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
selectionsort:
[4, 6, 3, 2, 7, 1, 8, 5]
[1, 6, 3, 2, 7, 4, 8, 5]
[1, 2, 3, 6, 7, 4, 8, 5]
[1, 2, 3, 6, 7, 4, 8, 5]
[1, 2, 3, 4, 7, 6, 8, 5]
[1, 2, 3, 4, 5, 6, 8, 7]
[1, 2, 3, 4, 5, 6, 8, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
bubblesort:
[4, 6, 3, 2, 7, 1, 8, 5]
[4, 3, 6, 2, 7, 1, 8, 5]
[4, 3, 2, 6, 7, 1, 8, 5]
[4, 3, 2, 6, 1, 7, 8, 5]
[4, 3, 2, 6, 1, 7, 5, 8]
[3, 4, 2, 6, 1, 7, 5, 8]
[3, 2, 4, 6, 1, 7, 5, 8]
[3, 2, 4, 1, 6, 7, 5, 8]
[3, 2, 4, 1, 6, 5, 7, 8]
[2, 3, 4, 1, 6, 5, 7, 8]
[2, 3, 1, 4, 6, 5, 7, 8]
[2, 3, 1, 4, 5, 6, 7, 8]
[2, 1, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]
It doesn't make a big difference on small arrays but on large arrays it make a lot of difference (but then there are other methods).

How to find highest char value in ruby?

Suppose I'm given a string "Nas". I want to select the char which has the highest integer value. How can I do this in Ruby?
My implementation involved creating a hash with the numerical value for each char:
alpha = {}
('a'...'z').zip(1. .26).each do |x| alpha[x[0]] = x[1] end
And then I'd loop through my word like so:
word.each_char do |c |
puts c
end
I have defined a method which takes two parameters, the first param is an array which specifies the "importance of a char", and second param takes a word:
def designer_pdf(h, word)
alpha = {}
('a'...'z').zip(1..26).each do |x|
alpha[x[0]] = x[1]
end
word.each_char do |c|
puts c
end
end
designer_pdf (
[1, 3, 1, 3, 1, 4, 1, 3, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
'abc'
)
The goal is two return the highest value from the h array based on the character from word.
For example, word: 'abc':
a = 1
b = 3
c = 1
So return 3 because b is highest.
You can do this
For zep string
p [*'a'..'z'].zip([1, 3, 1, 3, 1, 4, 1, 3, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5])
.select{|x|("zeb".chars).include?x[0]}.max_by{|x|x[1]}
output
["z", 5]
You can pass any priority array and any word as arguments:
def designer_pdf(h, word)
alpha = Hash[('a'..'z').zip(h)]
# if you want only character from word with highest priority
character = word.chars.max_by{|e| alpha[e]}
# if you want only highest char value
value = alpha[character]
# if you want both character and value
[character, value]
end
> designer_pdf([1, 3, 1, 3, 1, 4, 1, 3, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], "abc")
#=> ["b", 3]
> designer_pdf([1, 3, 1, 3, 1, 4, 1, 3, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], "zeb")
#=> ["z", 5]
There is no need to construct a hash.
def largest_mapped_value(word, values)
base = 'a'.ord
values[word.each_char.max_by { |c| values[c.ord-base] }.ord-base]
end
# a b c d e f g h i j k l m n o p q r s t
values = [1, 3, 1, 3, 1, 4, 1, 3, 2, 5, 6, 5, 5, 7, 5, 5, 5, 5, 5, 1,
5, 5, 5, 5, 5, 5]
# u v w x y z
%w| cat kite zebra fined a |.each { |word|
puts "#{word}: #{largest_mapped_value(word, values)}" }
cat: 1
kite: 6
zebra: 5
fined: 7
a: 1
A variant is the following.
word = "fined"
base = 'a'.ord
#=> 97
word.each_char.map { |c| values[c.ord-base] }.max
#=> 7

Infinite loop in blocks in ruby

Why does the following piece of code result in an infinite loop of 3's?
a = [1,2,3,4,5,6,7,8,9,10]
a.each {|value| puts a.insert(value,3)}
The problem is that insert changes the original array:
a = [1,2,3,4,5,6,7,8,9,10]
a.each do |value|
a.insert(value, 3)
p a
end
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # original, ^ marks current value
# ^
# [1, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10] # inserted 3 at position 1
# ^
# [1, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10] # inserted 3 at position 3
# ^
# [1, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10] # inserted 3 at position 2
# ^
# [1, 3, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10] # inserted 3 at position 2
# ^
# [1, 3, 3, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10] # inserted 3 at position 2
# ^
# [1, 3, 3, 3, 3, 3, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10] # inserted 3 at position 2
# ^
# ... # continues forever ...
What you probably want instead is something like this:
a = [1,2,3,4,5,6,7,8,9,10]
a.each_index {|index| p a.dup.insert(index, 3) }
# [3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 3, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 4, 3, 5, 6, 7, 8, 9, 10]
# [1, 2, 3, 4, 5, 3, 6, 7, 8, 9, 10]
# [1, 2, 3, 4, 5, 6, 3, 7, 8, 9, 10]
# [1, 2, 3, 4, 5, 6, 7, 3, 8, 9, 10]
# [1, 2, 3, 4, 5, 6, 7, 8, 3, 9, 10]
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 3, 10]
each_index iterates over the indices, not the values. This is likely the correct thing to do here, because insert takes an index as first argument.
dup duplicates the array on every iteration so a remains unchanged.

how reverse a matrix object in ruby 1.9?

I am a beginner with Ruby. So I searched how reverse a matrix
1, 2, 3, 4 8, 9, 10, 11
4, 5, 6, 7 => 4, 5, 6, 7
8, 9, 10, 11 1, 2, 3, 4
I have tried:
require 'matrix'
m = Matrix[ [1,2,3,4],[4,5,6,7], [8,9,10,11] ]
m_rev = Matrix.build(m.row_size, m.column_size){|row|
m.row_size.downto(0){|i|
row = m.row(i)
}
}
Try: Matrix[*m.to_a.reverse]:
m = Matrix[ [1,2,3,4], [5,6,7,8], [9,10,11,12] ]
#=> Matrix[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
r = Matrix[*m.to_a.reverse]
#=> Matrix[[9, 10, 11, 12], [5, 6, 7, 8], [1, 2, 3, 4]]
Do not miss the *.
You can do something like:
m_rev = Matrix.rows m.to_a.reverse
You were on the right track, except that Matrix.build iterates over both rows and columns:
m_rev = Matrix.build(m.row_size, m.column_size){|row, column|
m[-row-1, column]
}
Simpler and faster:
m_rev = Matrix.rows(m.to_a.reverse)
# or
m_rev = Matrix[*m.to_a.reverse]

recursive removal of elements in array

Given an array of n elements, remove any adjacent pair of elements which are equal. Repeat this operation until there are no more adjacent pairs to remove; that will be the final array.
For e.g 1 2 2 3 4 should return the array 1 3 4.
please note array need not to be sorted.
check this test case also: 1,2,2,3,4,4,3,5 o/p should be 1,5.
(2,2) and (4,4) gets removed, then (3,3) which became adjacent after the removal of (4,4)
Any time you remove a pair of elements, you also need to see if you generated another pair that you want to remove.
The algorithm should follow naturally from that observation.
In Python:
>>> l=[1,2,2,3,4,4,3,5]
>>> [x for x in l if not l.count(x) > 1]
[1, 5]
This removes all integers that occur more than once in the list. This is a correct result for your example but I think that you are really trying to state something different. I think you are saying:
list:=(an unsorted list of integers)
while adjacent_pairs(list) is True:
remove_adjacent_pairs(list)
Once again, in Python:
#!/usr/bin/env python
def dedupe_adjacent(l):
for i in xrange(len(l) - 1, 0, -1):
if l[i] == l[i-1]:
del l[i-1:i+1]
return True
return False
def process_list(l):
print "input list: ",l
i=1
while(dedupe_adjacent(l)):
print " loop ",i,":",l
i+=1
print "processed list=",l
print
process_list([1,2,2,3,4,4,3,5])
process_list([1,2,2,3,4,4,6,3,5])
Output:
input list: [1, 2, 2, 3, 4, 4, 3, 5]
loop 1 : [1, 2, 2, 3, 3, 5]
loop 2 : [1, 2, 2, 5]
loop 3 : [1, 5]
processed list= [1, 5]
input list: [1, 2, 2, 3, 4, 4, 6, 3, 5]
loop 1 : [1, 2, 2, 3, 6, 3, 5]
loop 2 : [1, 3, 6, 3, 5]
processed list= [1, 3, 6, 3, 5]
The following:
function compress(arr) {
var prev, res = [];
for (var i in arr) {
if (i == 0 || (arr[i] != arr[i - 1]))
res.push(arr[i]);
}
return res;
}
compress([1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]);
Returns:
[1, 2, 3, 4, 3, 5, 6, 7, 8]
Also (JavaScript 1.6 solution):
[1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8].filter(function(el, i, arr) {
return i == 0 || (el != arr[i - 1]);
})
Edit: Removing any item that appears in the array more than once requires a different solution:
function dedup(arr) {
var res = [], seen = {};
for (var i in arr)
seen[arr[i]] = seen[arr[i]] ? ++seen[arr[i]] : 1;
for (var j in arr) {
if (seen[arr[j]] == 1)
res.push(arr[j]);
}
return res;
}
The following:
dedup([1, 2, 2, 3, 4, 4, 3, 5]);
Produces:
[1, 5]
I have a solution to this in Java. You need to use replaceAll method in String class in Java. You can use regular expession to remove such adjacent redundant characters:
public class MyString {
public static void main(String[] args) {
String str = "12234435";
while(!str.replaceAll("(\\w)\\1+", "").equalsIgnoreCase(str))
str = str.replaceAll("(\\w)\\1+", "");
System.out.println(str);
}
}
You can find how to give a regular expression here
I would:
Sort the array.
From the start of the array, until you are at the last element of the array do:
`count` = count the number of array[i] elements.
remove the first `count` elements of the array if `count` > 1.
The following Python 3 code will remove duplicates from a list (array). It does this by scanning the array from start towards end and compares the target element with the element one larger. If they are the same they are removed. If the element pointer is not pointing at 0, then it is reduced by 1 in order to catch nested pairs. If the two compared elements are different then the pointer is incremented.
I'm sure there's a more pythonic way to remove two adjacent elements from a list, but I'm new to Python and haven't figured that out yet. Also, you'll want to get rid of the print(indx, SampleArray) statement--I left it in there to let you follow the progress in the output listing below.
# Algorithm to remove duplicates in a semi-sorted list
def CompressArray(SampleArray):
indx=0
while(indx < len(SampleArray)-1):
print(indx, SampleArray)
if(SampleArray[indx]==SampleArray[indx+1]):
del(SampleArray[indx])
del(SampleArray[indx])
if(indx>0):
indx-=1
else:
indx+=1
return SampleArray
Here are sample runs for:
[1, 2, 2, 3, 4]
[1, 2, 2, 3, 4, 4, 3, 5]
[1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
[1, 2, 2, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
[1, 1, 2, 3, 3, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
================================
0 [1, 2, 2, 3, 4]
1 [1, 2, 2, 3, 4]
0 [1, 3, 4]
1 [1, 3, 4]
[1, 3, 4]
================================
0 [1, 2, 2, 3, 4, 4, 3, 5]
1 [1, 2, 2, 3, 4, 4, 3, 5]
0 [1, 3, 4, 4, 3, 5]
1 [1, 3, 4, 4, 3, 5]
2 [1, 3, 4, 4, 3, 5]
1 [1, 3, 3, 5]
0 [1, 5]
[1, 5]
================================
0 [1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 2, 2, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
0 [1, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 3, 3, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
0 [1, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 3, 3, 4, 3, 3, 5, 6, 7, 8, 8]
0 [1, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 4, 3, 3, 5, 6, 7, 8, 8]
2 [1, 4, 3, 3, 5, 6, 7, 8, 8]
1 [1, 4, 5, 6, 7, 8, 8]
2 [1, 4, 5, 6, 7, 8, 8]
3 [1, 4, 5, 6, 7, 8, 8]
4 [1, 4, 5, 6, 7, 8, 8]
5 [1, 4, 5, 6, 7, 8, 8]
[1, 4, 5, 6, 7]
================================
0 [1, 2, 2, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
1 [1, 2, 2, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
0 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
1 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
2 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
3 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
4 [1, 3, 4, 6, 7, 7, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
3 [1, 3, 4, 6, 6, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
2 [1, 3, 4, 4, 3, 8, 8, 5, 9, 10, 10, 9, 11]
1 [1, 3, 3, 8, 8, 5, 9, 10, 10, 9, 11]
0 [1, 8, 8, 5, 9, 10, 10, 9, 11]
1 [1, 8, 8, 5, 9, 10, 10, 9, 11]
0 [1, 5, 9, 10, 10, 9, 11]
1 [1, 5, 9, 10, 10, 9, 11]
2 [1, 5, 9, 10, 10, 9, 11]
3 [1, 5, 9, 10, 10, 9, 11]
2 [1, 5, 9, 9, 11]
1 [1, 5, 11]
[1, 5, 11]
================================
0 [1, 1, 2, 3, 3, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
0 [2, 3, 3, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
1 [2, 3, 3, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
0 [2, 2, 4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
0 [4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
1 [4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
2 [4, 5, 6, 6, 5, 7, 8, 8, 7, 4, 9]
1 [4, 5, 5, 7, 8, 8, 7, 4, 9]
0 [4, 7, 8, 8, 7, 4, 9]
1 [4, 7, 8, 8, 7, 4, 9]
2 [4, 7, 8, 8, 7, 4, 9]
1 [4, 7, 7, 4, 9]
0 [4, 4, 9]
[9]
================================
I love Java, but functional solutions should get more time on this site.
In Haskell, doing things the way the question asks:
compress lst = if (length lst == length b) then lst else (compress b) where
b = helper lst
helper [] = []
helper [x] = [x]
helper (x:y:xs) = if (x == y) then (helper xs) else (x:helper (y:xs))
You can solve this problem in O(n) time, although it is a bit more complicated
compress' lst = reverse (helper [] lst) where
helper xs [] = xs
helper [] (x:xs) = helper [x] xs
helper (a:as) (x:xs)
| a == x = helper as xs
| otherwise = helper (x:a:as) xs
I think we could use a stack to check adjacent duplicated elements.
Scan the array. For each new element, if it is equal to the top element in the stack, drop it and pop the top element from the stack. Otherwise, push it into the stack.
Here is the stack based algorithm based upon the edited question.
// pseudo code, not tested
void RemoveDupp(vector<int> & vin, vector<int> & vout)
{
int i = 0, int j = -1;
vout.resize(vin.size());
while (i < vin.size())
{
if (j == -1 || vout[j] != vin[i])
vout[++j] = vin[i++]; //push
else
j--, i++; //pop
}
vout.resize(j + 1);
}

Resources