Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
import Data.List
groupedSet :: (Num a, Eq a, Ord a) => (a -> a -> a) -> [a] -> [[(a, a)]]
groupedSet op xs =
map (map snd) . groupBy (\(a, _) (b, _) -> a == b) . sort $
[(x `op` y, (x, y)) | x <- xs, y <- xs, x <= y]
main :: IO ()
main = do
let a = groupedSet (+) numbers
{- i do not know these numbers: -}
b = filter ((> 1) . length . take 2) $ groupedSet (*) numbers
{- i know that you do not know them: -}
c = [x | x <- a, all (`elem` concat b) x]
{- then i know these numbers: -}
d = singlets b $ concat c
{- then i know them too: -}
e = singlets a $ concat d
print $ concat e
where numbers = [2 .. 99]
singlets a b = [y | x <- a, let y = b `intersect` x, length y == 1]
Для решения я использовал MATLAB. Да, я стреляю из пушки по воробьям, но с Матлабом я часто сталкиваюсь в работе
numbers = Union[Sort /@ Tuples[Range[2, 99], 2]];
goodproducts = Select[Reap[Sow[Plus @@ ##, Times @@ ##] & /@ numbers, _, List][[2]], (Length[##[[2]]] >= 2) &];
goodsums = Select[Reap[Sow[Times @@ ##, Plus @@ ##] & /@ numbers, _, List][[2]], (Complement[##[[2]], First /@ goodproducts] == {}) &];
goodproducts = Select[goodproducts, (Length[Intersection[##[[2]], First /@ goodsums]] == 1) &];
goodsums = Select[goodsums, (Length[Intersection[##[[2]], First /@ goodproducts]] == 1) &];
Select[numbers, And[MemberQ[First /@ goodproducts, Times @@ ##], Plus @@ ## == goodsums[[1, 1]]] &][[1]]
uniqueDay(X,D/M) :- select(D/M,X,Y),\+member(D/_,Y).
uniqueMonth(X,D/M) :- select(D/M,X,Y),\+member(_/M,Y).
monthWithUniqueDay(X,_/M) :- uniqueDay(X,_/M).
solve(X,X0) :-
exclude(monthWithUniqueDay(X0),X0,X1),
include(uniqueDay(X1),X1,X2),
include(uniqueMonth(X2),X2,X).
birthDays(X) :- X = [15/5,16/5,19/5,17/6,18/6,14/7,16/7,14/8,15/8,17/8].
num(D/M) :- numlist(2,99,N),select(X,N,_),select(Y,N,_),D is X * Y,M is X + Y.
nums(X) :- setof(Y,num(Y),X).
solve1(X) :- birthDays(X0),solve(X,X0).
solve2(X) :- nums(X0),solve(X,X0).
«Я знаю, что это май.
Это может быть 15, 16 или 19 — какой-то из этих трёх вариантов.
Значит, число, которое известно Бернарду — 15, 16 или 19.
Если у Бернарда 15, то тогда он сомневается между маем и августом.
Если у него 16, то он колеблется между маем и июлем.
Если у него 19, то он уже знает ответ.
Так что я не могу сказать, знает ли Бернард ответ, или не знает.»
Бернард: Я не знаю.В этом случае решение будет корректным.
Альберт: Я знал, что ты не знаешь.
Поначалу я не знал, когда у Шерил день рождения, но знаю теперь.
bool FirstPhraseMethod(int[] days){
bool result = true;
foreach (int day in days){
result = result && IsNotUniqueDay(day);
}
return result;
}
using System;
using System.Linq;
class Program
{
static void Main()
{
var birthDays = Enumerable.Range(2, 98)
.Join(
Enumerable.Range(2, 98), n => 1, n => 1,
(n1, n2) => new {D = n1*n2, M = n1 + n2})
.Distinct().ToList();
var x1 = birthDays.Where(d => !birthDays.Any(d1 => d.D == d1.D && d.M != d1.M)).ToList();
var x2 = birthDays.Where(d => x1.All(d1 => d1.M != d.M)).ToList();
var x3 = x2.Where(d => !x2.Any(d1 => d1.D == d.D && d1.M != d.M)).ToList();
var solve = x3.Where(d => !x3.Any(d1 => d1.D != d.D && d1.M == d.M)).ToList();
Console.WriteLine(string.Join(", ", solve.Select(d => d.D + " " + d.M)));
}
}
т.е. загадай султан два любых других числа
Решение задачи о двух мудрецах и числах от 1 до 100