Разгадать загадку Эйнштейна


19

Эйнштейн написал загадку. Он сказал, что 98% мира не могут решить это.

Я разгадал эту загадку примерно за 25 минут на поезде на работу. Это в основном просто дедукция.

Загадка

Есть 5 домов в 5 разных цветах в ряд.
В каждом доме живет человек с разной национальностью.
5 владельцев пьют определенный тип напитка, курят сигары определенной марки и содержат определенного питомца.
Ни один владелец не имеет одного и того же домашнего питомца, не курит одну и ту же марку сигары и не пьет один и тот же напиток.
Вопрос: кому принадлежит рыба?

Чтобы решить эту загадку, Эйнштейн предлагает 15 подсказок:

  1. Британец живет в красном доме.
  2. Швед держит собак в качестве домашних животных.
  3. Датчанин пьет чай.
  4. Зеленый дом находится слева от белого дома.
  5. Владелец зеленого дома пьет кофе.
  6. Владелец, который курит Pall Mall, выращивает птиц.
  7. Хозяин желтого дома курит Данхилл.
  8. Хозяин, живущий в центре дома, пьет молоко.
  9. Норвежец живет в первом доме.
  10. Хозяин, который курит смесь, живет рядом с тем, кто держит кошек.
  11. Владелец, который держит лошадь, живет рядом с тем, кто курит Dunhill.
  12. Владелец, который курит Bluemasters, пьет пиво.
  13. Немец курит принц.
  14. Норвежец живет рядом с синим домом.
  15. Владелец, который курит смесь, живет рядом с тем, кто пьет воду.

С этими подсказками вы можете прийти к решению.

Ваша задача: составить программу, которая решит эту загадку для вас. Жесткое кодирование решения не допускается (да)

Допускается жестко кодировать подсказки в любом формате.
Пример формата:

//Hints in order
(Nationality:Brit)==(Color:Red)
(Nationality:Swede)==(Pet:Dogs)
(Nationality:Dane)==(Drink: Tea)
(Color:Green)/(Color:White)
(Color:Green)==(Drink:Coffee)
(Smoke:PallMall)==(Pet:Birds)
(Color:Yellow)==(Smoke:Dunhill)
(House:3)==(Drink:Milk)
(Nationality:Norwegian)==(House:1)
(Smoke:Blend)/\(Pet:Cats)

== означает равно
/ означает слева от
\ означает справа от
/ \ означает слева или справа от

Как я уже сказал, он позволяет либо жестко задавать подсказки, либо использовать их в качестве входных данных.

Вывод: Вывод должен быть в следующем формате (с правильными значениями, просто говоря для троллей;))

 _____________    _____________    _____________    _____________    _____________
|   Number    |  |   Number    |  |   Number    |  |   Number    |  |   Number    |
| Nationality |  | Nationality |  | Nationality |  | Nationality |  | Nationality |
|    Color    |  |    Color    |  |    Color    |  |    Color    |  |    Color    |
|    Drink    |  |    Drink    |  |    Drink    |  |    Drink    |  |    Drink    |
|    Smoke    |  |    Smoke    |  |    Smoke    |  |    Smoke    |  |    Smoke    |
|     Pet     |  |     Pet     |  |     Pet     |  |     Pet     |  |     Pet     |
---------------  ---------------  ---------------  ---------------  ---------------

The <Nationality> in the <Color> house owns the fish!

Ящики Ascii art могут быть изменены вами, если они являются коробками, независимо от того, какие символы вы используете.

Любые знания по этой загадке и решению не могут быть использованы в программе. Он должен использовать чистую логику и дедукцию, чтобы разгадать загадку.

Помечено как codegolf, но может быть проблемой кода, не уверен. Любые мысли о критериях выигрыша для вызова кода не стесняйтесь поделиться :)

На данный момент это code-golf, поэтому программа с самым низким числом выигрышей.

Удачи и Счастливого кодирования :)


15
Утверждения первого абзаца почти наверняка ложны.
Питер Тейлор

1
@PeterTaylor Что ты имеешь в виду? 98% и Эйнштейн немного? Не знал бы это наверняка, межсетевые говорят это, и независимо от того, это забавно для фона :), я чувствовал себя особенным, когда я решил это, "да, я в тех 2%"
Teun Pronk

