I'm having a hard time understanding how to solve this problem without causing memory allocation problems. I'm pretty sure my logic is sound but unfortunately that doesn't seem to be good enough. Does anyone have any recommendations for this so I can understand how to write the code more efficiently?
Here's the problem:
Sample Input:
1
5 2 1
Sample Output
2
There are N = 5 prisoners and M = 2 sweets. Distribution starts at ID number S = 1, so prisoner 1 gets the first sweet and prisoner 2 gets the second (last) sweet. Thus, we must warn prisoner about the poison, so we print 2 on a new line.
# Enter your code here. Read input from STDIN. Print output to STDOUT
n = gets.strip.to_i
n.times do
arr = gets.strip.split(" ").map { |s| s.to_i}
prisoners = arr[0].to_i
sweets = arr[1].to_i
position = arr[2].to_i
prisoners_array = (1..prisoners).map { |p| p.to_i}
starting_position = prisoners_array[position - 1]
end_position = prisoners_array.size
awesome_array = (starting_position..end_position).map { |p| p.to_i}
awesomer_array = (prisoners_array[0]...starting_position).map { |p| p.to_i}
awesomest_array = awesome_array + awesomer_array
warning = 0
if sweets > prisoners
sweets = sweets % prisoners
end
for i in awesomest_array
warning += 1
if warning === sweets
puts prisoners_array[i - 1]
end
end
end
This appears to be the exercise in question. The key here is managing your use of modulo (which calculates a 0-indexed position) with the problem (which uses 1-indexed positions).
In the example case, we have 5 people (n) and want to iterate 2 positions (m) over them starting from person #1 (s). Person #1 is index position 0 which we calculate by subtracting one from s. We must also subtract one from the distance travelled t because getting to the starting position is considered the first move. So we have s+m-2.
By taking this resultant number, modulo % the total number of people, we will have calculated the 0-indexed position that we end up at. We'll need to add one back to this number to convert back to a 1-indexed system.
While it's okay to take a long-form approach to working exercise problems out (such as by populating arrays and actually iterating over them), this problem can also be solved as follows:
# Enter your code here. Read input from STDIN. Print output to STDOUT
gets.strip.to_i.times do
# n - number of prisoners
# m - number of sweets
# s - starting id
n, m, s = gets.split.map &:to_i
puts ((m+s-2) % n) + 1
end
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int t;
cin>>t;
for(int q=0;q<t;q++)
{
long long int n,m,s;
cin>>n>>m>>s;
while(s!=m)
{
if(s==n)s=0;
s++;
}
cout<<s;
//exit(0);
}
return 0;
}
Related
This question deals with how the statements and those involving recursion are executed, and in what order Ruby will handle the,. Specifically, as I've been learning online, I have found that Ruby does not follow Last in first out convention in a stack form of memory-management, but rather has a garbage collector. I have numbered questions at the bottom after all the code. I hope I have made everything clear, but please let me know what parts of the question may need improvement. Thank you.
def append(array, n)
return array if n < 0 #base case, how we end this thing
array << n*2 #Line No. 1
append(array, n - 1) #Line No. 2
array << n*2 #Line No. 3
end
append( [], 3)
#output [6,4,2,0,0,2,4,6]
The two lines below give the output of [6,4,2,0]
array << n*2 #Line No. 1
append(array, n - 1) #Line No. 2
When the order of the two statements are reversed the output is [0,2,4,6]
append(array, n - 1) #Line No. 2
array << n*2 #Line No. 3
In the original append method (top section of code), why does ruby stop to compute at the first recursive call, continue on to line 3, and then do the second recursive call, then concatenate the output of both recursions?
If line 2 and line 3 were the only part of the recursion the output would be[0,2,4,6], in ascending order. What is the convention that Ruby uses in its execution? Why does this code not give the output [6,4,2,0], since the n-1 is being called before array << n*2?
Is there a proper definition or programming theory as to how these recursive calls are handled?
Ruby is doing nothing unusual here, any more than any other "typical" computer language.
In the original append method (top section of code), why does ruby stop to compute at the first recursive call, continue on to line 3, and then do the second recursive call, then concatenate the output of both recursions?
I don't see any evidence for this. The first half of the output 6,4,2,0 is from Line 1. The second half 0,2,4,6 is from Line 3. Note that the first time it falls through to Line 3 is when n==0. So the next value after 6,4,2,0 is 0, then 2, 4, and finally 6. It pops out of the call stack, LIFO, just like any other computer language.
If line 2 and line 3 were the only part of the recursion the output would be[0,2,4,6], in ascending order. What is the convention that Ruby uses in its execution? Why does this code not give the output [6,4,2,0], since the n-1 is being called before array << n*2?
Because it has to call append 4 times before it returns to fall through to Line 3. By this time, n=0 which is why 0 is still first in this case.
Is there a proper definition or programming theory as to how these recursive calls are handled?
It's just LIFO. Give it some more thought.
If you're still not convinced, here is C++ code that prints the exact same sequence:
#include <iostream>
#include <list>
using namespace std;
list<int>& append( list<int> &array, int n )
{
if( n < 0 ) return array;
array.push_back(n*2);
append( array, n-1 );
array.push_back(n*2);
return array;
}
int main()
{
list<int> array;
append( array, 3 );
for( int& x : array ) cout << x << ' ';
cout << endl;
}
I came across this problem where you were given a number N as Input and then N numbers followed (where 3<=N<=2500). These N numbers were part of an Arithmetic Progression (of size N+1) from which one number was removed. So the task was to find that Missing number. For instance
5
1 3 5 9 11
The output is 7
I came up with two methods, the 2nd one passing all the test cases but the first one failing in certain (hidden) cases.
First I will explain the second method
METHOD II
Let diff=(last_number-first_number)/N
//Considering 0 based indexing
for i=0 to (N-2)
if( array[i+1] is not equal to (array[i]+diff))
print (array[i]+diff)
break
This method passed all the test cases. Now the first method which I implemented and which failed certain test cases was as follows
METHOD I
//Considering 0 based indexing
for i=1 to (N-2)
if (2*array[i] is not equal to (array[i-1]+array[i+1])) then
if( (array[i]-array[i-1])< (array[i+1]-array[i]))
print 2*array[i]-array[i-1]
else
print 2*array[i]-array[i+1]
break
Can anyone explain what is wrong with METHOD I?? Which cases am I missing.
Thanks.
Method 1 does not work when the numbers are in decreasing order.
For 7 5 1 output should be 3 but the algorithm will give 9.
Method 2 works in this case because the difference is correctly calculated as negative and the algorithm proceeds accordingly.
Though not answer of your original question but if you need it a better solution with O(logN) complexity for the finding the missing number(if there is only one). Use binary search .
make following comparision for binary search
if(a[mid] != mid*(difference)+a[0]) {
missing_num = mid*(difference) + a[0];
search lower half
}
else search higher half
This is my solution in Ruby:
number_of_terms = gets.chomp.to_i
Get number of terms from STDIN
progression = gets.chomp.split(' ').map(&:to_i)
Get the string, remove any leading and trailing white space, split it at the spaces between the numbers and then convert each item into an integer.
expected_sum = (number_of_terms+1)/2.0*(progression.first+progression.last)
Using formula for the summation of an arithmetic progression: n/2 ( a[0] + a[n] ).
Here dividing by 2.0 is important. Need to keep precision.
actual_sum = progression.inject(:+)
Checking what was the sum of the given numbers.
missing_element = (expected_sum - actual_sum).to_i
Difference is of course the missing element. Also converting into an integer to remove trailing .0
i.e. 4.0 => 4
puts "Missing element is: #{missing_element}"
Works for
1) Any value of N (given 5 in example)
2) Any Difference between terms (given 2 in example)
3) Difference can be + as well as - (example: 11 5 2 -1 -4)
int diff[]= new int[length-1];
for(int i = 0; i<length-1;i++){
diff[i] = n1[i+1]-n1[i];
System.out.println(diff[i]);
if(i!=0){
if(diff[i]<diff[i-1]){
if(diff[i]<0)
System.out.println(n1[i]+diff[i-1]);
else
System.out.println(n1[i-1]+diff[i]);
break;
}
if(diff[i]>diff[i-1]){
if(diff[i]<0)
System.out.println(n1[i-1]+diff[i]);
else
System.out.println(n1[i]+diff[i-1]);
break;
}
}
}
n1 is where you store the number array from String.
Length is how many numbers you are providing.
This is optimized so that if you miss number in between first two numbers then it only loops 3 times no matter how many numbers you have given
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int findDelta(long *x, int n);
int main(){
int n;
fscanf(stdin,"%d",&n);
long *x= (long*) calloc(n,sizeof(long));
long k;
for(int i=0;i<n;i++){
scanf("%ld",&k);
x[i]=k;
}
int delta=findDelta(x,n);
for(int i=0;i<n-1;i++){
if (x[i+1]-x[i] != delta)
printf("%ld\n",x[i]+delta);
}
free(x);
return 0;
}
int findDelta(long *x, int n){
long delta1,delta2;
delta1=x[1]-x[0];
int d1Count=0;
int d2Count=0;
for(int i=1;i<n-1;i++){
delta2=x[i+1]-x[i];
if(delta2==delta1)
d1Count++;
else
d2Count++;
}
if (d1Count > d2Count)
return (delta1);
else
return (delta2);
}
What is the best approach to find the total number of numbers between two given numbers whose binary representation is palindrome?
The problem I am trying to solve is here on spoj
http://www.spoj.com/problems/BINPALI/
I solved the spoj problem and code as below:
#include<iostream>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<string>
using namespace std;
int main()
{
int a,b,t;
cin>>t;
while(t--)
{
cin>>a>>b;
int total=0;
string s="";
while(a<=b)
{
s="";
for(int i=a;i>0;i=i/2)
{
if(i%2)
s+='1';
else
s+='0';
}
string s2="",s3="";
s2=s.substr(0,s.length()/2);
int k=s.length();
if(k%2)
s3=s.substr(s.length()/2+1,s.length());
else
s3=s.substr(s.length()/2,s.length());
reverse(s2.begin(),s2.end());
if(s2==s3)
{
cout<<a<<" ";
total++;
}
a++;
}
if(!total)
cout<<"none"<<endl;
}
return 0;
}
One possible approach is:
Take the binary representation of the 1st number M.
Find the 1st number greater than M that is palindrome in binary representation:
- For M, keep the left half of bits, the same value, and match the right half of the binary string with the left half.
For example if M is 10110111, the number shall be 10111101
If the resultant number is < M, then increment the left substring by 1 and then match the right substring.
Eg. if M is 10000011, the number shall be 10000001 < M , hence number shall be 10011001.
To find subsequent numbers, increment bits from the middle towards the end.
10011001
10100101
10111101
11000011
The time limit is very strict on this problem. Even an optimized palindrome generator will probably not work. You likely have to use the formula at OEIS for this given integer sequence.
There is an inversion formula as well. It's given as follows.
Inversion formula: If b>0 is any binary palindrome, then the index n for which a(n)=b is
n=palindromicIndexOf(b)=(((5-(-1)^m)/2) + sum_{k=1...floor(m/2)} (floor(b/2^k) mod 2)/2^k))*2^floor(m/2), where m=floor(log_2(b)).
You probably have to take the two given indexes and find the lowest n and highest n from the sequence somehow. Then print out all nth numbers from the sequence within the range (lowest n, highest n). Each query for the nth binary palindromic number is O(1) time so each test case should take O(log(B - A)) time. This is very very low but you need to get the formula working. :)
Good luck implementing the generator formula for this sequence. I tried it and could not get it to work. :( It's quite complicated.
But anyways for reference, I tried using an optimized palindrome generator in Python 2.7.5 and it gave me Time Limit Exceeded. Here is the code if you're interested.
from itertools import product, repeat
from bisect import insort, bisect
def all_binary_sequences_of_length_(n):
return [''.join(seq) for seq in product('01', repeat=n)]
def main():
binary_palindromes = [0, 1, 3, 5, 7]
for n in xrange(1, 15):
A = all_binary_sequences_of_length_(n)
for a in A:
b = a[::-1]
# Add palindromes of length 2n + 2
insort(binary_palindromes, int((a+b).join('11'), 2))
# Add palindromes of length 2n + 3
insort(binary_palindromes, int((a+'0'+b).join('11'), 2))
insort(binary_palindromes, int((a+'1'+b).join('11'), 2))
t = int(raw_input())
for _ in repeat(0, t):
a, b = map(int, raw_input().split())
start = bisect(binary_palindromes, a - 1)
end = bisect(binary_palindromes, b)
output = [str(binary_palindromes[i]) for i in xrange(start, end)]
if len(output) == 0:
print 'none'
else:
print ' '.join(output)
if __name__ == '__main__':
main()
I realize Python is not a very fast language but the time limit of only 1 second leads me to believe that the only way to solve this is by using the formula in OEIS. :)
Python is powerful! Don't make it complicated! Well, it is a bit slow!
for _ in range(input()):
has = False
x,y = map(int, raw_input().split())
for i in range(x,y+1):
temp = bin(i)
temp = temp[temp.index('b')+1:]
if temp[::-1] == temp:
has = True
print i,
if not has:
print "none"
I'm in a data structures class and am unable to reproduce the example data given by an instructor. The problem is the classic Josephus problem with a user supplied number of members, step interval, and starting position.
Specifically, I'm told that 99 people, starting on 23, counting off by 5 should leave 84 as the last man standing.
I come up with: 65. I ran again thinking the input may have been 99 people, starting at 5 with an interval of 23. This produced: 42.
My assignment solution involves a circular linked list, however this c code produces the same output in all cases:
#include <stdio.h>
int josephus(int n, long k)
{
if (n == 1)
return 1;
else
/* The position returned by josephus(n - 1, k) is adjusted because the
* recursive call josephus(n - 1, k) considers the original position
* k%n + 1 as position 1 */
return (josephus(n - 1, k) + k-1) % n + 1;
}
int main()
{
int n = 99;
int k = 23;
printf("The chosen place is %d\n", josephus(n, k) + 5);
return 0;
}
Thanks again.
LaFore sees counting off to be stepping over. I.e., starting at 1, counting by two will kill person 4 first. The text does have one example buried in it. This is not intuitive and LaFore seems to be the only author counting this way.
I've been learning Ruby, so I thought I'd try my hand at some of the project Euler puzzles. Embarrassingly, I only made it to problem 4...
Problem 4 goes as follows:
A palindromic number reads the same
both ways. The largest palindrome made
from the product of two 2-digit
numbers is 9009 = 91 × 99.
Find the largest palindrome made from
the product of two 3-digit numbers.
So I figured I would loop down from 999 to 100 in a nested for loop and do a test for the palindrome and then break out of the loops when I found the first one (which should be the largest one):
final=nil
range = 100...1000
for a in range.to_a.reverse do
for b in range.to_a.reverse do
c=a*b
final=c if c.to_s == c.to_s.reverse
break if !final.nil?
end
break if !final.nil?
end
puts final
This does output a palindrome 580085, but apparently this isn't the highest product of two three-digit numbers within the range. Strangely, the same code succeeds to return 9009, like in the example, if I change the range to 10...100.
Can someone tell me where I am going
wrong?
Also, is there a nicer way to
break out of the internal loop?
Thanks
You are testing 999* (999...100), then 998 * (999...100)
Hence you will be testing 999 * 500 before you test 997 * 996.
So, how you we find that right number?
First note the multiplication is reflective, a * b == b * a, so b need not go from 999...0 every time, just a ...0.
When you find a palindrone, add the two factors together and save the sum (save the two factors also)
Inside the loop, if (a+b) is ever less than the saved sum, abandon the inner loop and move to the next a. When a falls below sum/2, no future value you could find would be higher than the one you've already found, so you're done.
The problem is that you might find a palindrome for an a of 999 and a b of 200, but you break too soon, so you never see that there is one for 998*997 (just example numbers).
You need to either look for all palindromes or once you find the first one, set that b as your minimum bound and continue looking through the a loop.
Regarding the second question, my advice is to approach the problem in more functional, than procedural manner. So, rather than looping, you may try to "describe" your problem functionally, and let Ruby does the work:
From all the pairs of 3-digit numbers,
select only those whose product is a palindrome,
and find the one with the largest product
Although this approach may not yield the most efficient of the solutions, it may teach you couple of Ruby idioms.
Consider the digits of P – let them be x, y and z. P must be at least 6 digits long since the palindrome 111111 = 143×777 – the product of two 3-digit integers. Since P is palindromic:
P=100000x + 10000y + 1000z + 100z + 10y + x
P=100001x + 10010y + 1100z
P=11(9091x + 910y + 100z)
Since 11 is prime, at least one of the integers a or b must have a factor of 11. So if a is not divisible by 11 then we know b must be. Using this information we can determine what values of b we check depending on a.
C# Implementation :
using System;
namespace HighestPalindrome
{
class Program
{
static void Main(string[] args)
{
int i, j;
int m = 1;
bool flag = false;
while (true)
{
if (flag) j = m + 1;
else j = m;
for (i = m; i > 0; i--)
{
Console.WriteLine("{0} * {1} = {2}", 1000 - i, 1000 - j, (1000 - i) * (1000 - j));
j++;
//--- Palindrome Check ------------------------------
int number, temp, remainder, sum = 0;
number = temp = (1000 - i) * (1000 - j);
while (number > 0)
{
remainder = number % 10;
number /= 10;
sum = sum * 10 + remainder;
}
if (sum == temp)
{
Console.WriteLine("Highest Palindrome Number is - {0} * {1} = {2}", 1000 - i, 1000 - j, temp);
Console.ReadKey();
return;
}
//---------------------------------------------------
}
if (flag)
m++;
flag = !flag;
}
}
}
}
The mistake is you assume that if you find palindrom with greatest a value it will give the greatest product it isn't true. Solution is to keep max_product value and update it against solution you find.
I can answer your first question: You need to find the highest product, not the product containing the highest factor. In other words a * b could be greater than c * d even if c > a > b.
You're breaking on the first palindrome you come to, not necessarily the biggest.
Say you have A,B,C,D,E. You test E * A before you test D * C.
The main thing is to go through all the possible values. Don't try to break when you find the first answer just start with a best answer of zero then try all combinations and keep updating best. The secondary thing is to try to reduce the set of "all combinations".
One thing you can do is limit your inner loop to values less than or equal to a (since ab == ba). This puts the larger value of your equation always in a and substantially reduces the number of values you have to test.
for a in range.to_a.reverse do
for b in (100..a).to_a.reverse do
The next thing you can do is break out of the inner loop whenever the product is less than the current best value.
c = a*b
next if c < best
Next, if you're going to go through them all anyway there's no benefit to going through them in reverse. By starting at the top of the range it takes a while before you find a palindromic number and as a result it takes a while to reduce your search set. If you start at the bottom you begin to increase the lower bound quickly.
for a in range.to_a do
for b in (100..a).to_a do
My tests show that either way you try some 405K pairs however. So how about thinking of the problem a different way. What is the largest possible product of two 3 digit numbers? 999 * 999 = 998001 and the smallest is 100*100 = 10000. How about we take the idea you had of breaking on the first answer but apply it to a different range, that being 998001 to 10000 (or 999*999 to 100*100).
for c in (10000...998001).to_a.reverse do
We get to a palindrome after only 202 tests... the problem is it isn't a product of two 3-digit numbers. So now we have to check whether the palindrome we've found is a product of 2 3-digit numbers. As soon as we find a value in the range that is a palindrome and a product of two 3-digit numbers we're done. My tests show we find the highest palindrome that meets the requirement after less than 93K tests. But since we have the overhead of checking that all palindromes to that point were products of two 3-digit numbers it may not be more efficient than the previous solution.
So lets go back to the original improvement.
for a in range.to_a.reverse do
for b in (100..a).to_a.reverse do
We're looping rows then columns and trying to be efficient by detecting a point where we can go to the next row because any additional trys on the current row could not possibly be better than our current best. What if, instead of going down the rows, we go across the diagonals?
Since the products get smaller diagonal by diagonal you can stop as soon as you find a palindome number. This is a really efficient solution but with a more complex implementation. It turns out this method finds the highest palindrome after slightly more than 2200 trys.
ar=[]
limit = 100..999
for a in limit.to_a.reverse do
for b in (100..a).to_a.reverse do
c=a*b
if c.to_s == c.to_s.reverse
palndrm=c
ar << palndrm
end
end
end
print ar
print"\n"
puts ar.max
puts ar.min
an implementation:
max = 100.upto(999).inject([-1,0,0]) do |m, a|
a.upto(999) do |b|
prod = a * b
m = [prod, a, b] if prod.to_s == prod.to_s.reverse and prod > m[0]
end
m
end
puts "%d = %d * %d" % max
prints 906609 = 913 * 993
Here's what I came up with in Ruby:
def largest_palindrome_product(digits)
largest, upper, lower = 0, 10**digits - 1, 10**(digits - 1)
for i in upper.downto(lower) do
for j in i.downto(lower) do
product = i * j
largest = product if product > largest && palindrome?(product)
end
end
largest
end
And here's the function to check if the number is a palindrome:
def palindrome?(input)
chars = input.to_s.chars
for i in 0..(chars.size - 1) do
return false if chars[i] != chars[chars.size - i - 1]
end
true
end
I guess there's probably a more efficient solution out there, though.
For this problem, as we are looking for the highest palindrom, i assumed it would start with a 9. Thus ending with a 9 (palindrom).
if you pay attention, to get a number finishing by 9, you can only get it with numbers finishing by 9 and 1, 3 and 3, 7 and 7.
Then it is useless to check the other values (for instance 999*998 as it will not end with a 9).
Starting from 999 and 991, you can then substract 10 to 991, trying 999 and 981 etc...
You do the same with 993 and 993 ... 993 * 983
same with 997 * 997 then 997 * 987 etc
You don't need to go further than 900 or 10^4 - 10^3 as you can be sure the highest will be before.
int PB4_firstTry(int size)
{
int nb1 = (int)pow(10.0,size+1.0) - 1, nb2 = (int)pow(10.0,size+1.0) - 1;
int pal91 = getFirstPalindrome(size,9,1);
int pal33 = getFirstPalindrome(size,3,3);
int pal77 = getFirstPalindrome(size,7,7);
int bigger1 = (pal91 > pal33) ? pal91 : pal33;
return (bigger1 > pal77) ? bigger1 : pal77;
}
int getFirstPalindrome(int size,int ending1,int ending2)
{
int st1 = (int)pow(10.0,size+1.0) - 10 + ending1;
int comp = st1 - pow(10.0,size);
int st2 = (int)pow(10.0,size+1.0) - 10 + ending2;
int answer = -1;
while (st1 > comp)
{
for (int i = st2; i > comp && st1*i > answer; i-=10)
{
if (PB4_isPalindrome(st1*i))
answer = st1*i;
}
st1 -= 10;
}
return answer;
}
bool PB4_isPalindrome(int number)
{
std::string str = intToString(number);
for (int i = 0; i < (int)(str.length() / 2); i++)
{
if (str[i] != str[str.length() - 1 - i])
return false;
}
return true;
}
std::string intToString(int number)
{
std::ostringstream convert;
convert << number;
return convert.str();
}
Of course, this works for 4 size digits factors etc.