Hi
i am creating online quiz. For that i am creating arrays of answers selected by user. i used following code for that, it gives correct array but sometimes gives error "Index was outside the range"
//rsel is session values for selected answer
int rsel = Convert.ToInt32(Session["rblsel"]);
// [Convert.ToInt32(Session["Counter"] indicates size of array of no. of questions
int[] ansarray = new int[Convert.ToInt32(Session["Counter"]) - 1];
int[] temp = (int[])Session["arrofans"];
int j,n;
if (temp == null)
n = 0;
else
n = temp.Length;
for (j = 0; j < n; j++)
{
ansarray[j] = temp[j];
}
ansarray[j] = rsel;
Session["arrofans"] = ansarray;
Help me to find out exact error. Asp.net,c#
Thank you.
Why are you reducing the "counter" by one?
int[] ansarray = new int[Convert.ToInt32(Session["Counter"]) - 1];
It looks like that should probably be a + 1... but to be honest it would be simpler to use the size of ansarray - and use Array.Resize to effectively extend it:
int[] ansarray = (int[])Session["arrofans"];
Array.Resize(ref ansarray, ansarray.Length + 1);
ansarray[ansarray.Length - 1] = rsel;
Session["arrofans"] = ansarray;
That way you don't even need the "Counter" part of the session.
One possible OutOfRange could be triggered when
**arrofans.length >= Counter**
temp.Length should not be bigger than ansarray.Length, or precisely from your code it ansarray.Length must be temp.Length+1 or bigger. To avoid your problem you must change it to for (j = 0; j < n && j < (ansarray.Length-1); j++) but i don't know if it will suite your case
Related
I am trying to implement a "coupling to the past" algorithm in Rcpp. For this I need to store a matrix of random numbers, and if the algorithm did not converge create a new matrix of random numbers and store that as well. This might have to be done 10+ times or something until convergence.
I was hoping I could use a List and dynamically update it, similar as I would in R. I was actually very surprised it worked a bit but I got errors whenever the list size becomes large. This seems to make sense as I did not allocate the needed memory for the additional list elements, although I am not that familiar with C++ and not sure if that is the problem.
Here is an example of what I tried. however be aware that this will probably crash your R session:
library("Rcpp")
cppFunction(
includes = '
NumericMatrix RandMat(int nrow, int ncol)
{
int N = nrow * ncol;
NumericMatrix Res(nrow,ncol);
NumericVector Rands = runif(N);
for (int i = 0; i < N; i++)
{
Res[i] = Rands[i];
}
return(Res);
}',
code = '
void foo()
{
// This is the relevant part, I create a list then update it and print the results:
List x;
for (int i=0; i<10; i++)
{
x[i] = RandMat(100,10);
Rf_PrintValue(wrap(x[i]));
}
}
')
foo()
Does anyone know a way to do this without crashing R? I guess I could initiate the list at a fixed amount of elements here, but in my application the amount of elements is random.
You have to "allocate" enough space for your list. Maybe you can use something like a resizefunction:
List resize( const List& x, int n ){
int oldsize = x.size() ;
List y(n) ;
for( int i=0; i<oldsize; i++) y[i] = x[i] ;
return y ;
}
and whenever you want your list to be bigger than it is now, you can do:
x = resize( x, n ) ;
Your initial list is of size 0, so it expected that you get unpredictable behavior at the first iteration of your loop.
I'm constructing a graph with JGraphX. Using the following code, it takes an inordinately long time to build compared to similar graph implementations like JGraphT. Why would this be? The vertices are created quickly, but the nested loops that create the edges take a long time, especially when the array sizes are 1000.
Vertex[] verts = new Vertex[1000]; // My own vertex class
mxCell[] cells = new mxCell[1000]; // From com.mxGraph.model.mxCell
// Create graph
mxGraph mx = new mxGraph(); // from com.mxgraph.view.mxGraph
// Create vertices
for(int i = 0; i < verts.length; i++)
{
verts[i] = new Vertex(Integer.toString(i));
cells[i] = new mxCell(verts[i]);
mx.getModel().beginUpdate();
mx.insertVertex(null, Integer.toString(i), cells[i], 1, 1, 1, 1);
mx.getModel().endUpdate();
}
System.out.println("Vertices created.");
// Connect graph
Random r = new Random();
for(int j = 0; j < verts.length; j++)
{
for(int k = 0; k < verts.length; k++)
{
if(k != j)
{
if(r.nextInt(5) == 0) // Random connections, fairly dense
{
mx.getModel().beginUpdate();
mx.insertEdge(null, Integer.toString(k) + " " + Integer.toString(j), "", cells[j], cells[k]);
mx.getModel().endUpdate();
}
}
}
}
System.out.println("Finished graph.");
begin and end updates are meant for combining operations into one. Ending an update causes a complete validation of the graph. Here you're wrapping each atomic operation only, they have no effect.
Remove the begin/ends you have an put a begin after you create the graph and the end at the bottom of this code section and try that.
Project Euler problem 14:
The following iterative sequence is
defined for the set of positive
integers:
n → n/2 (n is even) n → 3n + 1 (n is
odd)
Using the rule above and starting with
13, we generate the following
sequence: 13 → 40 → 20 → 10 → 5 → 16 →
8 → 4 → 2 → 1
It can be seen that this sequence
(starting at 13 and finishing at 1)
contains 10 terms. Although it has not
been proved yet (Collatz Problem), it
is thought that all starting numbers
finish at 1.
Which starting number, under one
million, produces the longest chain?
My first instinct is to create a function to calculate the chains, and run it with every number between 1 and 1 million. Obviously, that takes a long time. Way longer than solving this should take, according to Project Euler's "About" page. I've found several problems on Project Euler that involve large groups of numbers that a program running for hours didn't finish. Clearly, I'm doing something wrong.
How can I handle large groups of numbers quickly?
What am I missing here?
Have a read about memoization. The key insight is that if you've got a sequence starting A that has length 1001, and then you get a sequence B that produces an A, you don't to repeat all that work again.
This is the code in Mathematica, using memoization and recursion. Just four lines :)
f[x_] := f[x] = If[x == 1, 1, 1 + f[If[EvenQ[x], x/2, (3 x + 1)]]];
Block[{$RecursionLimit = 1000, a = 0, j},
Do[If[a < f[i], a = f[i]; j = i], {i, Reverse#Range#10^6}];
Print#a; Print[j];
]
Output .... chain length´525´ and the number is ... ohhhh ... font too small ! :)
BTW, here you can see a plot of the frequency for each chain length
Starting with 1,000,000, generate the chain. Keep track of each number that was generated in the chain, as you know for sure that their chain is smaller than the chain for the starting number. Once you reach 1, store the starting number along with its chain length. Take the next biggest number that has not being generated before, and repeat the process.
This will give you the list of numbers and chain length. Take the greatest chain length, and that's your answer.
I'll make some code to clarify.
public static long nextInChain(long n) {
if (n==1) return 1;
if (n%2==0) {
return n/2;
} else {
return (3 * n) + 1;
}
}
public static void main(String[] args) {
long iniTime=System.currentTimeMillis();
HashSet<Long> numbers=new HashSet<Long>();
HashMap<Long,Long> lenghts=new HashMap<Long, Long>();
long currentTry=1000000l;
int i=0;
do {
doTry(currentTry,numbers, lenghts);
currentTry=findNext(currentTry,numbers);
i++;
} while (currentTry!=0);
Set<Long> longs = lenghts.keySet();
long max=0;
long key=0;
for (Long aLong : longs) {
if (max < lenghts.get(aLong)) {
key = aLong;
max = lenghts.get(aLong);
}
}
System.out.println("number = " + key);
System.out.println("chain lenght = " + max);
System.out.println("Elapsed = " + ((System.currentTimeMillis()-iniTime)/1000));
}
private static long findNext(long currentTry, HashSet<Long> numbers) {
for(currentTry=currentTry-1;currentTry>=0;currentTry--) {
if (!numbers.contains(currentTry)) return currentTry;
}
return 0;
}
private static void doTry(Long tryNumber,HashSet<Long> numbers, HashMap<Long, Long> lenghts) {
long i=1;
long n=tryNumber;
do {
numbers.add(n);
n=nextInChain(n);
i++;
} while (n!=1);
lenghts.put(tryNumber,i);
}
Suppose you have a function CalcDistance(i) that calculates the "distance" to 1. For instance, CalcDistance(1) == 0 and CalcDistance(13) == 9. Here is a naive recursive implementation of this function (in C#):
public static int CalcDistance(long i)
{
if (i == 1)
return 0;
return (i % 2 == 0) ? CalcDistance(i / 2) + 1 : CalcDistance(3 * i + 1) + 1;
}
The problem is that this function has to calculate the distance of many numbers over and over again. You can make it a little bit smarter (and a lot faster) by giving it a memory. For instance, lets create a static array that can store the distance for the first million numbers:
static int[] list = new int[1000000];
We prefill each value in the list with -1 to indicate that the value for that position is not yet calculated. After this, we can optimize the CalcDistance() function:
public static int CalcDistance(long i)
{
if (i == 1)
return 0;
if (i >= 1000000)
return (i % 2 == 0) ? CalcDistance(i / 2) + 1 : CalcDistance(3 * i + 1) + 1;
if (list[i] == -1)
list[i] = (i % 2 == 0) ? CalcDistance(i / 2) + 1: CalcDistance(3 * i + 1) + 1;
return list[i];
}
If i >= 1000000, then we cannot use our list, so we must always calculate it. If i < 1000000, then we check if the value is in the list. If not, we calculate it first and store it in the list. Otherwise we just return the value from the list. With this code, it took about ~120ms to process all million numbers.
This is a very simple example of memoization. I use a simple list to store intermediate values in this example. You can use more advanced data structures like hashtables, vectors or graphs when appropriate.
Minimize how many levels deep your loops are, and use an efficient data structure such as IList or IDictionary, that can auto-resize itself when it needs to expand. If you use plain arrays they need to be copied to larger arrays as they expand - not nearly as efficient.
This variant doesn't use an HashMap but tries only to not repeat the first 1000000 numbers. I don't use an hashmap because the biggest number found is around 56 billions, and an hash map could crash.
I have already done some premature optimization. Instead of / I use >>, instead of % I use &. Instead of * I use some +.
void Main()
{
var elements = new bool[1000000];
int longestStart = -1;
int longestRun = -1;
long biggest = 0;
for (int i = elements.Length - 1; i >= 1; i--) {
if (elements[i]) {
continue;
}
elements[i] = true;
int currentStart = i;
int currentRun = 1;
long current = i;
while (current != 1) {
if (current > biggest) {
biggest = current;
}
if ((current & 1) == 0) {
current = current >> 1;
} else {
current = current + current + current + 1;
}
currentRun++;
if (current < elements.Length) {
elements[current] = true;
}
}
if (currentRun > longestRun) {
longestStart = i;
longestRun = currentRun;
}
}
Console.WriteLine("Longest Start: {0}, Run {1}", longestStart, longestRun);
Console.WriteLine("Biggest number: {0}", biggest);
}
Basically I've been trying to make a working hours calculator and I've run into a problem. When the start time's value is greater than the finish time (eg. start is 23 and finish is 19), the result comes up as a negative. So what I want it to do in that scenario is to then multiply the negative number by -1 to make it positive again. However, this code below doesn't seem to have any effect in my app.
-(IBAction)done:(id)sender {
int result = [finishHours.text intValue] - [startHours.text intValue];
totalHours.text = [NSString stringWithFormat:#"%i", result];
if (result < 0) {
result = result * -1;
}
You set totalHours.text before you change the sign of your result variable.
what do you mean it doesn't have any effect? is it because you have changed result after you have set totalHours? would this fix your issue?
-(IBAction)done:(id)sender {
int result = [finishHours.text intValue] - [startHours.text intValue];
if (result < 0) {
result = result * -1;
}
totalHours.text = [NSString stringWithFormat:#"%i", result];
I need to create an asp.net page that auto generate a brackets tournament tennis style.
Regarding the managing of match in database, it's not a problem.
The problem is the dynamic graphics creation of brackets.
The user will be able to create tournament by 2-4...32 players.
And i don't know ho to create the graphics bracket in html or gdi...
Using Silverlight, and a Grid, You can produce something like this:
To do it, define a regular UserControl containing a Grid. (This is the default when you build a silverlight app in VS2008 with the Silverlight 3.0 SDK).
Then, add a call to the following in the constructor for the user control:
private void SetupBracket(int n)
{
var black = new SolidColorBrush(Colors.Gray);
// number of levels, or rounds, in the single-elim tourney
int levels = (int)Math.Log(n, 2) + 1;
// number of columns in the Grid. There's a "connector"
// column between round n and round n+1.
int nColumns = levels * 2 - 1;
// add the necessary columns to the grid
var cdc = LayoutRoot.ColumnDefinitions;
for (int i = 0; i < nColumns; i++)
{
var cd = new ColumnDefinition();
// the width of the connector is half that of the regular columns
int width = ((i % 2) == 1) ? 1 : 2;
cd.Width = new GridLength(width, GridUnitType.Star);
cdc.Add(cd);
}
var rdc = LayoutRoot.RowDefinitions;
// in the grid, there is one row for each player, and
// an interleaving row between each pair of players.
int totalSlots = 2 * n - 1;
for (int i = 0; i < totalSlots; i++)
{
rdc.Add(new RowDefinition());
}
// Now we have a grid of the proper geometry.
// Next: fill it.
List<int> slots = new List<int>();
ImageBrush brush = new ImageBrush();
brush.ImageSource = new BitmapImage(new Uri("Bridge.png", UriKind.Relative));
// one loop for each level, or "round" in the tourney.
for (int j = 0; j < levels; j++)
{
// Figure the number of players in the current round.
// Since we insert the rounds in the reverse order,
// think of j as the "number of rounds remaining."
// Therefore, when j==0, playersThisRound=1.
// When j == 1, playersThisRound = 2. etc.
int playersThisRound = (int)Math.Pow(2, j);
int x = levels - j;
int f = (int)Math.Pow(2, x - 1);
for (int i = 0; i < playersThisRound; i++)
{
// do this in reverse order. The innermost round is
// inserted first.
var r = new TextBox();
r.Background = black;
if (j == levels - 1)
r.Text = "player " + (i + 1).ToString();
else
r.Text = "player ??";
// for j == 0, this is the last column in the grid.
// for j == levels-1, this is the first column.
// The grid column is not the same as the current
// round, because of the columns used for the
// interleaved connectors.
int k = 2 * (x - 1);
r.SetValue(Grid.ColumnProperty, k);
int m = (i * 2 + 1) * f - 1;
r.SetValue(Grid.RowProperty, m);
LayoutRoot.Children.Add(r);
// are we not on the last round?
if (j > 0)
{
slots.Add(m);
// Have we just inserted two rows? Then we need
// a connector between these two and the next
// round (the round previously added).
if (slots.Count == 2)
{
string xamlTriangle = "<Path xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' "+
"xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' " +
"Data='M0,0 L 100 50 0 100 Z' Fill='LightBlue' Stretch='Fill'/>";
Path path = (Path)System.Windows.Markup.XamlReader.Load(xamlTriangle);
path.SetValue(Grid.ColumnProperty, 2 * (x - 1) + 1);
path.SetValue(Grid.RowProperty, slots[0]);
path.SetValue(Grid.RowSpanProperty, slots[1] - slots[0] + 1);
this.LayoutRoot.Children.Add(path);
slots.Clear();
}
}
}
}
}
In the above, the connector is just an isosceles triangle, with the apex pointing to the right. It is generated by XamlReader.Load() on a string.
You would also want to pretty it up, style it with different colors and fonts, I guess.
You can insert this silverlight "user control" into any HTML web page, something like embedding a flash app into a page. There are silverlight plugins for IE, Firefox, Opera, Safari, and Chrome.
If you don't want to use Silverlight, you could use a similar approach to construct an HTML table.