Quantcast
Channel: CodeChef Discuss - latest questions
Viewing all 39796 articles
Browse latest View live

Codechef Rating Predictor

$
0
0

Hello everyone!

alt text

Codechef Rating Predictor

The delay in previous month rating changes + inspiration from CF Predictor and for the practice of a web-application, i tried to write a script that can predict rating changes from ongoing live contests @ Codechef.

While the actual delays in rating changes s/would be fixed, this script can help in predicting rating changes as new submissions are made, so hopefully it can be useful for Long contests :).

The script is written in nodejs and is based on open rating formulas available at this link. The code for the project can be accessed here

Website is currently hosted on Openshift free servers and has few restrictions on use. Therefore the server might be slow or not responding during the period rating changes are calculated. Currently, ratings are expected to be updated every 15 minutes

I also tested rating changes on few past contests and the predictions were accurate within an error of 2 for almost everyone except the first rank (I have no idea why first rank predictions are wrong in some contests using current formulas)

Please note that project is still in beta stage and also actual changes might differ more due to changes in ranklist after plagiarism detection

Your feedback/suggestions would be appreciated

JUNE17 Links:

All: http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/JUNE17/all/

Long: http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/JUNE17/long/

Few stats on JUNE17 Predictions. I matched ratings (All) of first 6391 users and the results were as follows:

Difference - No of users

  • 0 - 5868
  • 1 - 275
  • 2 - 125
  • 3 - 68
  • >= 4 - 55

There were around 40 users having difference > 50. Turns out some usernames appears to be missing in the ranklist when sorted by rank and hence they were showing as last in the prediction list.

I ran the code again after fixing the above bug and results are better now (Maximum difference is 8)

  • 0 - 5900
  • 1 - 485
  • >= 2 - 6

Regarding C++ stl- set.

$
0
0

Hey guys, i need some help/clarification on sets.

(I searched for this but couldnt find anything relevant. Hence i would be grateful if you guys could help ^_^ )

Its with reference to problem XORSUB 's solution here which used the method of Gaussian Elimination .

With reference to that solution, there is a comment-

The logic is correct. But there is small flaw in implementation. The above code will give wrong output for following test case

1
3 1
12 10 8
This is because of how STL set works. For correct result, just swap these two statements

s.erase(t);
s.insert(t^m);

Why is this in this way? What is the effect of swapping the two statements? What error is caused in this method and how does swapping fix this? The usual pages on sets dont mention this anywhere, and I feel such exceptional cases should be known to the coder. I would be grateful if anyone can explain this ^_^

Sprague-Grundy Theorem Problems Tutorial

$
0
0

Encountered this rather interesting problem on Combinatorial Game Theory, no threads were present on this theorem so I thought I'll create one.

INTRODUCTION

What is Sprague-Grundy Theorem?
Suppose there is a Composite game being played among two players say A and B with let's say N subgames. The Sprague-Grundy Theorem says that if both A and B play optimally then the player starting first is guaranteed to win if the XOR of the Grundy Numbers of position in each sub-game at the beginning of the game is non-zero. Otherwise, if XOR evaluates to zero, then definitely the player not making the start will win.

I will only be discussing the application to keep thread short and simple and not the proof, refer this for proof.

What are Grundy Numbers?
Grundy Numbers are used to define the state of the game, and these are calculated at the initial condition of each sub-game.

Mathematically: The Grundy Number/ nimber is equal to 0 for a game that is lost immediately by the first player, and is equal to Mex of the nimbers of all possible next positions for any other game.

Calculation of mex
‘Minimum excludant’ a.k.a ‘Mex’ of a set of numbers is the smallest non-negative number not present in the set.

MEX

CALCULATIONS

To solve the problem as a whole, we analyse all sub-games individually and arrive at a result by XORing results of individual sub-games which can be known by analysing the grundy number for that sub-game. So our problem breaks down to create a function which can generate grundy numbers for a subgame.

Consider the following example for clarification:

EXAMPLE
The game starts with a pile of n stones, and the player to move may take any positive number of stones upto 3 only. The last player to move wins. Which player wins the game? This game is 1 pile version of Nim. Since if the first player has 0 stones, he will lose immediately, so Grundy(0) = 0

If a player has 1 stones, then he can take all the stones and win. So the next possible position of the game (for the other player) is (0) stones

Hence, Grundy(1) = Mex(0) = 1 [According to the definition of Mex]

Similarly, if a player has 2 stones, then he can take only 1 stone or he can take 2 stones and win. So the next possible position of the game (for the other player) is (1, 0) stones respectively.

Hence, Grundy(2) = Mex(0, 1) = 2 [According to the definition of Mex]

Similarly, Grundy(3) = Mex(0, 1, 2) = 3 [According to the definition of Mex]

But what about 4 stones ? If a player has 4 stones, then he can take 1 stone or he can take 2 stones or 3 stones, but he can’t take 4 stones (see the constraints of the game). So the next possible position of the game (for the other player) is (3, 2, 1) stones respectively.

Hence, Grundy(4) = Mex (1, 2, 3) = 0 [According to the definition of Mex]

So we can define Grundy Number of any n >= 4 recursively as-

Grundy(n) = Mex[Grundy (n-1), Grundy (n-2), Grundy (n-3)]

We summarize the first the Grundy Value from 0 to 10 in the below table-

alt text

NOTE: The function to calculate grundey number will be depending on the problem.

Function in this case:

int calculateGrundy(int n){

if (n == 0)
    return (0);

if (n == 1)
    return (1);

if (n == 2)
    return (2);

if (n == 3)
    return (3);

unordered_set<int> Set; // A Hash Table

for (i from 1 to 3)
        Set.insert(calculateGrundy(n - i));

return (calculateMex(Set));
}

Refer this pseudo-code for the calculation of Mex about which we talked earlier:

calculateMex(unordered_set a) Mex = 0 while(a.find(Mex)!=a.end()) return Mex

It is advised to either pre-calculate grundy numbers and store in array/vector for fast access or calculate grundy number for each sub-game depending on the constraints

Now we're in a stage where we have grundy numbers calculated, so using Sprague-Grundy Theorem, take XOR of all grundy numbes from all sub-games.
If NON-ZERO - The player who started wins else the player who plays second wins and that gives us our winner.

Any questions, suggestions/improvements are most welcome.

Thanks to @vijju123 for linking me to the source of this. Sources: geeksforgeeks

May LOC: How do I solve SimpleOne problem?

codeforces educational round question doubt

UNIONSET code review June Long, How this can be optimized ?

Help me with SUMQ

$
0
0

Here's my code for the problem SUMQ from June challenge. I am getting wrong answer even with easy constraints. Though I used simplest approach but I think it is correct indeed. I don't know what's wrong. Help me out.https://www.codechef.com/viewsolution/14209998

Merge Sort Tree - Tutorial

$
0
0

Prerequisites : Segment Trees

Target Problem : Given an array of N elements and you have to answer Q queries of the form L R K , To Count the numbers smaller than K in range L to R.

Key Idea : The key idea is to build a Segment Tree with a vector at every node and the vector contains all the elements of the subrange in a sorted order . And if you observe this segment tree structure this is some what similar to the tree formed during the merge sort algorithm ( Yes , thats why they are called Merge Sort Trees ) .

Building the tree :

vector<int>tree[5*N];
int A[N];
Void build_tree( int cur , int l , int r )
{
     if( l==r )
     {
            tree[cur].push_back( a[ l ] );
            return ;
     }
     int mid = l+(r-l)/2;
     build_tree(2*cur+1 , l , mid ); // Build left tree
     build_tree(2*cur+2 , mid+1 , r ); // Build right tree
     tree[cur] = merge( tree[2*cur+1] , tree[2*cur+2] ); //Merging the two sorted arrays
}