4
Оба этих бита. В этих веб-сетях также есть Timecube, поэтому вам не советуют верить всему, что они говорят, особенно если они не приводят никаких доказательств.
Питер Тейлор

1
@PeterTaylor Да, я знаю, но, как я уже сказал, в любом случае это забавно для фона и не похоже на факт или вымысел, существенный для данной проблемы. Также в Википедии говорится, что нет реальных доказательств этого :)
Теун Пронк

3
Я думаю, что решения должны иметь возможность обобщать произвольное количество домов, свойств и подсказок. Тогда это был бы по-настоящему интересный вопрос, который вам, как правило, не пришлось бы вставлять без всякого жесткого кода. Что в моем опыте всегда приводит к вопросу о том, насколько это действительно жестко.
Cruncher

Ответы:


24

Пролог - 954 персонажа

m(A,Z):-member(A,Z).
e:-e(Z),w(Z).
e(Z):-Z=[[1,A,F,K,P,U],[2,B,G,L,Q,V],[3,C,H,M,R,W],[4,D,I,N,S,X],[5,E,J,O,T,Y]],m([_,b,r,_,_,_],Z),m([_,s,_,d,_,_],Z),m([_,d,_,_,t,_],Z),m([WH,_,w,_,_,_],Z),m([GH,_,g,_,_,_],Z),GH=:=WH-1,m([_,_,g,_,c,_],Z),m([_,_,_,b,_,p],Z),m([_,_,y,_,_,d],Z),m([3,_,_,_,m,_],Z),m([1,n,_,_,_,_],Z),m([BH,_,_,_,_,b],Z),m([CH,_,_,c,_,_],Z),(BH=:=CH+1;BH=:=CH-1),m([DH,_,_,_,_,d],Z),m([HH,_,_,h,_,_],Z),(HH=:=DH+1;HH=:=DH-1),m([_,_,_,_,b,l],Z),m([_,g,_,_,_,r],Z),m([NH,n,_,_,_,_],Z),m([YH,_,b,_,_,_],Z),(NH=:=YH+1;NH=:=YH-1),m([SH,_,_,_,_,b],Z),m([XH,_,_,_,w,_],Z),(SH=:=XH+1;SH=:=XH-1),p([n,d,b,g,s],[A,B,C,D,E]),p([y,b,r,g,w],[F,G,H,I,J]),p([c,h,b,f,d],[K,L,M,N,O]),p([w,t,m,c,b],[P,Q,R,S,T]),p([d,b,p,r,l],[U,V,W,X,Y]).
t(X,[X|R],R).
t(X,[F|R],[F|S]):-t(X,R,S).
p([W|X],Y):-p(X,V),t(W,Y,V).
p([],[]).
b:-write('+--+--+--+--+--+--+'),nl.
z(A):-writef('|%2L|%2L|%2L|%2L|%2L|%2L|',A),nl.
w([A,B,C,D,E]):-b,z(A),z(B),z(C),z(D),z(E),b.

Выход

+--+--+--+--+--+--+
|1 |n |y |c |w |d |
|2 |d |b |h |t |b |
|3 |b |r |b |m |p |
|4 |g |g |f |c |r |
|5 |s |w |d |b |l |
+--+--+--+--+--+--+

Ключ:

  • Первый столбец - номер дома;
  • Вторая колонка - национальность;
  • Третий столбец - любимый цвет;
  • Четвертая колонка - домашнее животное;
  • Пятая колонна - напиток; и
  • Шестая колонка - сигарета (r = принц, l = bluemaster).

9
Это правильный язык для работы.
Маринус

Разве вы не должны произносить названия, чтобы сделать номера для гольфа сопоставимыми?
blabla999

5

Ruby 322 + вход 442

Перебор почти 25 миллиардов возможных ответов.
Мой компьютер может занять около 75 дней, чтобы запустить эту программу.
Я никогда не проверял, печатает ли эта программа правильный ответ!

Беги как ruby riddle.rb < riddle.in

riddle.rb (332 байта)

