home / fivethirtyeight / riddler-castles/castle-solutions-2

Menu
  • GraphQL API

riddler-castles/castle-solutions-2: 78

This directory contains the data behind the submissions for castles puzzle.

  • castle-solutions.csv contains the submissions for Can You Rule Riddler Nation?
  • castle-solutions-2.csv contains the submissions for The Battle For Riddler Nation, Round 2
  • castle-solutions-3.csv contains the submissions for Are You The Best Warlord?
  • castle-solutions-4.csv contains the submissions for A Peaceful (But Not Peaceful) Transition Of Power In Riddler Nation
  • castle-solutions-5.csv contains the submissions for The Fifth Battle For Riddler Nation, in which there were 13 castles rather than the usual 10

Readers were asked to submit a strategy for the following “Colonel Blotto”-style game:

In a distant, war-torn land, there are 10 castles. There are two warlords: you and your archenemy. Each castle has its own strategic value for a would-be conqueror. Specifically, the castles are worth 1, 2, 3, …, 9, and 10 victory points. You and your enemy each have 100 soldiers to distribute, any way you like, to fight at any of the 10 castles. Whoever sends more soldiers to a given castle conquers that castle and wins its victory points. If you each send the same number of troops, you split the points. You don’t know what distribution of forces your enemy has chosen until the battles begin. Whoever wins the most points wins the war.

Submit a plan distributing your 100 soldiers among the 10 castles. Once I receive all your battle plans, I’ll adjudicate all the possible one-on-one matchups. Whoever wins the most wars wins the battle royale and is crowned king or queen of Riddler Nation!

The data includes all valid submissions, with solvers’ identifying information removed. The 11 columns represent the soldiers deployed to each of the 10 castles, plus a column where the reader could describe his or her strategic approach.

Correction

Please see the following commit: https://github.com/fivethirtyeight/data/commit/c3f808fda5b67aa26ea6fa663ddd4d2eb7c6187f

Data license: CC Attribution 4.0 License · Data source: fivethirtyeight/data on GitHub · About: simonw/fivethirtyeight-datasette

This data as json, copyable