Querying the tree :

int query( int cur, int l, int r, int x, int y, int k)
{
       if( r < x || l > y )
      {
               return 0; //out of range
      }
      if( x<=l && r<=y )
      {
              //Binary search over the current sorted vector to find elements smaller than K

              Return upper_bound(tree[cur].begin(),tree[cur].end(),K)-tree[cur].begin();
      }
      int mid=l+(r-l)/2;
     return query(2*cur+1,l,mid,x,y,k)+query(2*cur+2,mid+1,r,x,y,k);
}

Build function Analysis : Build a merge sort tree takes O(NlogN) time which is same as Merge Sort Algorithm . It will take O(NlogN) memory because each number Ai will be present in at most LogN vectors (Height of the tree ) .

Query function Analysis : A range L to R can divided into at most Log(N) parts, where we will perform binary search on each part . So this gives us complexity of O(LogN * LogN) per query .

Handling Point Updates : The only reason that we cant handle updates on MST in this code is because its merge function takes too much time, so even if theres a point update it will lead to O(N). So the major issue is of vectors and rearranging them on updations, but why do we need vectors ? Just to find the elements smaller than K in that complete vector, right ? Lets forget about vectors and keep policy based data structure at each node which handles three queries (insertion , deletion and elements smaller than K in the set) in O(LogN) time . So now no need to rearrange vectors and we can use insertion - deletion to handle point queries . This is just an idea , we can discuss this in comments again if anyone has a doubt .

Bonus : How to use this to solve the query of type Kth smallest number in range L to R ? So we can binary search over the solution and find the value which has exactly K numbers smaller than it in the given range . Complexity : O(LogN * LogN * LogAi ) per query .

Why to use MST: Apart from the code simplicity, they answer queries online . We could have used some offline algorithms like MOs or even Segment tree but come on, Online Querying is great because it can be used in Dp Optimisations and stuff like that . Peace Out .


help needed - ZCO13003 (CHEWING)

Understanding performance of map and priority queue in stl

$
0
0

I was trying out the chef and reversing question of August Chanllenge. During the contest, I tried out this . My logic goes the same way as finding the path in Dijkstra's, the only difference is I am using revcnt[] as the basis of relaxing the edges. (The undirected version of the graph is stored in a vector and the input graph in a set). If an edge from i to j exists in the input graph(done by finding in the set line no 42 in the code), then revcnt[j]=revcnt[i] else, revcnt[j]=revcnt[i]+1. It gave TLE. I used map for getting the vertex with minimum revcnt[], because map is a form of balanced binary tree and hance the order of insertion is O(logn) and the ver first entry of the map will give the required node to start with.

Seeing other's solution, I tried the priority queue version of the same. It passed. Why is it so, because even in this the complexity is same I suppose. Then why the previous map solution gave tle.

SEAKAM - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Sergey Nagin
Tester:Antoniuk Vasyl and Misha Chorniy
Editorialist:Pushkar Mishra

DIFFICULTY:

Medium

PREREQUISITES:

Bitmask DP, Combinatorics

PROBLEM:

Given is a graph with $N$ nodes which is almost complete, i.e., all but $M$ edges are present. Count the number of permutations $P[1..N]$ such that if the permutation was considered to be the order in which nodes are visited in the graph then it is a valid traversal. In other words, there exists an edge from $P[1]$ to $P[2]$, from $P[2]$ to $P[3]$, ..., i.e., from $P[i]$ to $P[i+1]$ for $i = 1$ to $N-1$.

EXPLANATION:

Subtask 1
Simply iterate over all permutations of the nodes and count the valid ones by checking the presence of edges between $P[i]$ and $P[i+1]$. This approach takes $\mathcal{O}(N!)$ time and is fine for this substask.

