Logic

But everyone has problem solving abilities, animals too. So when a job description says "must be a logical thinker", they're simply writing something redundantly?

Yes, most likely. Job adverts are often full of waffle, ambiguity concerning the soft skills/general attributes required from a candidate etc...

Take the parts you can quantify: specific skills, education requirements, years of experience required and all you'd have is a fairly terse list - they need to pad it out a bit.

Then again even these more specific parts can't necessarily be trusted as recruiters are prone to slipping in buzzwords they don't understand or just making up the entire job posting altogether in an effort to harvest CVs.

Bottom line is don't worry about it too much, as long as you've not lied on your CV then chances are you've got something they're interested in if invited for an interview.
 
The best option then would be to drive for 0.54 of a mile - taking 1.64 minutes costing £0.21 then walk for 0.46 of a mile - taking 8.28 minutes costing £0. Total time: 9.9 minutes and costing £0.21.

Or perhaps drive the 0.5 miles to the shop and leave the car there and walk back with a brisk jog for the last 64 metres (0.04 miles) thus saving more money without overly exterting oneself. :D

Thanks all. Got a better understanding of it especially after semi-pro's post. I was indeed asking the question in a more philisophical sense but I was looking for an answer that I could understand.

I have a puzzle for you (it's going to be a long night) in which I've modified the names to reduce the number of people trying to cheat.

The OcUK Bridge

Myself and 3 other OcUK members have got to get a bus that arrives in 17 minutes and they must all cross a bridge to get there. All four of us begin on the same side of the bridge. The bus won't wait!

It is night. There is one torch. A maximum of two people can cross at one time. Any party who crosses, either 1 or 2 people, must have the flashlight with them. The torch must be walked back and forth, it cannot be thrown, etc. Each OcUK member walks at a different speed. A pair must walk together at the rate of the slower man's pace:

Zbornak: - 1 minute to cross
Magnolia: - 2 minutes to cross
Pho: - 5 minutes to cross
Semi-Pro: - 10 minutes to cross

For example: if Zbornak and Semi-pro walk across first, 10 minutes have elapsed when they get to the other side of the bridge. If Zbornak then returns with the torch, a total of 20 minutes have passed and you have failed the mission.


Post how long it took you to figure out but don't post the answer. I'll post the answer later tonight. If you can't get it or can't be bothered, feel free to Google it but don't post the answer. I have to admit I couldn't get this after about 7-8 minutes of writing out possibilities but I'm not patient and in the end, I looked up the answer.
 
Post how long it took you to figure out but don't post the answer. I'll post the answer later tonight. If you can't get it or can't be bothered, feel free to Google it but don't post the answer. I have to admit I couldn't get this after about 7-8 minutes of writing out possibilities but I'm not patient and in the end, I looked up the answer.

I decided - in honour of this thread - to embrace logic and write a brute-force C# program to do it. Programming is pure logic :p.

SOLVED!
Time taken: 00:00:00.5240299 - Good luck beating that on paper :p
Iterations: 3805
Winning time: 17
Winning combo:

[Magnolia + Zbornak Crosses, 2]
[Zbornak Returns, 3]
[Semi-Pro + Pho Crosses, 13]
[Magnolia Returns, 15]
[Magnolia + Zbornak Crosses, 17]


Source (could be done better I'm sure):
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace U2_Problem
{
    class Program
    {
        static void Main()
        {
            var tries = 0;
            var startTime = DateTime.Now;

            SolverResult answer = null;            
            while (answer == null)
            {
                var crossResult = Task.Factory.StartNew<SolverResult>(new Solver().Solve).Result;

                if (crossResult.Time <= 17)
                    answer = crossResult;

                tries++;
            }

            Console.WriteLine("SOLVED!");
            Console.WriteLine("Time taken: {0}", DateTime.Now - startTime);
            Console.WriteLine("Iterations: {0}", tries);
            Console.WriteLine("Winning time: {0}", answer.Time);
            Console.WriteLine("Winning combo:{0}", Environment.NewLine);

            foreach (var move in answer.CrossOrder)
                Console.WriteLine(move);
        }
    }

    public class SolverResult
    {
        public List<KeyValuePair<string, int>> CrossOrder { get; set; }
        public int Time { get; set; }
    }

    class Solver
    {
        private readonly Dictionary<string, int> _peopleWaitingToCross;
        private readonly Dictionary<string, int> _peopleCrossed;
        
        readonly Random _random = new Random();

        public Solver()
        {
            _peopleWaitingToCross = new Dictionary<string, int> {{"Zbornak", 1}, {"Magnolia", 2}, {"Pho", 5}, {"Semi-Pro", 10}};
            _peopleCrossed = new Dictionary<string, int>();
        }

        public SolverResult Solve()
        {
            var crossOrder = new List<KeyValuePair<string, int>>();
            var totalTime = 0;

            while (_peopleWaitingToCross.Any())
            {
                // Take two random people
                var p1 = TakeRandomPerson(_peopleWaitingToCross);
                var p2 = TakeRandomPerson(_peopleWaitingToCross);

                // Cross them
                AddToCrossed(p1);
                AddToCrossed(p2);
                totalTime += GetSingleCrossTime(p1, p2);

                crossOrder.Add(new KeyValuePair<string, int>(string.Format("{0} + {1} Crosses", p1.Key, p2.Key), totalTime));
                

                // If no one left we're done
                if (_peopleWaitingToCross.Count == 0)
                    break;

                // Cross someone back if people are left
                var personToCrossBack = TakeRandomPerson(_peopleCrossed);
                AddToWaiting(personToCrossBack);
                totalTime += personToCrossBack.Value;
                crossOrder.Add(new KeyValuePair<string, int>(string.Format("{0} Returns", personToCrossBack.Key), totalTime));
            }

            return new SolverResult { CrossOrder = crossOrder, Time = totalTime };
        }

        private static int GetSingleCrossTime(KeyValuePair<string, int> pesron1, KeyValuePair<string, int> person2)
        {
            return pesron1.Value > person2.Value ? pesron1.Value : person2.Value;
        }

        private KeyValuePair<string, int> TakeRandomPerson(IDictionary<string, int> source)
        {
            var person = source.ElementAt(_random.Next(source.Count));
            source.Remove(person.Key);

            return person;
        }

        private void AddToWaiting(KeyValuePair<string, int> person)
        {
            _peopleWaitingToCross.Add(person.Key, person.Value);
        }

        private void AddToCrossed(KeyValuePair<string, int> person)
        {
            _peopleCrossed.Add(person.Key, person.Value);
        }
    }
}
http://pastebin.com/Lp9ZPmfd

Took far too long but was a good test :o.
 
I decided - in honour of this thread - to embrace logic and write a brute-force C# program to do it. Programming is pure logic :p.

SOLVED!
Time taken: 00:00:00.5240299 - Good luck beating that on paper :p
Iterations: 3805
Winning time: 17
Winning combo:

[Magnolia + Zbornak Crosses, 2]
[Zbornak Returns, 3]
[Semi-Pro + Pho Crosses, 13]
[Magnolia Returns, 15]
[Magnolia + Zbornak Crosses, 17]

Took far too long but was a good test :o.

Do you work for GCHQ or something? Nice one. Correct! There's another solution which leaves the total time at 15 minutes.

Although you left a clue in your code which leaves me to believe you've seen this problem before or you looked it up to find more information...
 
Do you work for GCHQ or something? Nice one. Correct! There's another solution which leaves the total time at 15 minutes.

?

Looks like there are just two solutions which are both similar and both result in 17 minutes.

i.e. take the two fast guys cross (the 1 min + 2 min guys), leave one of them there, bring the other back send both the slow guys together (5 min + 10 min guys) then bring the fast guy back that you left originally and send both fast guys over again.

so either

2 mins + 1 min + 10 mins + 2 mins + 2 mins

or

2 mins + 2 mins + 10 mins + 1 min + 2 mins

would be interested in seeing the 15 minute solution

edit - I really don't think there is a 15 min solution
 
Last edited:
A logical approach.

An illogical approach would be throwing piles of unresearched ingredients into an oven going on intuition, and hoping something cake shaped came out.

hey it may be illogical but how do you think we got the first cake :p


go for it op, throw crap in an oven till you invent new cake :D
 
I decided - in honour of this thread - to embrace logic and write a brute-force C# program to do it. Programming is pure logic :p.

SOLVED!
Time taken: 00:00:00.5240299 - Good luck beating that on paper :p
Iterations: 3805
Winning time: 17
Winning combo:

[Magnolia + Zbornak Crosses, 2]
[Zbornak Returns, 3]
[Semi-Pro + Pho Crosses, 13]
[Magnolia Returns, 15]
[Magnolia + Zbornak Crosses, 17]


Source (could be done better I'm sure):
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace U2_Problem
{
    class Program
    {
        static void Main()
        {
            var tries = 0;
            var startTime = DateTime.Now;

            SolverResult answer = null;            
            while (answer == null)
            {
                var crossResult = Task.Factory.StartNew<SolverResult>(new Solver().Solve).Result;

                if (crossResult.Time <= 17)
                    answer = crossResult;

                tries++;
            }

            Console.WriteLine("SOLVED!");
            Console.WriteLine("Time taken: {0}", DateTime.Now - startTime);
            Console.WriteLine("Iterations: {0}", tries);
            Console.WriteLine("Winning time: {0}", answer.Time);
            Console.WriteLine("Winning combo:{0}", Environment.NewLine);

            foreach (var move in answer.CrossOrder)
                Console.WriteLine(move);
        }
    }

    public class SolverResult
    {
        public List<KeyValuePair<string, int>> CrossOrder { get; set; }
        public int Time { get; set; }
    }

    class Solver
    {
        private readonly Dictionary<string, int> _peopleWaitingToCross;
        private readonly Dictionary<string, int> _peopleCrossed;
        
        readonly Random _random = new Random();

        public Solver()
        {
            _peopleWaitingToCross = new Dictionary<string, int> {{"Zbornak", 1}, {"Magnolia", 2}, {"Pho", 5}, {"Semi-Pro", 10}};
            _peopleCrossed = new Dictionary<string, int>();
        }

        public SolverResult Solve()
        {
            var crossOrder = new List<KeyValuePair<string, int>>();
            var totalTime = 0;

            while (_peopleWaitingToCross.Any())
            {
                // Take two random people
                var p1 = TakeRandomPerson(_peopleWaitingToCross);
                var p2 = TakeRandomPerson(_peopleWaitingToCross);

                // Cross them
                AddToCrossed(p1);
                AddToCrossed(p2);
                totalTime += GetSingleCrossTime(p1, p2);

                crossOrder.Add(new KeyValuePair<string, int>(string.Format("{0} + {1} Crosses", p1.Key, p2.Key), totalTime));
                

                // If no one left we're done
                if (_peopleWaitingToCross.Count == 0)
                    break;

                // Cross someone back if people are left
                var personToCrossBack = TakeRandomPerson(_peopleCrossed);
                AddToWaiting(personToCrossBack);
                totalTime += personToCrossBack.Value;
                crossOrder.Add(new KeyValuePair<string, int>(string.Format("{0} Returns", personToCrossBack.Key), totalTime));
            }

            return new SolverResult { CrossOrder = crossOrder, Time = totalTime };
        }

        private static int GetSingleCrossTime(KeyValuePair<string, int> pesron1, KeyValuePair<string, int> person2)
        {
            return pesron1.Value > person2.Value ? pesron1.Value : person2.Value;
        }

        private KeyValuePair<string, int> TakeRandomPerson(IDictionary<string, int> source)
        {
            var person = source.ElementAt(_random.Next(source.Count));
            source.Remove(person.Key);

            return person;
        }

        private void AddToWaiting(KeyValuePair<string, int> person)
        {
            _peopleWaitingToCross.Add(person.Key, person.Value);
        }

        private void AddToCrossed(KeyValuePair<string, int> person)
        {
            _peopleCrossed.Add(person.Key, person.Value);
        }
    }
}
http://pastebin.com/Lp9ZPmfd

Took far too long but was a good test :o.

I love you :D
 
I decided - in honour of this thread - to embrace logic and write a brute-force C# program to do it. Programming is pure logic :p.

SOLVED!
Time taken: 00:00:00.5240299 - Good luck beating that on paper :p
Iterations: 3805
Winning time: 17
Winning combo:

[Magnolia + Zbornak Crosses, 2]
[Zbornak Returns, 3]
[Semi-Pro + Pho Crosses, 13]
[Magnolia Returns, 15]
[Magnolia + Zbornak Crosses, 17]


Source (could be done better I'm sure):

http://pastebin.com/Lp9ZPmfd

Took far too long but was a good test :o.

Isn't that actually the exact opposite of logic?

i.e instead of logically thinking about it you did it by trial and error, and so instead of taking 1 iteration you took over 3 thousand?
 
?
edit - I really don't think there is a 15 min solution

My apologies you're absouletly right. I'm thinking of a variation of the problem where the timings are slightly different.

hey it may be illogical but how do you think we got the first cake :p


go for it op, throw crap in an oven till you invent new cake :D

The odds suggest I'd have a house fire before I make an edible cake.

Isn't that actually the exact opposite of logic?

i.e instead of logically thinking about it you did it by trial and error, and so instead of taking 1 iteration you took over 3 thousand?

I can see your thinking, but the solution would never take one iteration. It would take multiple tries.

There has to be a logical explanation for this.

There is actually no explanation for this. <grabs beer>
 
I can see your thinking, but the solution would never take one iteration. It would take multiple tries.

true 1 would be quite optimistic, but the idea of logically thinking is you find the answer without exhausting every possible variation :p
 
Do you work for GCHQ or something? Nice one. Correct! There's another solution which leaves the total time at 15 minutes.

Although you left a clue in your code which leaves me to believe you've seen this problem before or you looked it up to find more information...

I can't acknowledge or deny whether I work for GCHQ :p.

I Googled the question to make sure it wasn't a joke one and saw it was also known as the U2 problem that's all.

I left it running for a minute or so which did 788,996 tries and it didn't find any solutions for 15 minutes so it's probably not possible.


Isn't that actually the exact opposite of logic?

i.e instead of logically thinking about it you did it by trial and error, and so instead of taking 1 iteration you took over 3 thousand?

True, but I used programming which uses logical statements to solve it :p.

Because it was brute force and random it could easily do it in 10 thousand tries or it might do it in 1 - was just luck.

Here's a revised algorithm then, it takes 1 iteration to solve it by initially taking the quickest two people (1+2) then from that taking the fastest person (1 in this case) back again so it leaves a quick person on either side. It then carries on taking the slowest people over together (e.g. 5+10) which minimises the amount of lost time - taking 1+5 then 1+10 would be 15, losing 5 minutes.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace U2_Problem
{
    class Program
    {
        static void Main()
        {
            var tries = 0;
            var startTime = DateTime.Now;

            SolverResult answer = null;            
            while (answer == null)
            {
                var crossResult = Task.Factory.StartNew<SolverResult>(new Solver().Solve).Result;

                if (crossResult.Time <= 17)
                    answer = crossResult;

                tries++;
            }

            Console.WriteLine("SOLVED!");
            Console.WriteLine("Time taken: {0}", DateTime.Now - startTime);
            Console.WriteLine("Iterations: {0}", tries);
            Console.WriteLine("Winning time: {0}", answer.Time);
            Console.WriteLine("Winning combo:{0}", Environment.NewLine);

            foreach (var move in answer.CrossOrder)
                Console.WriteLine(move);
        }
    }

    public class SolverResult
    {
        public List<KeyValuePair<string, int>> CrossOrder { get; set; }
        public int Time { get; set; }
    }

    class Solver
    {
        private readonly Dictionary<string, int> _peopleWaitingToCross;
        private readonly Dictionary<string, int> _peopleCrossed;
        
        readonly Random _random = new Random();

        public Solver()
        {
            _peopleWaitingToCross = new Dictionary<string, int> {{"Zbornak", 1}, {"Magnolia", 2}, {"Pho", 5}, {"Semi-Pro", 10}};
            _peopleCrossed = new Dictionary<string, int>();
        }

        public SolverResult Solve()
        {
            var crossOrder = new List<KeyValuePair<string, int>>();
            var totalTime = 0;

            while (_peopleWaitingToCross.Any())
            {
                // Take quickest people the first time to leave a fast person on either side of the bridge
                // then continue to take the slowest two people to minimise cross time loss
                // e.g. taking 5+10 together = 10 total whereas taking 1+5 then 1+10 = 15
                var p1 = totalTime == 0 ? TakeFastestPerson(_peopleWaitingToCross) : TakeSlowestPerson(_peopleWaitingToCross);
                var p2 = totalTime == 0 ? TakeFastestPerson(_peopleWaitingToCross) : TakeSlowestPerson(_peopleWaitingToCross);

                // Cross them
                AddToCrossed(p1);
                AddToCrossed(p2);
                totalTime += GetSingleCrossTime(p1, p2);

                crossOrder.Add(new KeyValuePair<string, int>(string.Format("{0} + {1} Crosses", p1.Key, p2.Key), totalTime));
                

                // If no one left we're done
                if (_peopleWaitingToCross.Count == 0)
                    break;

                // Cross fastest person back if people are left
                var personToCrossBack = TakeFastestPerson(_peopleCrossed);
                AddToWaiting(personToCrossBack);
                totalTime += personToCrossBack.Value;
                crossOrder.Add(new KeyValuePair<string, int>(string.Format("{0} Returns", personToCrossBack.Key), totalTime));
            }

            return new SolverResult { CrossOrder = crossOrder, Time = totalTime };
        }

        private static int GetSingleCrossTime(KeyValuePair<string, int> pesron1, KeyValuePair<string, int> person2)
        {
            return pesron1.Value > person2.Value ? pesron1.Value : person2.Value;
        }

        private KeyValuePair<string, int> TakeRandomPerson(IDictionary<string, int> source)
        {
            var person = source.ElementAt(_random.Next(source.Count));
            source.Remove(person.Key);

            return person;
        }

        private KeyValuePair<string, int> TakeFastestPerson(IDictionary<string, int> source)
        {
            var person = source.OrderBy(o => o.Value).First();
            source.Remove(person.Key);

            return person;
        }

        private KeyValuePair<string, int> TakeSlowestPerson(IDictionary<string, int> source)
        {
            var person = source.OrderByDescending(o => o.Value).First();
            source.Remove(person.Key);

            return person;
        }

        private void AddToWaiting(KeyValuePair<string, int> person)
        {
            _peopleWaitingToCross.Add(person.Key, person.Value);
        }

        private void AddToCrossed(KeyValuePair<string, int> person)
        {
            _peopleCrossed.Add(person.Key, person.Value);
        }
    }
}
http://pastebin.com/v4Eshgwf

Better? :p
 
With the bridge problem, there is a nice logical way to think about it.

Lets rename the people as letters to make things easier:
A takes 1 minute
B takes 2 minutes
C takes 5 minutes
D takes 10 minutes

We need to get four people from one side to the other.
The first trip takes two people across, and then each round trip after that adds another person, so 5 trips across the bridge are needed.

If C & D travel separately then this eats up 15 minutes, with 3 other trips needed (which will take a minimum of 3 minutes) so they must travel together in one trip, which takes 10 minutes.
This leaves 4 trips needed in 7 minutes.

So, if C & D must travel together A & B need to take the first trip to ensure that there is someone fast to come back with the torch.
This takes 2 minutes.
Now, either A or B can come back.
Lets assume B comes back in a further 2 minutes.

At this point A is across the bridge
B, C & D are not and 4 minutes have gone.

Now we've already said that C & D must travel together, so they go across the bridge in 10 minutes.

Time taken is now 14 minutes.

A comes back in 1 minute. We're up to 15 minutes.
A & B go across again in 2 minutes.

Everyone is across the bridge and 17 minutes have gone.

All of this can easily be derived once we figure out that C & D must cross together.
 
Interesting way of working it out :). I never tend to have the patience with these things :D.
 
Back
Top Bottom