I tried the first question:
Problem
The Snapper is a clever little device that, on one side, plugs its input plug into an output socket, and, on the other side, exposes an output socket for plugging in a light or other device.
When a Snapper is in the ON state and is receiving power from its input plug, then the device connected to its output socket is receiving power as well. When you snap your fingers -- making a clicking sound -- any Snapper receiving power at the time of the snap toggles between the ON and OFF states.
In hopes of destroying the universe by means of a singularity, I have purchased N Snapper devices and chained them together by plugging the first one into a power socket, the second one into the first one, and so on. The light is plugged into the Nth Snapper.
Initially, all the Snappers are in the OFF state, so only the first one is receiving power from the socket, and the light is off. I snap my fingers once, which toggles the first Snapper into the ON state and gives power to the second one. I snap my fingers again, which toggles both Snappers and then promptly cuts power off from the second one, leaving it in the ON state, but with no power. I snap my fingers the third time, which toggles the first Snapper again and gives power to the second one. Now both Snappers are in the ON state, and if my light is plugged into the second Snapper it will be on.
I keep doing this for hours. Will the light be on or off after I have snapped my fingers K times? The light is on if and only if it's receiving power from the Snapper it's plugged into.
You can submit your small set as many times as you want, but the large set you only get one chance. You also only get 8 minutes to run the large set input and return a result before you are DQ'd from that questions all together.
I spent a couple hours figuring out how to do the question above quickly. But I made a minor mistake in my algrothim and missed the large set because the time ran out. I didn't realize until I spent another hour fixing my algoritmh that you could only submit once. oh well.
My solution for the above was pretty much this:
for(int i = 1; i <= 30;i++) { if(q.get(Integer.valueOf(i)) != null) { int n = i; double step = Math.pow(2, n); double start = step - 1; for(SnapperStateTuple d: q.get(Integer.valueOf(i)) ) { double test = d.k; test -= start; if(test % step == 0) results.set(d.row-1, true); } } }
The surrounding setup code has been removed for brevity. But the code above ran the large set in 1 second or so correctly.
Since I was DQ'd from that question I tried another one.
Roller coasters are so much fun! It seems like everybody who visits the theme park wants to ride the roller coaster. Some people go alone; other people go in groups, and don't want to board the roller coaster unless they can all go together. And everyone who rides the roller coaster wants to ride again. A ride costs 1 Euro per person; your job is to figure out how much money the roller coaster will make today.
The roller coaster can hold k people at once. People queue for it in groups. Groups board the roller coaster, one at a time, until there are no more groups left or there is no room for the next group; then the roller coaster goes, whether it's full or not. Once the ride is over, all of its passengers re-queue in the same order. The roller coaster will run R times in a day.
For example, suppose R=4, k=6, and there are four groups of people with sizes: 1, 4, 2, 1. The first time the roller coaster goes, the first two groups [1, 4] will ride, leaving an empty seat (the group of 2 won't fit, and the group of 1 can't go ahead of them). Then they'll go to the back of the queue, which now looks like 2, 1, 1, 4. The second time, the coaster will hold 4 people: [2, 1, 1]. Now the queue looks like 4, 2, 1, 1. The third time, it will hold 6 people: [4, 2]. Now the queue looks like [1, 1, 4, 2]. Finally, it will hold 6 people: [1, 1, 4]. The roller coaster has made a total of 21 Euros!
Input
The first line of the input gives the number of test cases, T. T test cases follow, with each test case consisting of two lines. The first line contains three space-separated integers: R, k and N. The second line contains N space-separated integers gi, each of which is the size of a group that wants to ride. g0 is the size of the first group, g1 is the size of the second group, etc.
The solution I came up with is algorithmically correct, but too slow for a huge set (without the arbitrary limit i through in)
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashSet;
import java.util.LinkedList;
//R is the number of runs
//k is the number of ppl a rollercoaster can hold
//N is the num if groups
//
//
//5 5 10
//2 4 2 3 4 2 1 2 1 3
public class ThemePark {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException
{
long start = Calendar.getInstance().getTimeInMillis();
if(args.length != 1)
{
System.out.println("Usage: filename");
return;
}
File out = File.createTempFile("themepark", ".txt");
System.out.println(out.getCanonicalPath());
BufferedWriter bw = new BufferedWriter(new FileWriter(out));
File in = new File(args[0]);
BufferedReader stream = new BufferedReader(new FileReader(in));
String readline = stream.readLine();
Integer numInputs = Integer.parseInt(readline);
for(long inputIndex = 1; inputIndex <=numInputs; inputIndex++)
{
long start1 = Calendar.getInstance().getTimeInMillis();
boolean converged = false;
long lastRunValue = 0;
String[] values = stream.readLine().split(" ");
long r = Integer.parseInt(values[0]);
long k = Integer.parseInt(values[1]);
long N = Integer.parseInt(values[2]);
long n_multiplier = N;
String[] groups = stream.readLine().split(" ");
while(!converged)
{
LinkedList
long n_cycle = 0;
long loop_times = 0 ;
long rides = 0;
boolean rec = false;
boolean terminate = false;
ArrayList
// System.out.println("start: " + r + " " + k + " " + " " + N);
for(String s : groups)
{
groups_size.offer(Integer.parseInt(s));
}
long monies = 0;
for(rides = 0; rides < r; rides++)
{
Integer onRoller = 0;
LinkedList
while(true)
{
if(!groups_size.isEmpty() && onRoller + groups_size.peek() <= k)
{
Integer nextGrp = groups_size.poll();
n_cycle++;
onRoller += nextGrp;
exitList.offer(nextGrp);
}
else
{
// System.out.println("On Roll: " + exitList);
if(rec)
{
cycleList.add(exitList);
}
monies += onRoller;
break;
}
if(n_cycle == n_multiplier)
{
// System.out.println("-----");
loop_times++;
n_cycle = 0;
if(rec)
{
// System.out.println("Pattern Found - terminate");
terminate = true;
}
if(loop_times == 3)
{
// System.out.println("Start Rec");
rec = true;
}
}
}
groups_size.addAll(exitList);
if(terminate)
break;
}
if(terminate)
{
cycleList.remove(cycleList.size()-1);
// System.out.println("pattern size: " + cycleList.size());
long patternCost = 0;
for(LinkedList
{
for(Integer t : i)
{
patternCost += t;
}
}
// System.out.println("Pattern Cost: " + patternCost);
long numberOfFullCyclesLeft = ((r - rides - 1) / cycleList.size());
monies += numberOfFullCyclesLeft * patternCost;
rides += cycleList.size() * numberOfFullCyclesLeft +1;
for(; rides < r; rides++)
{
Integer onRoller = 0;
LinkedList
while(true)
{
if(!groups_size.isEmpty() && onRoller + groups_size.peek() <= k)
{
Integer nextGrp = groups_size.poll();
onRoller += nextGrp;
exitList.offer(nextGrp);
}
else
{
// System.out.println("On Roll: " + exitList);
monies += onRoller;
break;
}
}
groups_size.addAll(exitList);
}
}
// System.out.println("Case #" + inputIndex + ": "+monies );
if(lastRunValue == monies)
{
System.out.println("CONVERGED");
converged = true;
}
else
{
n_multiplier+=cycleList.size();
// System.out.println("bump up: " + n_multiplier);
if(n_multiplier > 100000)
{
converged = true;//give up
}
}
lastRunValue = monies;
}
bw.write("Case #" + inputIndex + ": "+lastRunValue);
bw.newLine();
long total = Calendar.getInstance().getTimeInMillis() - start1;
System.out.println("Time: " + total + "ms");
}
bw.flush();
bw.close();
long total = Calendar.getInstance().getTimeInMillis() - start;
System.out.println("Time: " + total + "ms");
System.out.println(out.getCanonicalPath());
}
}
No comments:
Post a Comment