Subtask 2, 3, 4
Most of the counting questions can be solved using DP. Let us see how we can think about this particular problem in terms of optimal sub-structure and overlapping sub-problems, i.e., the two necessary and sufficient requirements of a DP.

Let us think of the problem now in a way that we get to a DP. We can see that the number of missing edges are extremely few, i.e., just 7. In other words, the graph is an almost complete one. 7 missing edges means we just need to worry about the arrangement of at max 14 nodes. The other nodes can be shuffled in any manner since they don't affect the correctness of a permutation.

Let us call the set of nodes which have certain edges missing $faulty\_nodes$. So it is the relative placement of the nodes of this set. Let $x$ and $y$ be two nodes in this set. If $x$ and $y$ HAVE an edge between them, i.e., edge $(x, y)$ is not amongst the $M$ missing edges, then we needn't worry about how $x$ and $y$ are placed relative to each other in a permutation. This is our only concern is that the nodes which share a missing edge should not be adjacent to each other in a permutation. Even if $x$ and $y$ appear adjacent to each other, that won't make the particular permutation invalid.

But what happens if $x$ and $y$ do not share an edge? We have to make sure they don't appear adjacent to each other. How do we ensure that? We basically need to make sure that there always exists at least one element $z$ such that $z$ has an with both $x$ and $y$. In other words, $z$ behave as a bridge.

This gives us a hint towards the solution, i.e., the DP. We know that there only exist at maximum 14 nodes in the $faulty\_nodes$ set. This means that we can iterate over all possible relative placements of the faulty nodes. Not clear? Let us take an example. Let the given graph have 5 nodes $n_1$, $n_2$, $n_3$, $n_4$, $n_5$. Of these 5, let us assume that edges $(n_2, n_3)$ and $(n_3, n_4)$ are missing, i.e., $n_2$, $n_3$, $n_4$ are faulty nodes.

In this case, there are 6 (i.e., 3!) possible relative placements of the faulty nodes in a permutation. There are $(n_4, n_2, n_3)$, $(n_4, n_3, n_2)$, $(n_2, n_4, n_3)$, $(n_2, n_3, n_4)$, $(n_3, n_4, n_2)$ and $(n_3, n_2, n_4)$. Note that these are relative placements of the faulty nodes only. This means that the remaining nodes, i.e., $n_1$ and $n_5$ can be placed anywhere between these faulty nodes to form a permutation $P$ of the graph. If then each adjacent pair $P[i]$, $P[i+1]$ have an edge between them then the permutation is a valid one. Now let us pick up any one of the 6 relative arrangements and try to add the two remaining nodes in it.

Let's take $(n_2, n_4, n_3)$. Now let us see where all we can fit the $n_1$ and $n_5$ nodes so as to form valid permutations. We must place one between $n_4$ and $n_3$ since they can't be together. There must be a node between them to act as a bridge. So one valid placement of $n_1$ and $n_5$ can be $(n_1, n_2, n_4, n_5, n_3)$. Another one can be made by swapping $n_1$ and $n_5$. Further another one can be made one by moving around $n_1$ in $(n_1, n_2, n_4, n_5, n_3)$, something like $(n_2, n_4, n_5, n_1, n_3)$.

Now, we have a way to count the number of valid permutations that can be made. First, we take a relative arrangement of the faulty nodes. Then between each pair of faulty nodes that have a missing edge, we must place at least one normal node to act as bridge. This way, we will be able to count all the valid permutations.

One way to go about this is to cycle through all the arrangements of the faulty nodes. For a particular arrangement, we check which all pairs of adjacent faulty nodes need a bridge element between them. If a pair $x$, $y$ needs one, we "tie" a normal node $z$ to the front of $y$. Thus, we treat pair $z$, $y$ as one element. Now, we arrange the "modified" nodes in the faulty nodes set (modified as in tied with normal nodes where required) in the $(N-$ number of normal nodes used as bridges$)$ possible positions. The number of ways to do this further multiplied by the factorial of number of normal nodes (this is because any of the normal nodes can be used and bridge and they can be shifted around) gives the number of valid permutations for the particular relative arrangement. But this method has a problem. There can be total of 14! possible arrangements of the faulty nodes. This is not practical. We have to reduce the number of cases to consider.

This is where DP comes into picture. Let's maintain a DP with three states: $DP[mask][first\_node][number\_tied]$. What do these states indicate? $mask$ tells us which of the faulty nodes have been arranged; $first\_node$ is the first node of the arrangement and $number\_tied$ tells the stores the number of normal nodes that have been used as bridges, i.e., tied to a faulty node. The state $mask$ goes from $1$ to $2^{14}-1$, $first\_node$ has 14 possible values and $number\_tied$ also has 14 possible values at max.

Thus, $DP[mask][first\_node][number\_tied]$ gives the number of arrangements of the faulty nodes whose bit is 1 in the number mask such that the first node of the arrangement is $first\_node$ and the $number\_tied$ is the number of normal nodes used as bridges.

We can now formulate the recurrence:

let k = faulty_nodes.size()
let ans = 0 //counter variable
let normal_nodes = N - k;

for mask = 1 to (2^k-1)
{
    for first_node = 0 to k-1
    {
        for number_tied = 0 to k-1
        {
            //appending a new node to the beginning of the arrangement that
            //is given by mask.
            for new_first = 0 to k-1
            {
                if(new_first bit in mask == 0)
                {
                    new_mask = bitwise_or(mask, 2^new_first)
                    missing_edge = 1 if edge (new_first, first_node) missing else 0

                    //adding to the count of sequences starting with new_first and
                    //containing faulty nodes as the ones in the new_mask
                    dp[new_mask][new_first][number_tied + missing_edge] += dp[mask][first_node][number_tied];

                    //note that if the edge (new_first, first_node) is missing,
                    //we will have to tie an element to first_node, i.e.,
                    //increasing number_tied by 1.
                }
            }

            if(mask == (2^k - 1))
            {
                //if all the faulty nodes have been arranged then we can
                //count the number of valid permutations for this
                //particular arrangement

                total_objects = N - number_tied;
                val = dp[mask][first_node][number_tied];

                //getting all ways of arranging items
                get_ways = (total_objects choose k) * (val);

                //multiplying the number of ways of permuting normal nodes.
                get_ways = (get_ways * factorial[normal_nodes]);

                //adding to the counter variable
                ans = (ans + get_ways);
            }
        }
    }
}

return ans;

The editorialist's program follows the editorial. Please see for implementation details. The (n choose k) mod m has been calculated using inverse factorials since m in this case is a sufficiently large prime.

OPTIMAL COMPLEXITY:

$\mathcal{O}(M^32^M)$ per test case.

SAMPLE SOLUTIONS:

Author
Tester
Editorialist

Poll for JUNE17 Video Editorials

$
0
0

Hi everyone!

This month's long challenge editorials are not out yet. Hence, I would like to invite you all to vote for 2 problems, for which I will be making video editorials.

https://strawpoll.com/5y796xr

Cheers!

Good websites for number theory.

$
0
0

What are the best sources for learning number theory?

Heavy-Light Decomposition

$
0
0

Can someone provide a good tutorial(well explained) or provide some link on how to exactly implement H-L Decomposition. I have searched a lot and been through almost all suggested websites. The main problem is in the segment tree part. I have seen some implementations but cant understand really why all that is being done.

A walk, through code would be really helpful in understand the essence.

Thank You

Tries Implementation in C++

$
0
0

Hi team, I am looking for the simple implementation of Tries Data Structure in C++ with some descriptions of code which will make it easier to understand.I have gone through several codes available on net but all of them are lacking description.If you have your own code, then pls provide the description of your code, otherwise, your code is useless for me.


Help in Templeland

$
0
0

