Reading n number and compare in pascal - pascal

I am going to write a program that asks the user to enter "n" number and then compare number to find 2th largest number i used while:
while i>n do read(number); i:=i+1;
is that true? how to save number and compare them?
for ex if user have 4 number save them like this:
a:=number1;
b:=number2; ...

The algorithm for finding the second largest number from a set (assuming that's what you're after) is relatively simple.
get number into ultimate, on end-of-file exit
get number into penult, on end-of-file exit
if penult is greater than ultimate:
swap ultimate and penult
while true:
get number into num, on end-of-file return penult
if num is greater than ultimate:
set penult to ultimate
set ultimate to num
else:
if num is greater than penult:
set penult to num
In other words, keep a "list" of the top two numbers [ultimate, penult] and slot each coming number into that list if it turns out to belong there.
Once you run out of numbers, the second item of that list is the second highest number from the entire set.
On the off-chance that you don't want duplicates taking up both slots (such as 1,2,1 giving you 1 as the second highest where you really want 2), you can throw away those duplicates if they match:
get number into ultimate, on end-of-file exit
set penult to ultimate
while penult is equal to ultimate:
get number into penult, on end-of-file exit
if penult is greater than ultimate:
swap ultimate and penult
while true:
get number into num, on end-of-file return penult
if num is greater than ultimate:
set penult to ultimate
set ultimate to num
else:
if num is greater than penult and num is not equal to ultimate:
set penult to testnum
Rewriting that in Pascal, I'll leave as an exercise for you, since it may well be classwork.

Related

What is an efficient code for generating n binary digit numbers with k bits set as one?

Is there any efficient code to generate numbers with n digits in their binary representation with exactly r bits set as one?
Also is this a good strategy to generate masks for finding NcR combinations of a set?
I've thought about generating all 2^n numbers and counting their bits but counting bits seems to be O(nlogn).
Well, if we are given a number with K bits set, how can we find the next largest number with K bits set? If we do this repeatedly we can generate all of them.
Generating the next one breaks down to a couple simple rules:
The highest bit that changes must change from 0 to 1. Otherwise the new number would be smaller than the given one.
The highest bit that changes must be the lowest one possible. Otherwise there would be other valid numbers between the current one and the new one. When we change a bit from 0 to 1, we have to change another bit from 1 to 0, and this bit has to be smaller, so the high bit we want to change from 0 to 1 is the lowest 0 bit with a 1 bit in a lower position.
The remaining lower bits must be set to their smallest valid configuration. Otherwise there would again be other valid numbers between the current one and the new one. The smallest valid configuration for the lower bits is the one with all the 1 bits in the lowest positions.
It turns out that there are little binary math tricks that implement all these rules easily. Here it is in python:
N = 6 # length of numbers to generate
K = 4 # number of bits to be set
cur = (1<<K)-1 #smallest number witk K bits set
while cur < (1<<N):
print format(cur,'b')
#when you subtract 1, you turn off the lowest 1 bit
#and set lower bits to 1, so we can get the samallest 1 bit like this:
lowbit = cur&~(cur-1)
#when you add lowbit, you turn it off, along with all the adjacent 1s
#This is one more than the number we have to move into lower positions
ones = cur&~(cur+lowbit)
#cur+lowbit also turns on the first bit after those ones, which
#is the one we want to turn on, so the only thing left after that
#is turning on the ones at the lowest positions
cur = cur+lowbit+(ones/lowbit/2)
You can try it out here: https://ideone.com/ieWaUW
If you want to enumerate NcR combinations using bitmasks, then this is a good way to do it. If you would prefer to have, say, an array of indexes of the chosen items, then it would be better to use a different procedure. You can make 3 rules like the above for incrementing that array too.

Finding duplicate digits in integers

