PostScript - Comparing values for equality + "if" structure - if-statement

I have previously defined
/smth1 [0 1 0] def
/smth2 [-1 0 0] def
I need to check if they are equal, and if they are, perform some action...
For example, (Equal!) show.
I know that I should use eq and, possibly, something like
... {(Equal!) show} if
But I can't figure out how to correctly compare the previously defined smth1 and smth2.
Please advise.

You don't want to compare the arrays, you want to compare the contents of the arrays. Arrays and other compound objects can be tested for equality in PostScript, but that doesn't test their contents, only whether they are the same object.
Eg:
%!
/Array1 [0 0 0] def
/Array2 [0 0 0] def
/Pointer Array1 def
Array1 Array2 eq
{
(Array1 equals Array2\n) print
}
{
(Array1 does not equal Array2\n) print
}
ifelse
Array1 Pointer eq
{
(Array1 equals Pointer\n) print
}
{
(Array1 does not equal Pointer\n) print
}
ifelse
If you run that, you will see that Array1 and Array2 are not equal, but that Array1 and Pointer are. That's because Pointer is (loosely) a pointer to Array1. In fact, the way PostScript works, both are references to the same object. Whereas Array1 and Array2 are references to different objects, even though their contents are the same.
So in your case, you want to retrieve each element of the array, and compare it against the same element in another array. If they are not equal, abort, otherwise, carry on.
Useful operators we will use: length, for, eq, get, dup, exch, if, ifelse
The examples below are not intended to be a working solution but should give you ways to deal with this problem:
Example 1, check the lengths
%!
%% First let us define two arrays of differing lengths
userdict begin %% We'll define these in user dict
/Array1 [0 0 0] def
/Array2 [0 1] def
% So when testing compound objects for equality, we should first
% start by checking the lengths (sizes) of the two objects
Array1 length % Put array1 on the stack then call the 'length' operator
% stack now contains the length of Array1
Array2 length % Put array2 on the stack then call the 'length' operator
% stack now contains the lengths of Array1 and Array2
eq % The eq operator tests the two objects on the stack to
% see if they are equal and returns a boolean
% stack now contains a boolean
% So now we declare some executable arrays, each executable array
% can be thought of as an inline function. We define one for each possible
% value; true or false
{
(Array1 and Array2 are equal!\n) print
}
{
(Array1 and Array2 are not equal!\n) print
}
% The ifelse operator consumes two executable arrays, and a boolean, from
% the operand stack. If the boolean is true it executes the first
% array, otherwise it executes the second.
ifelse
Example 2, now check the contents
%!
%% First let us define two arrays with the same contents
userdict begin %% We'll define these in user dict
/Array1 [0 0 0] def
/Array2 [0 0 0] def
Array1 length Array2 length eq
{
% The 'for' operator consumes 4 operands, the initial value of the loop counter,
% the amount to increment the counter by on each pass, and the terminating
% value of the counter, finally the executable array to execute on each pass.
% So, starting at loop count = 0, incrementing by 1 each time, and stopping
% when the counter is the length of the array. Note! Because we start at 0
% The counter is the array length - 1.
0 1 Array1 length 1 sub
{
%% Now on each pass the top element on the stack is the loop counter
%% We're going to need that twice, once for each array. So we start by
%% taking a copy and putting it on the stack
dup
%% The stack now contains: <loop count> <loop count>
%% Now get the n'th element from the first array:
get
%% The stack now contains: <loop count> <array1 element 'n'>
%% We want to use the loop counter to index the second array, but its not
%% on top of the stack, so swap the top two elements:
exch
%% Stack now contains: <array1 element 'n'> <loop count>
%% Now use the counter to get the n'th element from the second array
get
%% stack now contains: <array1 element n><array 2 element n>
%% check for equality
eq not
{
(Arrays are not equal!\n) print
} if
}
for
}{
(Arrays are not equal in length\n) print
} ifelse
Now there are some obvious corollaries here; arrays are just containers, there is nothing to prevent an array containing another array, or a dictionary, or a string.....
To deal with this, it would be better to define a number of functions to test equality, and call them as required, potentially recursively.
The function above doesn't return anything to indicate success or failure (except output on the back channel). Clearly a boolean result is required. The easiest way to do that is to stick a 'true' on the stack, if the equality fails, pop the true and replace it with a false.
The function doesn't terminate when it finds an inequality, the exit operator could be used to do that (you'll probably want to implement the boolean above first though)
Finally, the function is inefficient, since it constantly copies the same objects out of the current dictionary. Its possible to rewrite the function to do all the operations on the stack, which would be quicker.
Caveat: I haven't actually tested the PostScript programs here, typos are entirely possible :-)