I just joined CodeChef and trying to solve Temple Land problem. The link to the problem is : https://www.codechef.com/problems/TEMPLELA. I've written following code for the problem :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            int Num_of_Strips;
            Console.WriteLine("Enter the number of strips to look at(1<=Number of Strips<=100) : ");
            Num_of_Strips = int.Parse(Console.ReadLine());
            int[] Num = new int[Num_of_Strips+1];
            int flag = 0;
            for(int i=0;i<Num_of_Strips;i++)
            {
                Console.WriteLine("Enter the length of Strip" + (i+1) +" : ");
                Num[i + 1] = int.Parse(Console.ReadLine());
                int[] height = new int[Num[i + 1]+1];
                for (int j = 1; j <= Num[i + 1];j++)
                {
                    Console.WriteLine("Enter the height of part" + j + " : ");
                    height[j] = int.Parse(Console.ReadLine());
                }
                if((height[1] == 1)&&(height[Num[i + 1]] == 1))
                {
                    if(Num[i + 1]%2 == 1)
                    {
                        int Centre_Position = (Num[i + 1] + 1) / 2;
                        for(int k = 1; k<= Num[i + 1];k++)
                        {
                            if((k>1) && (k<=Centre_Position))
                            {
                                if(height[k] == height[k-1]+1)
                                {
                                    flag = 1;
                                }
                                else
                                {
                                    flag = 0;
                                    break;
                                }

                            }
                            else if((k>Centre_Position) && (k< Num[i + 1]))
                            {
                                if(height[k] == height[k-1]-1)
                                {
                                    flag = 1;
                                }
                                else
                                {
                                    flag = 0;
                                    break;
                                }
                            }
                        }
                        if(flag == 0)
                        {
                            Console.WriteLine("no");
                        }
                        else
                        {
                            Console.WriteLine("yes");
                        }
                    }
                    else
                    {
                        Console.WriteLine("no");
                    }
                }
                else
                {
                    Console.WriteLine("no");
                }
            }
            Console.ReadKey();
        }
    }
}

This code is working fine in my System incuding other two systems I've checked it with and providing correct output. Don't know why it is giving Runtime Error(NZEC) while submitting the solution. Can anyone help me in detecting if there is any problem in the code or why it is giving such error whie uploading to codechef.

Why do I get an NZEC?

$
0
0

Why m i getting NZEC (Non Zero Exit Code) for my program?

help newbie programmer......

$
0
0

i am new to competitive programming ....i am unable to solve more than one problem in the june challenge... how should i improve my programming skills ... any book or website links to know the algorithms and programming skills......

TLG - Editorial

$
0
0

PROBLEM LINK:

Practice

Author:ADMIN

Editorialist:SUSHANT AGARWAL

DIFFICULTY:

EASY

PREREQUISITES:

Basic looping,Arrays

PROBLEM:

At the end of each round the leader and her current lead are calculated. Once all the rounds are over the player who had the maximum lead at the end of any round in the game is declared the winner.

EXPLANATION:

Create two arrays(Player1-Stores the scores of player 1 in all the rounds)[a1,a2,a3....an] and (Player2-Stores the scores of player 2 in all the rounds)[b1,b2,b3...bn].

Create a third array "Lead" such that the i'th element of Lead is ((a1+a2...+ai) - (b1+b2...bi)). Create a fourth array "modulus lead" such that the i'th element of this array is the modulus of the i'th element of "Lead".

Find the maximum element of "modulus lead".This is the maximum lead attained by the winner.If the element in the corresponding position of "lead" is positive then player 1 is the winner,otherwise player 2 is.

EDITORIALIST'S SOLUTION:

Editorialist's solution can be found here.

Best Editor to write C++ program?

$
0
0

Which is the best editor for writing programs in c++.Currently i use DevC++. i want editor in which i could set a predefined template so that i dont have to type macros and include libraries again and again?

Viewing all 39796 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>