rowid Castle 1 Castle 2 Castle 3 Castle 4 Castle 5 Castle 6 Castle 7 Castle 8 Castle 9 Castle 10 Why did you choose your troop deployment?
78 1 6 9 16 5 15 9 12 15 12 I chose it based on an intuition that a certain number of people would pick the winning strategy from last time, a certain number of people would pick a strategy which beats that one, a certain number would pick a strategy which beats THAT one, and so on and so forth. Like with a Keynesian beauty contest game, you want to be exactly one step ahead of most other people; no more, no less. And, in my experience, people usually go around 2-3 levels deep on these things. So, I generated a data set which took the original strategy and added a lot of the winning strategy, and one which beats the winning strategy, and one which beats that, etc. Then, I calculated the expected number of net points you can get, based on this dataset, for each number of people in each castle. After that, it's a simple evolving function to find a strategy where taking away from any one castle would cause more harm than the good of adding someone to another castle. The remainder of my answer is a copy of the R code which I made to find this answer: library(foreign) setwd("~/Voting data") previousanswers <- read.csv("castle-solutions.csv") previousanswers <- previousanswers[,-11] #I'm not using the text comments, and they just make things harder to read. #Need 28+ points to win. previouswinner <- c(3,5,8,10,13,1,26,30,2,2) #I'm going to make a "predicted" dataset, baesd on the previous answers, the previous winner, and winning strategies against the previous winner and so on #The idea is that some people will copy the winner, some people will anticipate that and make a strategy which beats the winner #some people will anticipate that and make a strategy which beats the winner beater, etc., etc. #I'm going 4 layers deep on winner beating. I'm guessing a peek around 2-3. #Winning strategies should be able to soundly beat the strategy they are set against, while retaining #2+ in each castle. #There is some subjectivity going into these winnerb1 <- c(4,6,9,11,14,5,5,31,6,9) #This will beat the previous winner in castles 1,2,3,4,5,6,7,9,10, giving 47 points winnerb2 <- c(6,8,11,13,16,10,8,7,10,11) #This will beat b1 in all but castle 8 and beat the previous winner in all but 7 and 8. winnerb3 <- c(2,2,13,15,4,12,12,9,12,15) winnerb4 <- c(2,2,3,17,6,14,14,11,14,17) #Now to combine them together into one big data matrix previouswinnermatrix <- t(matrix(rep(previouswinner),10,nrow(previousanswers) * 0.20)) winnerb1matrix <- t(matrix(rep(winnerb1),10,nrow(previousanswers) * 0.15)) winnerb2matrix <- t(matrix(rep(winnerb2),10,nrow(previousanswers) * 0.22)) winnerb3matrix <- t(matrix(rep(winnerb3),10,nrow(previousanswers) * 0.20)) winnerb4matrix <- t(matrix(rep(winnerb4),10,nrow(previousanswers) * 0.10)) colnames(previouswinnermatrix) <- colnames(previousanswers) colnames(winnerb1matrix) <- colnames(previousanswers) colnames(winnerb2matrix) <- colnames(previousanswers) colnames(winnerb3matrix) <- colnames(previousanswers) colnames(winnerb4matrix) <- colnames(previousanswers) datamatrix <- rbind(previousanswers, previouswinnermatrix, winnerb1matrix, winnerb2matrix, winnerb3matrix, winnerb4matrix) #Now that I have my data, it's time to figure out what the expected number of points I can expect #from each castle, for each number of soldiars at that castle. expectedmatrix <- matrix(0,100,10) colnames(expectedmatrix) <- colnames(datamatrix) #Only 100 rows. I'm precluding strategies that include 0 people at any castle. #Now, to go by for each castle... for (i in 1:ncol(expectedmatrix)) { #...and go through each number of soldiers in that castle... for (j in 1:nrow(expectedmatrix)) { #And replace that value with the expected number of net wins with that number of people #+1 if win, 0 if tie, -1 if lose. expectedmatrix[j,i] <- (length(datamatrix[(datamatrix[,i] < j),i]) - length(datamatrix[(datamatrix[,i] > j),i])) / length(datamatrix[,i]) } #Multiple each column by the value of that castle, to get expected # of points expectedmatrix[,i] <- expectedmatrix[,i] * i } #Now, to make a looped function to continue taking away from the castle with the lowest expected loss #And giving to the castle with the highest expected gain #Until lowest loss > greatest gain strategy <- c(10,10,10,10,10,10,10,10,10,10) losses <- strategy gains <- strategy keepgoing <- TRUE while (keepgoing) { for (i in 1:10) { #calculte losses if (strategy[i] == 1) { losses[i] <- 10 } else { losses[i] <- expectedmatrix[strategy[i],i] - expectedmatrix[strategy[i]-1,i] } #calculate gains if (strategy[i] == 100) { gains[i] <- 0 } else { gains[i] <- expectedmatrix[strategy[i]+1,i] - expectedmatrix[strategy[i],i] } } #If the biggest gain and smallest loss are the same castle, break if (which.max(gains) == which.min(losses)) { keepgoing <- FALSE } else { #If the biggest gain is less than the smallest loss, break if (max(gains) < min(losses)) { keepgoing <- FALSE } else { #Otherwise, evolve the strategy. strategy[which.max(gains)] <- strategy[which.max(gains)] + 1 strategy[which.min(losses)] <- strategy[which.min(losses)] - 1 } } } #Cool, that was quick. #How many expected points can we get? expectednetpoints <- 0 for (i in 1:10) { expectednetpoints <- expectednetpoints + expectedmatrix[strategy[i],i] } #Based on the datamatrix I generated (which is dubious), this strategy will get 8.18 points more than a given opponent, on average.
Powered by Datasette · Queries took 12.364ms · Data license: CC Attribution 4.0 License · Data source: fivethirtyeight/data on GitHub · About: simonw/fivethirtyeight-datasette