g=readlines
v=g.shift(5).map &:split
c,*d=v.map{|a|[*a.permutation]}
c.product(*d){|a|(f=eval a.map{|b|b.each_with_index.map{|s,i|"#{s}=#{i}\n"}.join}.join+'g.map{|h|eval h}.all?&&fish')&&(r=['-----------']*5
puts [r,[*0..4],*a,r].map{|s|s.map{|t|'|%11s|'%t}.join},"The #{a[0][f]} in the #{a[1][f]} house owns the fish!")}

riddle.in (442 байта)

brit dane german norwegian swede
blue green red white yellow
beer coffee milk tea water
blends bluemasters dunhill pall_mall prince
birds cats dogs fish horse
brit==red
swede==dogs
dane==tea
green==white-1
green==coffee
pall_mall==birds
yellow==dunhill
2==milk
norwegian==0
blends==cats-1||blends==cats+1
horse==dunhill-1||horse==dunhill+1
bluemasters==beer
german==prince
norwegian==blue-1||norwegian==blue+1
blends==water-1||blends==water+1

Входной файл должен содержать 5 строк имен, за которыми следуют строки логических выражений. Номера домов от 0 до 4. Должны быть fish.

Программа звонит Array#permutationпять раз, чтобы найти все способы заказа массивов национальностей, цветов, напитков, курения и домашних животных. Длинный цикл состоит в том c.product(*d){|a|...}, Array#productчтобы вызвать итерацию почти 25 миллиардов возможных ответов. Тело цикла имеет форму (f=eval ...)&&(...). eval ...Часть оценивает логические выражения. Если все верно, то fэто номер дома рыбы, и &&(...)часть печатает ответ. Дом № 0 это правда в Руби.

Код гольф означает не добавлять код для скорости! Но мне не хватает 75 дней, чтобы запустить программу!


1
Даже использование одной или двух улик вместо грубой силы спасло бы много поисков.
QWR

Я не знаю Ruby, но Интернет говорит, что он медленный . Могу поспорить, что если вы перевели свой ответ на скомпилированный язык, а затем даже немного его оптимизировали, вы могли бы приблизиться (r?) К ускорению на 5000%, которое необходимо для проверки правильности в разумные сроки. Если бы вы написали даже самый грубый, но хорошо документированный перевод на Java, я был бы рад оптимизировать его для вас, а затем проверить правильность.
Rainbolt

4

Пролог, 653 персонажа

a([],L,L).
a([H|T],L2,[H|L3]):-a(T,L2,L3).
m(X,L):-a(_,[X|_],L).
r(X,Y,L):-a(_,[X,Y|_],L).
n(X,Y,L):-r(X,Y,L);r(Y,X,L).
s:-s(S),w(S).
s(S):-length(S,5),m([b,r,_,_,_],S),m([s,_,_,_,d],S),m([d,_,t,_,_],S),r([_,g,_,_,_],[_,w,_,_,_],S),m([_,g,c,_,_],S),m([_,_,_,p,b],S),m([_,y,_,d,_],S),S=[_,_,[_,_,m,_,_],_,_],S=[[n,_,_,_,_],_,_,_,_],n([_,_,_,b,_],[_,_,_,_,c],S),n([_,_,_,d,_],[_,_,_,_,h],S),m([_,_,b,l,_],S),m([g,_,_,r,_],S),n([n,_,_,_,_],[_,b,_,_,_],S),n([_,_,_,b,_],[_,_,w,_,_],S),m([_,_,_,_,f],S).
b:-write('----------------+'),nl.
z(Y,A):-write(Y),writef('|%2L|%2L|%2L|%2L|%2L|',A),nl.
w([S1,S2,S3,S4,S5]):-b,z(1,S1),z(2,S2),z(3,S3),z(4,S4),z(5,S5),b.

1
Я взял на себя смелость удалять ненужные пробелы и разрывы строк в вашем коде, что сокращает его до 653 символов.
Фатализировать

1
Проверено на SWI-Прологе, Просто наберите? - s.
ej8000

3

Smalltalk 1332 символа

Используя простой Smalltalk:

