Skip to content

Instantly share code, notes, and snippets.

@jimmitt
Last active December 25, 2015 16:08
Show Gist options
  • Save jimmitt/7003069 to your computer and use it in GitHub Desktop.
Save jimmitt/7003069 to your computer and use it in GitHub Desktop.
Trapezoid Walkway problem from ACM competition qualification
// Created by James Trimble (on Twitter @jamestrimble)
// View the original problem here, https://icpc-qual-13.contest.scrool.se/problems/walkway
import java.util.LinkedList;
public class trapezoidwalkway {
public static Integer iterations = 0;
public static Double memo[];
public static void main(String[] args) {
Integer backPorch, gazebo;
Integer stones[][];
int problem = 5;
switch (problem) {
case 0:
backPorch = 120;
gazebo = 240;
stones = new Integer[][]{{120,350,60},{120,150,95},{240,300,60},{240,350,220},{150,300,100},{300,350,120}};
break;
case 1:
backPorch = 140;
gazebo = 100;
stones = new Integer[][]{{100,140,50},{100,140,80}};
break;
case 2:
backPorch = 140;
gazebo = 100;
stones = new Integer[][]{{240,50,50},{50,100,40},{240,140,80}};
break;
case 3:
backPorch = 140;
gazebo = 100;
stones = new Integer[][]{{240,50,50},{240,50,40},{50,100,40},{240,140,80}};
break;
case 4:
backPorch = 140;
gazebo = 100;
stones = new Integer[][]{{240,60,50},{60,70,10},{70,80,19},{80,50,19},{10,50,40},{10,20,20},{30,20,30},{30,40,40},{40,50,23},{50,100,40},{240,140,80}};
break;
case 5:
backPorch = 191;
gazebo = 494;
stones = new Integer[][]{{191,782,2},{782,337,3},{337,708,29},{708,888,6},{888,482,30},{482,788,22},{788,650,9},{650,205,10},{205,843,27},{843,631,45},{631,267,45},{267,618,25},{618,30,11},{30,644,44},{644,909,15},{909,360,41},{360,318,29},{318,958,1},{958,267,32},{267,989,50},{989,996,5},{996,300,33},{300,282,22},{282,397,25},{397,464,43},{464,724,45},{724,697,4},{697,401,22},{401,494,4},{494,325,49}};
break;
default:
backPorch = 150;
gazebo = 150;
stones = new Integer[][]{{150,250,100},{150,250,60}};
break;
}
memo = new Double[1000];
for (int i = 0; i < 1000; i++) {
memo[i] = -1.0;
}
iterations = 0;
try {
//System.out.println("Naive = "+naive(backPorch,gazebo,stones.length-1,stones,0)+", "+iterations+" iterations");
}
catch (StackOverflowError e) {
System.out.println("Naive = Stackoverflow, >"+iterations+" iterations");
}
iterations = 0;
try {
System.out.println("TopDown = "+memoize(backPorch,gazebo,stones.length-1,stones,0)+", "+iterations+" iterations");
}
catch (StackOverflowError e) {
System.out.println("TopDown = Stackoverflow, >"+iterations+" iterations");
}
iterations = 0;
try {
System.out.println("BottomUp = "+bottomup(backPorch, gazebo, stones.length - 1, stones, 0)+", "+iterations+" iterations");
}
catch (StackOverflowError e) {
System.out.println("BottomUp = Stackoverflow, >"+iterations+" iterations");
}
}
public static Double cost(Integer a, Integer b, Integer h) {
return .02*.5*h*(b+a);
}
public static Double naive(Integer backPorch, Integer gazebo, Integer stoneIndex, Integer stones[][], Integer length) {
iterations++;
/*if (stoneIndex >= 0) {
System.out.println("naive("+backPorch+","+gazebo+","+
stoneIndex+"=["+
stones[stoneIndex][0]+","+
stones[stoneIndex][1]+","+
stones[stoneIndex][2]+"]"+
",stones[][],"+length+")");
}
else {
System.out.println("naive("+backPorch+","+gazebo+","+stoneIndex+",stones[][],"+length+")");
}*/
Integer start = 0, stop = 1, height = 2;
Integer currentStone[];
Double currentStoneCost;
// If the starting and stopping sizes are the same or there are no stones available, return
if (backPorch.compareTo(gazebo)==0) {
return 0.0;
}
if (stoneIndex < 0 || length > stones.length) {
return 99999999.0;
}
currentStone = stones[stoneIndex];
currentStoneCost = cost(currentStone[start], currentStone[stop], currentStone[height]);
// If the current stone won't fit with our current beginning, try the next stone
if (currentStone[start].compareTo(backPorch) != 0 && currentStone[stop].compareTo(backPorch) != 0) {
return naive(backPorch, gazebo, stoneIndex-1, stones, length);
}
// Otherwise return the minimum of the cost of building the path with the current stone or without it
else {
Double costWithout = naive(backPorch, gazebo, stoneIndex-1, stones, length); // The cost for not using the stone
Double costWith;
if (currentStone[start].compareTo(backPorch)==0) {
costWith = naive(currentStone[stop], gazebo, stones.length-1, stones, ++length);
return Math.min(
currentStoneCost+costWith,
costWithout);
} else {
costWith = naive(currentStone[start], gazebo, stones.length-1, stones, ++length);
return Math.min(
currentStoneCost+costWith,
costWithout);
}
}
}
public static Double topdown(Integer backPorch, Integer gazebo, Integer stoneIndex, Integer stones[][], Integer length) {
/*if (stoneIndex >= 0) {
System.out.println("topdown("+backPorch+","+gazebo+","+
stoneIndex+"=["+
stones[stoneIndex][0]+","+
stones[stoneIndex][1]+","+
stones[stoneIndex][2]+"]"+
",stones[][],"+length+")");
}
else {
System.out.println("topdown("+backPorch+","+gazebo+","+stoneIndex+",stones[][],"+length+")");
}*/
Integer start = 0, stop = 1, height = 2;
Integer currentStone[];
Double currentStoneCost;
// If the starting and stopping sizes are the same or there are no stones available, return
if (backPorch.compareTo(gazebo)==0) {
return 0.0;
}
if (stoneIndex < 0 || length > stones.length) {
return 99999999.0;
}
currentStone = stones[stoneIndex];
currentStoneCost = cost(currentStone[start], currentStone[stop], currentStone[height]);
// If the current stone won't fit with our current beginning, try the next stone
if (currentStone[start].compareTo(backPorch) != 0 && currentStone[stop].compareTo(backPorch) != 0) {
return memoize(backPorch, gazebo, stoneIndex-1, stones, length);
}
// Otherwise return the minimum of the cost of building the path with the current stone or without it
else {
Double costWithout = memoize(backPorch, gazebo, stoneIndex-1, stones, length); // The cost for not using the stone
Double costWith;
if (currentStone[start].compareTo(backPorch)==0) {
costWith = memoize(currentStone[stop], gazebo, stones.length-1, stones, ++length);
return Math.min(
currentStoneCost+costWith,
costWithout);
} else {
costWith = memoize(currentStone[start], gazebo, stones.length-1, stones, ++length);
return Math.min(
currentStoneCost+costWith,
costWithout);
}
}
}
public static Double memoize(Integer backPorch, Integer gazebo, Integer stoneIndex, Integer stones[][], Integer length) {
iterations++;
if (memo[backPorch] == -1.0) {
memo[backPorch] = topdown(backPorch, gazebo, stoneIndex, stones, length);
}
return memo[backPorch];
}
public static Double bottomup(Integer backPorch, Integer gazebo, Integer stoneIndex, Integer stones[][], Integer length) {
/*if (stoneIndex >= 0) {
System.out.println("topdown("+backPorch+","+gazebo+","+
stoneIndex+"=["+
stones[stoneIndex][0]+","+
stones[stoneIndex][1]+","+
stones[stoneIndex][2]+"]"+
",stones[][],"+length+")");
}
else {
System.out.println("topdown("+backPorch+","+gazebo+","+stoneIndex+",stones[][],"+length+")");
}*/
Integer start = 0, stop = 1, height = 2;
Integer currentStone[];
Double currentStoneCost;
Double costs[] = new Double[1001];
LinkedList <Integer> needsUpdating = new LinkedList<Integer>();
Integer currentUpdate;
Double tempCost;
for (int i = 0; i < costs.length; i++) {
costs[i] = 9999999.0;
}
costs[backPorch] = 0.0;
needsUpdating.addLast(backPorch);
while (!needsUpdating.isEmpty()) {
currentUpdate = needsUpdating.removeFirst();
for (int j = 0; j < stones.length; j++) {
iterations++;
tempCost = cost(stones[j][start],stones[j][stop],stones[j][height]);
if (currentUpdate.compareTo(stones[j][start])==0) {
if (costs[currentUpdate]+tempCost < costs[stones[j][stop]]) {
costs[stones[j][stop]] = costs[currentUpdate]+tempCost;
needsUpdating.addLast(stones[j][stop]);
//System.out.println("Added "+stones[j][stop]);
}
}
else if (currentUpdate.compareTo(stones[j][stop])==0) {
if (costs[currentUpdate]+tempCost < costs[stones[j][start]]) {
costs[stones[j][start]] = costs[currentUpdate]+tempCost;
needsUpdating.addLast(stones[j][start]);
//System.out.println("Added "+stones[j][start]);
}
}
}
}
/*for (int i = 0; i < costs.length; i++) {
if (costs[i] < 999) System.out.println("costs["+i+"]="+costs[i]);
} */
return costs[gazebo];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment