Infinite loop in blocks in ruby - 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.

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).

Linux script using a Hardware (True) Random number generator

I'd like to use the built in hardware random number generator in my RPI3 for a project. Currently I'm only able to use /dev/hwrng to save binary dumps with
dd if=/dev/hwrng of=data.bin bs=25 count=1
What I need for my project is to read 200 bit long data chunks from the random source (/dev/hwrng) with a frequency of 1 reading/second and count the 1's in it and write the result as decimal into a text file with a timestamp, like this:
datetime, value
11/20/2018 12:48:09, 105
11/20/2018 12:48:10, 103
11/20/2018 12:48:11, 97
The decimal number should be always close to 100, since it is a random data source and the expected number of 1's and 0's should be the same.
Any help is appreciated....
I did come up wit a perl script that is close to what I wan't, so let me share it. I'm sure it could be done in a much cleaner way though...
#!/usr/bin/perl
use strict;
use warnings;
use DateTime;
my #bitcounts = (
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3,
3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,
3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2,
2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5,
5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3,
2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4,
4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4,
4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6,
5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5,
5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
);
for (my $i=0; $i <= 10; $i++) {
system("dd if=/dev/hwrng of=temprnd.bin bs=25 count=1 status=none");
my $filename = 'temprnd.bin';
open(my $fh, '<', $filename) or die "$!";
binmode $fh;
my $count = 0;
my $byte = 0;
while ( read $fh, $byte, 1 ) {
$count += $bitcounts[ord($byte)];
}
my $dt = DateTime->now;
print join ',', $dt->ymd, $dt->hms,"$count\n";
system("rm temprnd.bin");
sleep 1;
}
__END__
Try running the following code
for ((n=0; n<200; ++n)); do echo $(date '+%m/%d/%Y %H:%M:%S'), $(od -vAn -N1 -tu1 < /dev/hwrng); sleep 1; done
If you want to save it to a file, add simple redirect in the end
> somefile
Updating on the new request, try running the following code
for ((n=0; n<10; ++n)); do
count=0
for ((s=0; s<200; ++s)); do
if (( $(od -vAn -N1 -tu1 < /dev/hwrng) > 127 )); then ((++count)); fi
done
echo $(date '+%m/%d/%Y %H:%M:%S'), $count
sleep 1
done

How to duplicate value of array in ruby

I have two arrays of integers, e.g.
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [7, 8, 9]
I would like to repeatedly duplicate the value of 'b' to get a perfectly matching array lengths like this:
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [7, 8, 9, 7, 8, 9, 7, 8, 9, 7]
We can assume that a.length > b.length
Assuming you mean
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [7, 8, 9]
then you can do:
b.cycle.take(a.length) #=> [7, 8, 9, 7, 8, 9, 7, 8, 9, 7]
<script src="//repl.it/embed/JJ3x/2.js"></script>
See Array#cycle and Enumerable#take for more details.
I would have used Array#cycle had it been available, but since it was taken I thought I'd suggest some alternatives (the first being my fav).
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = [7, 8, 9]
[*b*(a.size/b.size), *b[0, a.size % b.size]]
#=> [7, 8, 9, 7, 8, 9, 7, 8, 9, 7]
Array.new(a.size) { |i| b[i % b.size] }
#=> [7, 8, 9, 7, 8, 9, 7, 8, 9, 7]
b.values_at(*(0..a.size-1).map { |i| i % b.size })
#=> [7, 8, 9, 7, 8, 9, 7, 8, 9, 7]

Ruby correct code for nested loop for Euler 8

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]

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