C#
Your task is to write a program for SAT that appears to execute in polynomial time.
"Appears" is unnecessary. I can write a program that really does execute in polynomial time to solve SAT problems. This is quite straightforward in fact.
MEGA BONUS: If you write a SAT-solver that actually executes in polynomial time, you get a million dollars! But please use a spoiler tag anyway, so others can wonder about it.
Awesome. Please send me the million bucks. Seriously, I have a program right here that will solve SAT with polynomial runtime.
Let me start by stating that I'm going to solve a variation on the SAT problem. I'm going to demonstrate how to write a program that exhibits the unique solution of any 3-SAT problem. The valuation of each Boolean variable has to be unique for my solver to work.
We begin by declaring a few simple helper methods and types:
class MainClass
{
class T { }
class F { }
delegate void DT(T t);
delegate void DF(F f);
static void M(string name, DT dt)
{
System.Console.WriteLine(name + ": true");
dt(new T());
}
static void M(string name, DF df)
{
System.Console.WriteLine(name + ": false");
df(new F());
}
static T Or(T a1, T a2, T a3) { return new T(); }
static T Or(T a1, T a2, F a3) { return new T(); }
static T Or(T a1, F a2, T a3) { return new T(); }
static T Or(T a1, F a2, F a3) { return new T(); }
static T Or(F a1, T a2, T a3) { return new T(); }
static T Or(F a1, T a2, F a3) { return new T(); }
static T Or(F a1, F a2, T a3) { return new T(); }
static F Or(F a1, F a2, F a3) { return new F(); }
static T And(T a1, T a2) { return new T(); }
static F And(T a1, F a2) { return new F(); }
static F And(F a1, T a2) { return new F(); }
static F And(F a1, F a2) { return new F(); }
static F Not(T a) { return new F(); }
static T Not(F a) { return new T(); }
static void MustBeT(T t) { }
Now let's pick a 3-SAT problem to solve. Let's say
(!x3) &
(!x1) &
(x1 | x2 | x1) &
(x2 | x3 | x2)
Let's parenthesize that a bit more.
(!x3) & (
(!x1) & (
(x1 | x2 | x1) &
(x2 | x3 | x2)))
We encode that like this:
static void Main()
{
M("x1", x1 => M("x2", x2 => M("x3", x3 => MustBeT(
And(
Not(x3),
And(
Not(x1),
And(
Or(x1, x2, x1),
Or(x2, x3, x2))))))));
}
And sure enough when we run the program, we get a solution to 3-SAT in polynomial time. In fact the runtime is linear in the size of the problem!
x1: false
x2: true
x3: false
You said polynomial runtime. You said nothing about polynomial compile time. This program forces the C# compiler to try all possible type combinations for x1, x2 and x3, and choose the unique one that exhibits no type errors. The compiler does all the work, so the runtime doesn't have to. I first exhibited this interesting techinque on my blog in 2007: http://blogs.msdn.com/b/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx Note that of course this example shows that overload resolution in C# is at least NP-HARD. Whether it is NP-HARD or actually undecidable depends on certain subtle details in how type convertibility works in the presence of generic contravariance, but that's a subject for another day.
3
I'm voting to close this question as off-topic because underhanded challenges are no longer welcome on this site. http://meta.codegolf.stackexchange.com/a/8326/20469
– cat – 2016-04-15T14:19:14.050This question hits more than one closure criterion. Too broad: a problem which solves any problem in P meets the criteria. Too subjective and/or unclear: "appears to execute in polynomial time" is open to all kinds of interpretations. – Peter Taylor – 2014-03-17T16:21:20.760
Would it be better if we restrict problem choices to well-known NP problems, and remove the twist? I think appears to execute in polynomial time is what gives people flexibility for the popularity contest. – Jonathan Pullano – 2014-03-17T16:25:07.927
11It would be better if you restrict the problem domain, otherwise you invoke the cloud of uncertainty around what is "well-known". Why not pick a single NP-hard problem and focus on that? That has the advantage of leaving other such problems open to future questions along the same line. Several narrow questions can provide far more ongoing delight and entertainment to the site than one broad one. – Jonathan Van Matre – 2014-03-17T16:38:05.433
Fair enough. I'll edit shortly. – Jonathan Pullano – 2014-03-17T16:44:50.713
1Can't add comments yet... Eric Lippert's "solution" is of course a sleight of hand. The C# language requires the compiler to do all the work. So given a 3SAT problem, you can ask the C# compiler to solve it, which will take exponential time. With that done, the C# compiler generates a program that solves one instance of 3SAT in linear time. Now since the solution of any instance of any NP complete problem is either YES or NO, that's not really much of an achievement. – gnasher729 – 2014-03-18T08:57:11.240
9@gnasher729: I got the C# compiler to solve a SAT problem; I consider that to be a reasonably interesting achievement. – Eric Lippert – 2014-03-18T22:07:15.337
9It would be fun if someone accidentally solves SAT in polynomial time here. – Turion – 2014-03-19T16:06:27.907
please tag this code trolling – Tim Seguine – 2014-03-19T16:39:54.220
@Turion: S/He'd be recruited to the Laundry. – Peter - Reinstate Monica – 2014-03-20T11:43:46.967
fyi further inquiry there are P vs NP tags on cs.se & tcs.se. see also how not to solve P=?NP cs.se and math monster/many P vs NP refs/stackexchange questions
– vzn – 2014-03-21T20:19:18.8835@Turion decades of Research, millions in rewards and prizes and all the women and fame one could have - but the real motivation for solving P=NP will end up being this PCG challenge. – NothingsImpossible – 2014-03-22T00:20:37.373
Not thinking about the problem can sometimes make it easier. – Turion – 2014-03-22T01:06:58.803
@TimSeguine ...why? – Doorknob – 2014-03-23T22:22:35.160
Warhing: Do not do this in PHP. Everything is true if the PHP gods want it to be. – Tortoise – 2014-03-24T01:55:52.353
@NothingsImpossible: Women? Really? – SamB – 2014-03-24T17:57:32.880