Related

Recursion on a list involving arithmetic operations and counting elements?

I'm struggling to really grasp the understanding of Prolog lists and recursive calls. I've been working on a program to keep track of how many items are greater than the head of the list and then recursively call this relation to check greater than the next element and so on. I've gotten my program working to the point where it can count the number of elements greater than the head but once it reaches the end and tries to recursively call the relation on the next element it fails. From the research I've done here's what I have and how I think it's supposed to work:
Input - List = [7,2,4,3,6,9,8,10,12,5].
testHead(List).
testHead([H|T]) :-
greaterThan(H,T,0),
teastHead(T).
^My understanding is this relation takes the head element from the list and calls greaterThan using the head and the rest of the list. After the greaterThan finishes, it should recursively call testHead(T) to test the next element and so on.
greaterThan(H,[X|T],C) :-
H > X ->
C2 is C+1,
greaterThan(H,T,C2);
greaterThan(H,T,C).
^My understand here is the greaterThan reads in the head element, the rest of the list, and a variable for counting. If the head is greater than the next element, increase the count and recursively call greaterThan with the Tail and new count; else recursively call greaterThan without incrementing count.
My expected output would be C2 = 12. (7 is greater than 5 elements, 2 is greater than 0 elements, 4 is greater than 1 element, and so on)
The actual output currently is 5; then false.
My program seems to be correctly evaluating and incrementing for the head element but when it finishes greaterThan for that element the program returns false. I've tried researching and understanding lists and recursive calls in prolog but I've been hitting a wall. I'm not sure if it fails because you can't recursively run the increment relation or if there's some other issue with my list relation. Any clarification on how to tackle this issue and how prolog functions here would be helpful.
Lets start with your first code snippet:
testHead(List).
testHead([H|T]) :-
greaterThan(H,T,0),
teastHead(T).
You got the idea of recursion but I see four problems.
First: there is only one attribute for testHead, which means (besides true and false) you get nothing back. So it should look more like this: testHead([H|T], L) ....
Second: you need to know when to stop. This is normally the first line of a predicate. Yours states: anything matches. But it should say something like: if there is no element left, I can "return" an empty list. testHead([],[]).
Third: You call greaterThan(H,T,0) with the fixed value 0, which means you want to test if the "output" value is zero. Which is not the case, you want to count stuff. So put a variable here: N
Fourth: If you have calculated a value N you have to forward it to the outputlist. Since you will get the list Nlist from your recursive call, you can create a new list with N as the head element and Nlist as the tail and "return" this new list.
Conclusion:
testHead([],[]).
testHead([H|T],[N|Nlist]) :-
greaterThan(H,T,N),
testHead(T,Nlist).
Sadly we can not test it yet, we have to have a look at greaterThan/3.
Your snippet is the following:
greaterThan(H,[X|T],C) :-
H > X ->
C2 is C+1,
greaterThan(H,T,C2);
greaterThan(H,T,C).
And also here are some parts odd.
First: You need to tell when to stop. Usually you stop with the empty list [] or if the list has only one element left [A]. If you are not interested in the content of A you use a "throw away variable" which starts with an underscore _. This results in: greaterThan(_,[],0). Which means: if my list is empty, there are 0 numbers greater in my list, no matter what the refence value was. Also since the order of rules matters you put this on top of your recursion rule.
Second: You got the cases right, so if H is larger than the head X of the list do something, otherwise "ignore" X by just calling the same predicate without X. The problem appears in the something part: since the value of C2 is unificated before C you need to calculate C depending on C2 and not vice versa. C is C2+1 means: I know the value C2 from the recursion call and since H>X I want to add one to its value and "return" it.
Third: You know the value of C2 just after asking greaterThan(H,T,C2), so put the C is C2+1 after it.
Ok, now we got:
greaterThan(_,[],0).
greaterThan(H,[X|T],C) :-
H > X ->
greaterThan(H,T,C2),
C is C2+1;
greaterThan(H,T,C).
testHead([],[]).
testHead([H|T],[N|Nlist]) :-
greaterThan(H,T,N),
testHead(T,Nlist).
Lets test it!
?- testHead( [7,2,4,3,6,9,8,10,12,5],L).
L = [5, 0, 1, 0, 1, 2, 1, 1, 1, 0] ;
false.
Looks good besides that you don't want a list but a total number. Ok, here you go:
testHead([],0).
testHead([H|T],New) :-
greaterThan(H,T,N),
testHead(T,NN),
New is NN+N.
?- testHead( [7,2,4,3,6,9,8,10,12,5],N).
N = 12 ;
false.
Explanation: if your input list is empty, there is nothing to be done, "return" the neutral element for addition: 0.
If your inputlist has a head element H, calculate the "greater as N remaining elements" through greaterThan(H,T,N). Assume your code works so you can call testHead(T,NN) for your tail list T and get the sum value NN. If both values N and NN are known, add them and state it as the "return".