|n c v g p t r|n:=#(Brit Swede Dane Norwegian German
Red Green White Yellow Blue
Tea Coffee Milk Beer Water
PallMall Dunhill Blends Bluemasters Prince
Dogs Birds Cats Horses Fish).
v:=Dictionary new.n do:[:n|v at:n put:nil].g:=n splitForSize:5.
c:={{[:b :r|b==r].#Brit.#Red}.{[:s :d|s==d].#Swede.#Dogs}.{[:d :t|d==t].#Dane.#Tea}.
{[:g :w|g==(w-1)].#Green.#White}.{[:g :c|g==c].#Green.#Coffee}.
{[:p :b|p==b].#PallMall.#Birds}.{[:y :d|y==d].#Yellow.#Dunhill}.
{[:m|m==3].#Milk}.{[:n|n==1].#Norwegian}.{[:b :c|(b-c)abs==1].#Blends.#Cats}.
{[:h :d|(h-d)abs==1].#Horses.#Dunhill}.{[:m :b|m==b].#Bluemasters.#Beer}.
{[:g :p|g==p].#German.#Prince}.{[:n :b|(n-b)abs==1].#Norwegian.#Blue}.
{[:b :w|(b-w)abs==1].#Blends.#Water}}.
t:=[:c|x:=(c from:2collect:[:n|v at:n]).(x includes:nil)or:[c first valueWithArguments:x]].
p:=[|f|(((''-'',* 16),'' ''),*5)printCR.g do:[:n||w|w:=n collect:[:n|v at:n].w sortWith:n.
n do:[:n|''|''print.(n centerPaddedTo:14)print.''| ''print].''''printCR.].(((''-'',* 16),'' ''),*5)printCR.
f:=v at:#Fish.(''The %1 in the %2 house owns the fish''bindWith:(g first detect:[:n|(v at:n)==f])with:((g at:2) detect:[:n|(v at:n)==f]))printCR].
r:=[:gi|gi==0ifTrue:p ifFalse:[#(1 2 3 4 5)permutationsDo:[:perm|v declareAll:(g at:gi)from:perm.
(c conform:t)ifTrue:[r value:gi-1]].v declareAll:(g at:gi)from:#(nil),*5]].
r value:g size.

Выход:

---------------- ---------------- ---------------- ---------------- ---------------- 
|  Norwegian   | |     Dane     | |     Brit     | |    German    | |    Swede     | 
|    Yellow    | |     Blue     | |     Red      | |    Green     | |    White     | 
|    Water     | |     Tea      | |     Milk     | |    Coffee    | |     Beer     | 
|   Dunhill    | |    Blends    | |   PallMall   | |    Prince    | | Bluemasters  | 
|     Cats     | |    Horses    | |    Birds     | |     Fish     | |     Dogs     | 
---------------- ---------------- ---------------- ---------------- ----------------
The German in the Green house owns the fish

Поскольку версия для гольфа почти не читается, вот код разработчика с собственными именами, отступами и пробелами для удобства чтения:

|names constraints foundSolution v groups printSolution testC test try|

names := #(Brit Swede Dane Norwegian German
 Red Green White Yellow Blue
 Tea Coffee Milk Beer Water
 PallMall Dunhill Blends Bluemasters Prince
 Dogs Birds Cats Horses Fish).

v := Dictionary new.
names do:[:n | v at:n put:nil].
groups := names splitForSize:5.

constraints := {
        {[:b :r | b==r] . #Brit . #Red   }.          "/ The Brit lives in the red house.
        {[:s :d | s==d] . #Swede . #Dogs }.          "/ The Swede keeps dogs as pets.
        {[:d :t | d==t] . #Dane . #Tea   }.          "/ The Dane drinks tea.
        {[:g :w | g==(w-1)] . #Green . #White }.     "/ The green house is on the immediate left of the white house.
        {[:g :c | g==c] . #Green . #Coffee}.         "/ The green house's owner drinks coffee.
        {[:p :b | p==b] . #PallMall . #Birds}.       "/ The owner who smokes Pall Mall rears birds.
        {[:y :d | y==d] . #Yellow . #Dunhill}.       "/ The owner of the yellow house smokes Dunhill.
        {[:m | m==3] . #Milk}.                       "/ The owner living in the center house drinks milk.
        {[:n | n==1] . #Norwegian }.                 "/ The Norwegian lives in the first house.
        {[:b :c | (b-c)abs==1] . #Blends . #Cats}.   "/ The owner who smokes Blends lives next to the one who keeps cats.
        {[:h :d | (h-d)abs==1] . #Horses . #Dunhill}."/ The owner who keeps the horse lives next to the one who smokes Dunhill.
        {[:m :b | m==b] . #Bluemasters . #Beer}.     "/ The owner who smokes Bluemasters drinks beer.
        {[:g :p | g==p] . #German . #Prince}.        "/ The German smokes Prince.
        {[:n :b | (n-b)abs==1] . #Norwegian . #Blue}."/ The Norwegian lives next to the blue house.
        {[:b :w | (b-w)abs==1] . #Blends . #Water}.  "/ The owner who smokes Blends lives next to the one who drinks water.
}.
testC := [:c | vi:=((c from:2) collect:[:n|v at:n]). (vi includes:nil) or:[c first valueWithArguments:vi]].
test := [constraints conform:testC].

printSolution :=
 [  |f|
    ((('-',* 16),' '),*5) printCR.
    groups do:[:names|
         |values|
         values := names collect:[:nm|v at:nm].
         values sortWith:names.
         names do:[:n| '|'print. (n centerPaddedTo:14)print.'| ' print].
         '' printCR.
    ].
    ((('-',* 16),' '),*5) printCR.
    f := v at:#Fish.
    ('The %1 in the %2 house owns the fish'
        bindWith:((groups at:1) detect:[:n|(v at:n)==f])
        with:((groups at:2) detect:[:n|(v at:n)==f]))printCR
 ].


try := [:gi |
    gi == 0 
     ifTrue: printSolution
     ifFalse:[
        (1 to:5) asArray permutationsDo:[:perm |
            v declareAll:(groups at:gi) from:perm.
            test value ifTrue:[
                try value:(gi-1).
            ].
        ].
        v declareAll:(groups at:gi) from:#(nil nil nil nil nil).
    ].
].
try value:groups size.

Использование библиотеки решателя ограничений:

Использование библиотеки решателя ограничений, которая очень похожа на ту, что описана в руководстве OZ / Mozart. Как я ожидаю, вы пожалуетесь, что это не относится к конкурсу ;-), оно добавлено только для вашего удовольствия и вдохновения (ищите пакет с противопоказаниями на вашем языке), без гольфа и без учета символов.

|solution|

solution := Solver
    anySolutionFor:[
        |Brit Swede Dane Norwegian German
         Red Green White Yellow Blue
         PallMall Dunhill Prince Blends Bluemasters
         Tea Coffee Water Beer Milk
         Dogs Birds Cats Horses Fish|

        Brit        := (1 %% 5) name:#Brit.
        Swede       := (1 %% 5) name:#Swede.
        Dane        := (1 %% 5) name:#Dane.
        Norwegian   := (1 %% 5) name:#Norwegian.
        German      := (1 %% 5) name:#German.

        Red     := (1 %% 5) name:#Red.
        Green   := (1 %% 5) name:#Green.
        White   := (1 %% 5) name:#White.
        Yellow  := (1 %% 5) name:#Yellow.
        Blue    := (1 %% 5) name:#Blue.

        PallMall     := (1 %% 5) name:#PallMall.
        Dunhill      := (1 %% 5) name:#Dunhill.
        Prince       := (1 %% 5) name:#Prince.
        Blends       := (1 %% 5) name:#Blends.
        Bluemasters  := (1 %% 5) name:#Bluemasters.

        Tea    := (1 %% 5) name:#Tea.
        Coffee := (1 %% 5) name:#Coffee.
        Milk   := (1 %% 5) name:#Milk.
        Water  := (1 %% 5) name:#Water.
        Beer   := (1 %% 5) name:#Beer.

        Dogs         := (1 %% 5) name:#Dogs.
        Birds        := (1 %% 5) name:#Birds.
        Cats         := (1 %% 5) name:#Cats.
        Horses       := (1 %% 5) name:#Horses.
        Fish         := (1 %% 5) name:#Fish.

        Solver allDistinct:{ Brit . Swede . Dane . Norwegian . German. }.
        Solver allDistinct:{ Red. Green. White. Yellow. Blue. }.
        Solver allDistinct:{ PallMall. Dunhill. Prince. Blends. Bluemasters. }.
        Solver allDistinct:{ Tea. Coffee. Milk. Water. Beer }.
        Solver allDistinct:{ Dogs. Birds. Cats. Horses. Fish. }.

        Brit       =: Red.           "/ The Brit lives in the red house.
        Swede      =: Dogs.          "/ The Swede keeps dogs as pets.
        Dane       =: Tea.           "/ The Dane drinks tea.
        Green =: (White - 1).        "/ The green house is on the immediate left of the white house.
        Green =: Coffee.             "/ The green house's owner drinks coffee.
        PallMall   =: Birds.         "/ The owner who smokes Pall Mall rears birds.
        Yellow =: Dunhill.           "/ The owner of the yellow house smokes Dunhill.
        Milk =: 3.                   "/ The owner living in the center house drinks milk.
        Norwegian =: 1.              "/ The Norwegian lives in the first house.
        (Blends - Cats) abs =: 1.    "/ The owner who smokes Blends lives next to the one who keeps cats.
        (Horses - Dunhill) abs =: 1. "/ The owner who keeps the horse lives next to the one who smokes Dunhill.
        Bluemasters =: Beer.         "/ The owner who smokes Bluemasters drinks beer.
        German =: Prince.            "/ The German smokes Prince.
        (Norwegian - Blue) abs =: 1. "/ The Norwegian lives next to the blue house.
        (Blends - Water) abs =: 1.   "/ The owner who smokes Blends lives next to the one who drinks water.
    ].

solution printCR.

Обратите внимание на оператор «=:», что означает «объединить с». Решатель использует алгоритм обратного отслеживания на множестве ограничений, определенных в проблемном блоке. Оставшийся код печатает решение в коробки:

    |pLine pSorted f |

    pLine := [ 
        (1 to:5) do:[:i | ('-' ,* 15) print] separatedBy:[' ' print].
        '' printCR.
    ].
    pSorted := [:keys |
        |items t|

        items := keys collect:[:k| solution at:k].
        t := keys copy. items values sortWith:t. 
        pLine value:(t collect:[:x | '| ',(x centerPaddedTo:11),' |']).
    ].

    pLine value.
    pSorted value:#( Brit Swede Dane Norwegian German ).
    pSorted value:#( Red Green White Yellow Blue ).
    pSorted value:#( Tea Coffee Milk Water Beer ).
    pSorted value:#( PallMall Dunhill Prince Blends Bluemasters ).
    pSorted value:#( Dogs Birds Cats Horses Fish ).
    pLine value.

    f := solution at:'Fish'.
    ('The %1 in the %2 house owns the fish!'
        bindWith:(#( Brit Swede Dane Norwegian German ) detect:[:n| (solution at:n) == f])
        with:(#( Red Green White Yellow Blue ) detect:[:n| (solution at:n) == f])
            ) printCR.

Выход:

Solution(Brit->3 Swede->5 Dane->2 Norwegian->1 German->4 Red->3 Green->4
 White->5 Yellow->1 Blue->2 PallMall->3 Dunhill->1 Prince->4 Blends->2
 Bluemasters->5 Tea->2 Coffee->4 Milk->3 Water->1 Beer->5 Dogs->5 Birds->3
 Cats->1 Horses->2 Fish->4)
--------------- --------------- --------------- --------------- ---------------
|  Norwegian  | |    Dane     | |    Brit     | |   German    | |    Swede    |
|   Yellow    | |    Blue     | |     Red     | |    Green    | |    White    |
|    Water    | |     Tea     | |    Milk     | |   Coffee    | |    Beer     |
|   Dunhill   | |   Blends    | |  PallMall   | |   Prince    | | Bluemasters |
|    Cats     | |   Horses    | |    Birds    | |    Fish     | |    Dogs     |
--------------- --------------- --------------- --------------- ---------------
The German in the Green house owns the fish!

Изменить: упс - я забыл напечатать строку "кто владеет рыбой" в простой версии.


3

Руби 1166 символов

Редактировать: Обновлено для правильного формата вывода

Работает последовательно менее чем за 0,2 секунды на MBP i5.

Источник: View On Github

Один лайнер:

def q(a);a.permutation;end;def z(a,b,c,d);l(a,b,c,d)||l(c,d,a,b);end;def l(a,b,c,d);(0..4).any?{|i|a[i]==b&&c[i+1]==d};end;def i(a,b,c,d);(0..4).any?{|i|a[i]==b&&c[i]==d};end;def t(i);['White','Yellow','Blue','Red','Green','German','Swede','Brit','Norwegian','Dane','Birds','Cats','Horses','Fish','Dogs','Beer','Water','Tea','Milk','Coffee','Blends','PallMall','Prince','Bluemasters','Dunhill'][i];end;def y(s);l=13-s.length;'|'+' '*(l/2.0).floor+s+' '*(l/2.0).ceil+'|';end;def d(s);b=[' '+(0..4).map{'_'*13}.join(' '*4)];u='  ';b<<[1,2,3,4,5].map{|i|y(i.to_s)}.join(u);s.each{|i|b<<i.map{|j|y(t(j))}.join(u)};b<<(0..4).map{'-'*15}.join(u);b<<'';z=s[4].index(13);b<<"The #{t s[0][z]} in the #{t s[1][z]} house owns the fish!";b.join "\n";end;q([0,1,2,3,4]).each{|c|l(c,4,c,0)||next;q([5,6,7,8,9]).each{|n|i(n,7,c,3)||next;n[0]==8||next;z(n,8,c,2)||next;q([10,11,12,13,14]).each{|a|i(n,6,a,14)||next;q([15,16,17,18,19]).each{|d|d[2]==18||next;i(c,4,d,19)||next;i(n,9,d,17)||next;q([20,21,22,23,24]).each{|s|z(a,12,s,24)||next;i(s,21,a,10)||next;z(s,20,d,16)||next;z(s,20,a,11)||next;i(n,5,s,22)||next;i(c,1,s,24)||next;i(s,23,d,15)||next;puts d([n,c,d,s,a]);exit}}}}}

Дополненный новыми строками, чтобы соответствовать странице:

def q(a);a.permutation;end;def z(a,b,c,d);l(a,b,c,d)||l(c,d,a,b);end
def l(a,b,c,d);(0..4).any?{|i|a[i]==b&&c[i+1]==d};end;def i(a,b,c,d);
(0..4).any?{|i|a[i]==b&&c[i]==d};end;def t(i);['White','Yellow','Blue',
'Red','Green','German','Swede','Brit','Norwegian','Dane','Birds',
'Cats','Horses','Fish','Dogs','Beer','Water','Tea','Milk','Coffee',
'Blends','PallMall','Prince','Bluemasters','Dunhill'][i];end;def y(s);
l=13-s.length;'|'+' '*(l/2.0).floor+s+' '*(l/2.0).ceil+'|';end;
def d(s);b=[' '+(0..4).map{'_'*13}.join(' '*4)];u='  ';
b<<[1,2,3,4,5].map{|i|y(i.to_s)}.join(u);s.each{|i|b<<i.map{|j|
y(t(j))}.join(u)};b<<(0..4).map{'-'*15}.join(u);b<<'';
z=s[4].index(13);
b<<"The #{t s[0][z]} in the #{t s[1][z]} house owns the fish!";
b.join "\n";end;q([0,1,2,3,4]).each{|c|l(c,4,c,0)||next;
q([5,6,7,8,9]).each{|n|i(n,7,c,3)||next;n[0]==8||next;z(n,8,c,2)||next;
q([10,11,12,13,14]).each{|a|i(n,6,a,14)||next;
q([15,16,17,18,19]).each{|d|d[2]==18||next;i(c,4,d,19)||next;
i(n,9,d,17)||next;q([20,21,22,23,24]).each{|s|z(a,12,s,24)||next;
i(s,21,a,10)||next;z(s,20,d,16)||next;z(s,20,a,11)||next;i(n,5,s,22)||next;
i(c,1,s,24)||next;i(s,23,d,15)||next;puts d([n,c,d,s,a]);exit}}}}}

Выходы:

 _____________    _____________    _____________    _____________    _____________
|      1      |  |      2      |  |      3      |  |      4      |  |      5      |
|  Norwegian  |  |    Dane     |  |    Brit     |  |   German    |  |    Swede    |
|   Yellow    |  |    Blue     |  |     Red     |  |    Green    |  |    White    |
|    Water    |  |     Tea     |  |    Milk     |  |   Coffee    |  |    Beer     |
|   Dunhill   |  |   Blends    |  |  PallMall   |  |   Prince    |  | Bluemasters |
|    Cats     |  |   Horses    |  |    Birds    |  |    Fish     |  |    Dogs     |
---------------  ---------------  ---------------  ---------------  ---------------

The German in the Green house owns the fish!

Код без правил

@colors        = [:white, :yellow, :blue, :red, :green].shuffle.permutation
@cigars        = [:blends, :pall_mall, :prince, :bluemasters, :dunhill].shuffle.permutation
@nationalities = [:german, :swedish, :british, :norwegian, :danish,].shuffle.permutation
@drinks        = [:beer, :water, :tea, :milk, :coffee].shuffle.permutation
@pets          = [:birds, :cats, :horses, :fish, :dogs].shuffle.permutation

def next_to?(set_a, val_a, set_b, val_b)
  left_of?(set_a, val_a, set_b, val_b) ||
  left_of?(set_b, val_b, set_a, val_a)
end

def left_of?(set_a, val_a, set_b, val_b)
  (0..4).any? do |i|
    set_a[i]   == val_a &&
    set_b[i+1] == val_b
  end
end

def implies?(set_a, val_a, set_b, val_b)
  (0..4).any? do |i|
    set_a[i] == val_a &&
    set_b[i] == val_b
  end
end

def solve
  i = 0
  @colors.each do |colors|
    i += 1
    next unless left_of?(colors, :green, colors, :white)
    @nationalities.each do |nationalities|
      i += 1
      next unless implies?(nationalities, :british, colors, :red)
      next unless nationalities[0] == :norwegian
      next unless next_to?(nationalities, :norwegian, colors, :blue)
      @pets.each do |pets|
        i += 1
        next unless implies?(nationalities, :swedish, pets, :dogs) 
        @drinks.each do |drinks|
          i += 1
          next unless drinks[2] == :milk
          next unless implies?(colors, :green, drinks, :coffee)
          next unless implies?(nationalities, :danish, drinks, :tea)
          @cigars.each do |cigars|
            i += 1
            next unless next_to?(pets, :horses, cigars, :dunhill)
            next unless implies?(cigars, :pall_mall, pets, :birds)
            next unless next_to?(cigars, :blends, drinks, :water)
            next unless next_to?(cigars, :blends, pets, :cats)
            next unless implies?(nationalities , :german, cigars, :prince)
            next unless implies?(colors, :yellow, cigars, :dunhill)
            next unless implies?(cigars, :bluemasters,  drinks, :beer)
            return [colors, nationalities, pets, drinks, cigars], i
          end
        end
      end
    end
  end
end

class Symbol
  def humanize
    result = self.to_s
    result.gsub!('_', ' ')
    result.split(' ').collect{|part| part.capitalize }.join(' ')
  end
end

solution, attempts = solve

puts "\nSolved in #{attempts} attempts.\n\n"

for i in (0..4)
  number, color, nationality, cigar, drink, pet = i+1, solution[0][i], solution[1][i].humanize, solution[4][i].humanize, solution[3][i], solution[2][i]
  puts "House #{number} is #{color}. The owner is #{nationality}, smokes #{cigar}, drinks #{drink}, and keeps #{pet}."
end

puts "\n"

Выходы:

Solved in 37663 attempts.

House 1 is yellow. The owner is Norwegian, smokes Dunhill, drinks water, and keeps cats.
House 2 is blue. The owner is Danish, smokes Blends, drinks tea, and keeps horses.
House 3 is red. The owner is British, smokes Pall Mall, drinks milk, and keeps birds.
House 4 is green. The owner is German, smokes Prince, drinks coffee, and keeps fish.
House 5 is white. The owner is Swedish, smokes Bluemasters, drinks beer, and keeps dogs.

Использование shuffleв начальной настройке гарантирует уникальные пути решения каждый раз. Вы можете увидеть это по количеству попыток, изменяющихся между запусками. Это уменьшает необходимость подачи входных данных отдельно, хотя изменение кода для этого будет тривиальным.


2
Вывод не соответствует требуемому формату.
Мего

Здесь, в PPCG, недостаточно иметь правильное решение. Ответы должны соответствовать спецификации, которая включает правильное форматирование.
El'endia Starman

2
Ok. Исходное сообщение дополнено кодом форматирования для соответствия требованиям спецификации.
Шон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.