Lets say we have an integer array of N elements which consists of integers between 0 and 10000. We need to detect the numbers including a digit more than once e.g 1245 is valid while 1214 is not. How can we do this optimally? Thanks!
You need two loops. One loop you scan each element of the array.
In the inner loop, you determine if for the given element it's valid or not based on the criteria you indicated. To determine if a number has the same digit more than once, you need a routine that effectively extracts each digit one by one. I think the most optimal way to do that is to do "mod 10" on the number, then loop dividing the original by 10. keep doing that until you don't have number left (zero). Now that you have a routine for looking at each digit of an integer, the way to determine if there are duplicate digits the most optimally is to create an array of 10 booleans. Start with a cleared array. For every digit, use it as an index into the bool array and set it to true. If you see "true" again in that spot before you set it, that means that element in the bool array was visited before, thus it's a duplicate digit. So you break out of the loop altogether and say you found an invalid value.

algorithms an pseudocode first year IT

I am faced with a question that goes like this:
Write pseudocode that allows a user to repeatedly enter positive
integers until an odd number is entered. It would then print the sum
of all numbers entered (excluding the odd number).
Example: given that the user enters 2 24 16 8 7 the program would print 50.
I would like to get some feedback on my algorithm for this problem.
1. Start
2. Declare int number,n,sum=0
3. Do
4. Input number
5. Read number
6. n=number%2
7. If (n==0) then sum+=number
8. while (n==0)
9. If(n==1) then display number and print sum
10. Endif
11. Endwhile
11. Stop
Bugs
You need to move a copy of line 5 (n=number%2) inside of the loop - right now you've got an infinite loop if n == 0 because n is not modified inside of the loop
Possible Bugs
Some languages will return a negative value on the modulo operation if the dividend or divisor is negative, so you may want to take the absolute value of the remainder (n=abs(number%2))
Formatting / Syntax
This is a case where you should use a do while loop - this will let you eliminate lines 3 through 5
Indent the stuff inside the loop
I think you are using do while loop and i made some changes to your algorithm. i think it solves your problem.
1. Start
2. Declare int number,n,sum=0
3. Do
4. Input number
5. Read number
6. n=number%2
7. If (n==0) then sum=sum+number
8. while (n==0)
9. print sum
10.Stop
number+sum should be sum+=numberbecause you need to add the value of the number to the sum, the number+sum isn't assigned anywhere.
You need to add below two inside the loop
6. n=number%2
7. If (n==0) then sum+=number
or else it will be an infinite loop or until some one enters an odd number.

Trying to check if a number is greater than one

I am writing a piece of prolog code and i want to find out if a number is greater than 1.It always return false whenever i query it.
sss(count):- count > 1.
Variables in Prolog begin with an uppercase letter or underscore. That being said,
sss(Count):- Count > 1.

Find if any permutation of a number is within a range