Is this code a bubble sorting program?

I made a simple bubble sorting program, the code works but I do not know if its correct.
What I understand about the bubble sorting algorithm is that it checks an element and the other element beside it.
#include <iostream>
#include <array>
using namespace std;
int main()
{
int a, b, c, d, e, smaller = 0,bigger = 0;
cin >> a >> b >> c >> d >> e;
int test1[5] = { a,b,c,d,e };
for (int test2 = 0; test2 != 5; ++test2)
{
for (int cntr1 = 0, cntr2 = 1; cntr2 != 5; ++cntr1,++cntr2)
{
if (test1[cntr1] > test1[cntr2]) /*if first is bigger than second*/{
bigger = test1[cntr1];
smaller = test1[cntr2];
test1[cntr1] = smaller;
test1[cntr2] = bigger;
}
}
}
for (auto test69 : test1)
{
cout << test69 << endl;
}
system("pause");
}
It is a bubblesort implementation. It just is a very basic one.
Two improvements:
the outerloop iteration may be one shorter each time since you're guaranteed that the last element of the previous iteration will be the largest.
when no swap is done during an iteration, you're finished. (which is part of the definition of bubblesort in wikipedia)
Some comments:
use better variable names (test2?)
use the size of the container or the range, don't hardcode 5.
using std::swap() to swap variables leads to simpler code.
Here is a more generic example using (random access) iterators with my suggested improvements and comments and here with the improvement proposed by Yves Daoust (iterate up to last swap) with debug-prints
The correctness of your algorithm can be explained as follows.
In the first pass (inner loop), the comparison T[i] > T[i+1] with a possible swap makes sure that the largest of T[i], T[i+1] is on the right. Repeating for all pairs from left to right makes sure that in the end T[N-1] holds the largest element. (The fact that the array is only modified by swaps ensures that no element is lost or duplicated.)
In the second pass, by the same reasoning, the largest of the N-1 first elements goes to T[N-2], and it stays there because T[N-1] is larger.
More generally, in the Kth pass, the largest of the N-K+1 first element goes to T[N-K], stays there, and the next elements are left unchanged (because they are already increasing).
Thus, after N passes, all elements are in place.
This hints a simple optimization: all elements following the last swap in a pass are in place (otherwise the swap wouldn't be the last). So you can record the position of the last swap and perform the next pass up to that location only.
Though this change doesn't seem to improve a lot, it can reduce the number of passes. Indeed by this procedure, the number of passes equals the largest displacement, i.e. the number of steps an element has to take to get to its proper place (elements too much on the right only move one position at a time).
In some configurations, this number can be small. For instance, sorting an already sorted array takes a single pass, and sorting an array with all elements swapped in pairs takes two. This is an improvement from O(N²) to O(N) !
Yes. Your code works just like Bubble Sort.
Input: 3 5 1 8 2
Output after each iteration:
3 1 5 2 8
1 3 2 5 8
1 2 3 5 8
1 2 3 5 8
1 2 3 5 8
1 2 3 5 8
Actually, in the inner loop, we don't need to go till the end of the array from the second iteration onwards because the heaviest element of the previous iteration is already at the last. But that doesn't better the time complexity much. So, you are good to go..
Small Informal Proof:
The idea behind your sorting algorithm is that you go though the array of values (left to right). Let's call it a pass. During the pass pairs of values are checked and swapped to be in correct order (higher right).
During first pass the maximum value will be reached. When reached, the max will be higher then value next to it, so they will be swapped. This means that max will become part of next pair in the pass. This repeats until pass is completed and max moves to the right end of the array.
During second pass the same is true for the second highest value in the array. Only difference is it will not be swapped with the max at the end. Now two most right values are correctly set.
In every next pass one value will be sorted out to the right.
There are N values and N passes. This means that after N passes all N values will be sorted like:
{kth largest, (k-1)th largest,...... 2nd largest, largest}
No it isn't. It is worse. There is no point whatsoever in the variable cntr1. You should be using test1 here, and you should be referring to one of the many canonical implementations of bubblesort rather than trying to make it up for yourself.

Varying initializer in a 'for loop' in C++

int i = 0;
for(; i<size-1; i++) {
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
Here I started with the fist position of array. What if after the loop I need to execute the for loop again where the for loop starts with the next position of array.
Like for first for loop starts from: Array[0]
Second iteration: Array[1]
Third iteration: Array[2]
Example:
For array: 1 2 3 4 5
for i=0: 2 1 3 4 5, 2 3 1 4 5, 2 3 4 1 5, 2 3 4 5 1
for i=1: 1 3 2 4 5, 1 3 4 2 5, 1 3 4 5 2 so on.
You can nest loops inside each other, including the ability for the inner loop to access the iterator value of the outer loop. Thus:
for(int start = 0; start < size-1; start++) {
for(int i = start; i < size-1; i++) {
// Inner code on 'i'
}
}
Would repeat your loop with an increasing start value, thus repeating with a higher initial value for i until you're gone through your list.
Suppose you have a routine to generate all possible permutations of the array elements for a given length n. Suppose the routine, after processing all n! permutations, leaves the n items of the array in their initial order.
Question: how can we build a routine to make all possible permutations of an array with (n+1) elements?
Answer:
Generate all permutations of the initial n elements, each time process the whole array; this way we have processed all n! permutations with the same last item.
Now, swap the (n+1)-st item with one of those n and repeat permuting n elements – we get another n! permutations with a new last item.
The n elements are left in their previous order, so put that last item back into its initial place and choose another one to put at the end of an array. Reiterate permuting n items.
And so on.
Remember, after each call the routine leaves the n-items array in its initial order. To retain this property at n+1 we need to make sure the same element gets finally placed at the end of an array after the (n+1)-st iteration of n! permutations.
This is how you can do that:
void ProcessAllPermutations(int arr[], int arrLen, int permLen)
{
if(permLen == 1)
ProcessThePermutation(arr, arrLen); // print the permutation
else
{
int lastpos = permLen - 1; // last item position for swaps
for(int pos = lastpos; pos >= 0; pos--) // pos of item to swap with the last
{
swap(arr[pos], arr[lastpos]); // put the chosen item at the end
ProcessAllPermutations(arr, arrLen, permLen - 1);
swap(arr[pos], arr[lastpos]); // put the chosen item back at pos
}
}
}
and here is an example of the routine running: https://ideone.com/sXp35O
Note, however, that this approach is highly ineffective:
It may work in a reasonable time for very small input size only. The number of permutations is a factorial function of the array length, and it grows faster than exponentially, which makes really BIG number of tests.
The routine has no short return. Even if the first or second permutation is the correct result, the routine will perform all the rest of n! unnecessary tests, too. Of course one can add a return path to break iteration, but that would make the code somewhat ugly. And it would bring no significant gain, because the routine will have to make n!/2 test on average.
Each generated permutation appears deep in the last level of the recursion. Testing for a correct result requires making a call to ProcessThePermutation from within ProcessAllPermutations, so it is difficult to replace the callee with some other function. The caller function must be modified each time you need another method of testing / procesing / whatever. Or one would have to provide a pointer to a processing function (a 'callback') and push it down through all the recursion, down to the place where the call will happen. This might be done indirectly by a virtual function in some context object, so it would look quite nice – but the overhead of passing additional data down the recursive calls can not be avoided.
The routine has yet another interesting property: it does not rely on the data values. Elements of the array are never compared. This may sometimes be an advantage: the routine can permute any kind of objects, even if they are not comparable. On the other hand it can not detect duplicates, so in case of equal items it will make repeated results. In a degenerate case of all n equal items the result will be n! equal sequences.
So if you ask how to generate all permutations to detect a sorted one, I must answer: DON'T.
Do learn effective sorting algorithms instead.

find a single element in an array of consecutive duplicate elements

Given an array of elements where every element is repeated except a single element. Moreover all the repeated elements are consecutive to each other.
We need to find out the index of that single element.
Note:
array may not be sorted
expected time O(logn)
range of elements can
be anything.
O(n) is trivial. but how can I figure out logn?
Gave a thought to bitwise operators also but nothing worked out.
Also, I am unable to make use of this statement in this question all the repeated elements are consecutive to each other.
Ex: 2 2 3 3 9 9 1 1 5 6 6
output 5
It can be done in O(logn) by checking if arr[2k] == arr[2k+1], k>=0 - if it is, then the distinct elementt is AFTER 2k+1, if it's not - than it is before before 2k+1.
This allows you to effectively trim half of the array at each step by checking the middle value, and recursing only on a problem half as big, getting it O(logn) overall.
Python code:
def findUnique(arr,l,r):
if r-l < 2:
return (arr[l],l)
mid = (r-l)/2 + l
if mid % 2 != 0:
flag = -1
else:
flag = 0
if (mid == 0 or arr[mid-1] != arr[mid] ) and (mid == len(arr)-1 or arr[mid] != arr[mid+1] ):
return (arr[mid],mid)
if arr[mid+flag] == arr[mid+1+flag]:
return findUnique(arr,mid,r)
return findUnique(arr,l,mid)
Assuming each element is repeated exactly twice, except one, then it is easy.
The first answer is correct, just feel like I could elaborate a bit on it.
So, lets take your example array.
a = [2 2 3 3 9 9 1 1 5 6 6];
If all elements were paired, then you can take an even index and know for sure that the next element will be the same.
a[0] = 2;
a[1] = 2; //as well
a[2] = 3;
a[3] = 3; //as well
General case:
a[k] = a[k+1] = x;
where k is even, and x is some value.
BUT, in your case, we know that there is one index that doesn't follow this rule.
in order to find it, we can use Binary Search (just for reference), with a bit of extra computation in the middle.
We go somewhere in the middle, and grab an element with an even index.
If that elements' value equals to the next elements' value, then your lonely value is in the second part of the array, because the pairing wasn't broken yet.
If those values are not equal, then either your lonely value is in the first half OR you are at it (it is in the middle).
You will need to check couple elements before and after to make sure.
By cutting your array in half with each iteration, you will achieve O(logn) time.

checking whether a particular element exists or not in a c++ STL vector

I wanted to check whether an element exist at a particular vector location, say i, before accessing it like v[i]. Could you let me know how can I do that?
Thank you.
if (0 <= i && i < v.size()) {
// OK
std::cout << v[i]; // Example
} else {
// Wrong
}
An element is guaranteed to exist at every position i where i >= 0 and i < v.size() as vectors are contiguous sequences of elements and "holes" are not possible.
Use v.size().
If you want to know if an element exists in a vector, the quickest method is to sort the array then use a search method such as binary search.
If this action is performed many times, perhaps changing the data structure will yield better performance. An std::map is good for this, and if your compiler has one, use a hash table or map.
Otherwise the only way to determine if a value exists in an vector without accessing the vector is to use a second data structure to remember the value and position.
I understand you have a std::vector preallocated at a specific dimension, let's say n, and you want to see if the element at index i (i < n) was initialized or is just allocated.
Like #Thomas Matthews said, you can use a second data structure, a simple bool[n], in which, at index k, you store true if the element at index k in your vector exists and false otherwise.
0 1 2 3 4 5
v = [ * * * * ]
0 1 2 3 4 5
exists = [ true, false, true, false, true, true ]