I need to find if any permutation of the number exists within a specified range, i just need to return Yes or No.
For eg : Number = 122, and Range = [200, 250]. The answer would be Yes, as 221 exists within the range.
PS:
For the problem that i have in hand, the number to be searched
will only have two different digits (It will only contain 1 and 2,
Eg : 1112221121).
This is not a homework question. It was asked in an interview.
The approach I suggested was to find all permutations of the given number and check. Or loop through the range and check if we find any permutation of the number.
Checking every permutation is too expensive and unnecessary.
First, you need to look at them as strings, not numbers,
Consider each digit position as a seperate variable.
Consider how the set of possible digits each variable can hold is restricted by the range. Each digit/variable pair will be either (a) always valid (b) always invalid; or (c) its validity is conditionally dependent on specific other variables.
Now model these dependencies and independencies as a graph. As case (c) is rare, it will be easy to search in time proportional to O(10N) = O(N)
Numbers have a great property which I think can help you here:
For a given number a of value KXXXX, where K is given, we can
deduce that K0000 <= a < K9999.
Using this property, we can try to build a permutation which is within the range:
Let's take your example:
Range = [200, 250]
Number = 122
First, we can define that the first number must be 2. We have two 2's so we are good so far.
The second number must be be between 0 and 5. We have two candidate, 1 and 2. Still not bad.
Let's check the first value 1:
Any number would be good here, and we still have an unused 2. We have found our permutation (212) and therefor the answer is Yes.
If we did find a contradiction with the value 1, we need to backtrack and try the value 2 and so on.
If none of the solutions are valid, return No.
This Algorithm can be implemented using backtracking and should be very efficient since you only have 2 values to test on each position.
The complexity of this algorithm is 2^l where l is the number of elements.
You could try to implement some kind of binary search:
If you have 6 ones and 4 twos in your number, then first you have the interval
[1111112222; 2222111111]
If your range does not overlap with this interval, you are finished. Now split this interval in the middle, you get
(1111112222 + 222211111) / 2
Now find the largest number consisting of 1's and 2's of the respective number that is smaller than the split point. (Probably this step could be improved by calculating the split directly in some efficient way based on the 1 and 2 or by interpreting 1 and 2 as 0 and 1 of a binary number. One could also consider taking the geometric mean of the two numbers, as the candidates might then be more evenly distributed between left and right.)
[Edit: I think I've got it: Suppose the bounds have the form pq and pr (i.e. p is a common prefix), then build from q and r a symmetric string s with the 1's at the beginning and the end of the string and the 2's in the middle and take ps as the split point (so from 1111112222 and 1122221111 you would build 111122222211, prefix is p=11).]
If this number is contained in the range, you are finished.
If not, look whether the range is above or below and repeat with [old lower bound;split] or [split;old upper bound].
Suppose the range given to you is: ABC and DEF (each character is a digit).
Algorithm permutationExists(range_start, range_end, range_index, nos1, nos2)
if (nos1>0 AND range_start[range_index] < 1 < range_end[range_index] and
permutationExists(range_start, range_end, range_index+1, nos1-1, nos2))
return true
elif (nos2>0 AND range_start[range_index] < 2 < range_end[range_index] and
permutationExists(range_start, range_end, range_index+1, nos1, nos2-1))
return true
else
return false
I am assuming every single number to be a series of digits. The given number is represented as {numberOf1s, numberOf2s}. I am trying to fit the digits (first 1s and then 2s) within the range, if not the procudure returns a false.
PS: I might be really wrong. I dont know if this sort of thing can work. I haven't given it much thought, really..
UPDATE
I am wrong in the way I express the algorithm. There are a few changes that need to be done in it. Here is a working code (It worked for most of my test cases): http://ideone.com/1aOa4
You really only need to check at most TWO of the possible permutations.
Suppose your input number contains only the digits X and Y, with X<Y. In your example, X=1 and Y=2. I'll ignore all the special cases where you've run out of one digit or the other.
Phase 1: Handle the common prefix.
Let A be the first digit in the lower bound of the range, and let B be the first digit in the upper bound of the range. If A<B, then we are done with Phase 1 and move on to Phase 2.
Otherwise, A=B. If X=A=B, then use X as the first digit of the permutation and repeat Phase 1 on the next digit. If Y=A=B, then use Y as the first digit of the permutation and repeat Phase 1 on the next digit.
If neither X nor Y is equal to A and B, then stop. The answer is No.
Phase 2: Done with the common prefix.
At this point, A<B. If A<X<B, then use X as the first digit of the permutation and fill in the remaining digits however you want. The answer is Yes. (And similarly if A<Y<B.)
Otherwise, check the following four cases. At most two of the cases will require real work.
If A=X, then try using X as the first digit of the permutation, followed by all the Y's, followed by the rest of the X's. In other words, make the rest of the permutation as large as possible. If this permutation is in range, then the answer is Yes. If this permutation is not in range, then no permutation starting with X can succeed.
If B=X, then try using X as the first digit of the permutation, followed by the rest of the X's, followed by all the Y's. In other words, make the rest of the permutation as small as possible. If this permutation is in range, then the answer is Yes. If this permutation is not in range, then no permutation starting with X can succeed.
Similar cases if A=Y or B=Y.
If none of these four cases succeed, then the answer is No. Notice that at most one of the X cases and at most one of the Y cases can match.
In this solution, I've assumed that the input number and the two numbers in the range all contain the same number of digits. With a little extra work, the approach can be extended to cases where the numbers of digits differ.

Resources