Вход на сайт
задача из Haskell
NEW 20.04.14 10:38
Всем привет.
прошу помочь с решением задачи
условия следующие:
Robert der Rollenspieler möochte die Wahrscheinlichkeit berechnen, dass seine Spielgur eine
Fertigkeitsprüfung besteht, um die nächste Aufstufung seiner Spielgur zu planen. In seinem
Spiel wird eine Fertigkeitsprüfung wie folgt durchgeführt: Gegeben sind drei Attribute
der Spielgur und eine Schwierigkeit. Robert muss jeden der drei Attributswerte mit einem
20-seitigen Würfel (Zahlen von 1{20) unterwürfeln. Für jeden der drei Würfelwürfe wird die
Dierenz notiert, falls der Würfel über dem Fähigkeitswert liegt und 0 sonst. Die Prüfung
gelingt, wenn die Summe der abgeschnittenen Dierenzen kleiner oder gleich dem Schwierigkeitswert
ist. Zusätzlich gilt, dass die Prüfung immer gelingt, wenn mindestens zwei der drei
Würfelwürfe eine 1 ergeben haben; aber die Prüfung misslingt auch schon, falls 2 20 füallt.
Я прописал условия в списке:
erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], x+y<40, x+z<40, y+z<40,
if x-a1<=0
then (x-a1) == 0
else (x-a1) == (x-a1),
if y-a2<=0
then (y-a2) == 0
else (y-a2) == (y-a2),
if z-a3<=0
then (z-a3) == 0
else (z-a3) == (z-a3),
(x-a1)+(y-a2)+(z-a3)<=n]
Но вывод комбинаций выходит не полный, а именно при данных (2,2,3) 3 Hskell выводит [(2,2,3),(2,2,4),(2,2,5),(2,2,6),(2,3,3),(2,3,4),(2,3,5),(2,4,3),(2,4,4),(2,5,3),(3,2,3),(3,2,4),(3,2,5),(3,3,3),(3,3,4),(3,4,3),(4,2,3),(4,2,4),(4,3,3),(5,2,3)]
Исходя из условий задачи комбинаций должно быть больше, например (1,1,1) при ручном пересчете: 1<2 -> 0, 1<2 -> 0, 1<3 -> 0 , 0+0+0=0 < 3. Я это отразил в условиях (отмечено зеленым), но похоже не правильно. Помогите плз, разрбраться.
Так же не получается приклееть к списку считалку всех выриантов:
summE [] = 0
summE erfolgG = 1 + length (tail erfolgG)
прошу помочь
прошу помочь с решением задачи
условия следующие:
Robert der Rollenspieler möochte die Wahrscheinlichkeit berechnen, dass seine Spielgur eine
Fertigkeitsprüfung besteht, um die nächste Aufstufung seiner Spielgur zu planen. In seinem
Spiel wird eine Fertigkeitsprüfung wie folgt durchgeführt: Gegeben sind drei Attribute
der Spielgur und eine Schwierigkeit. Robert muss jeden der drei Attributswerte mit einem
20-seitigen Würfel (Zahlen von 1{20) unterwürfeln. Für jeden der drei Würfelwürfe wird die
Dierenz notiert, falls der Würfel über dem Fähigkeitswert liegt und 0 sonst. Die Prüfung
gelingt, wenn die Summe der abgeschnittenen Dierenzen kleiner oder gleich dem Schwierigkeitswert
ist. Zusätzlich gilt, dass die Prüfung immer gelingt, wenn mindestens zwei der drei
Würfelwürfe eine 1 ergeben haben; aber die Prüfung misslingt auch schon, falls 2 20 füallt.
Я прописал условия в списке:
erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], x+y<40, x+z<40, y+z<40,
if x-a1<=0
then (x-a1) == 0
else (x-a1) == (x-a1),
if y-a2<=0
then (y-a2) == 0
else (y-a2) == (y-a2),
if z-a3<=0
then (z-a3) == 0
else (z-a3) == (z-a3),
(x-a1)+(y-a2)+(z-a3)<=n]
Но вывод комбинаций выходит не полный, а именно при данных (2,2,3) 3 Hskell выводит [(2,2,3),(2,2,4),(2,2,5),(2,2,6),(2,3,3),(2,3,4),(2,3,5),(2,4,3),(2,4,4),(2,5,3),(3,2,3),(3,2,4),(3,2,5),(3,3,3),(3,3,4),(3,4,3),(4,2,3),(4,2,4),(4,3,3),(5,2,3)]
Исходя из условий задачи комбинаций должно быть больше, например (1,1,1) при ручном пересчете: 1<2 -> 0, 1<2 -> 0, 1<3 -> 0 , 0+0+0=0 < 3. Я это отразил в условиях (отмечено зеленым), но похоже не правильно. Помогите плз, разрбраться.
Так же не получается приклееть к списку считалку всех выриантов:
summE [] = 0
summE erfolgG = 1 + length (tail erfolgG)
прошу помочь
NEW 21.04.14 20:25
в ответ Kvint 20.04.14 10:38
что-то я из немецкого текста не особо понял - есть по русски или английски?
насчет считалки результатов - зачем так сложно, если нужна длина, то почему просто не взять length и применить к результату?, типа
summE = length
ну или если хочется самому считать, то уж тогда
summE [] = 0
summE (x:xs) = 1 + summE xs
насчет считалки результатов - зачем так сложно, если нужна длина, то почему просто не взять length и применить к результату?, типа
summE = length
ну или если хочется самому считать, то уж тогда
summE [] = 0
summE (x:xs) = 1 + summE xs
NEW 21.04.14 22:19
Я правильно понял что вы пытаетесь сделать список с перебором всех подходящих бросков кубика? А потом для подсчета вероятности поделить длину списка на 20^3?
А если так? (сильно не бить, haskell давно не трогал :))
diff x a | x - а > 0 = х - а
| х - а <= 0 = 0
erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], x+y<40, x+z<40, y+z<40,
(diff x a1)+(diff y a2)+(diff z a3) <= n]
Но. Про варианты с двумя выброшенными единицами вы забыли
Вам надо бы что-то вроде (с case-ом вроде понятнее)
check x y z a1 a2 a3 n = case (x,y,z) of
(1,1,_) -> True
(1,_,1) -> True
(_,1,1) -> True
(20,20,_) -> False
(20,_,20) -> False
(_,20,20) -> False
(_,_,_) -> (diff x a1)+(diff y a2)+(diff z a3) <= n
и
erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], check x y z a1 a2 a3 n]
В ответ на:
erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], x+y<40, x+z<40, y+z<40,
if x-a1<=0
then (x-a1) == 0
else (x-a1) == (x-a1),
if y-a2<=0
then (y-a2) == 0
else (y-a2) == (y-a2),
if z-a3<=0
then (z-a3) == 0
else (z-a3) == (z-a3),
(x-a1)+(y-a2)+(z-a3)<=n]
erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], x+y<40, x+z<40, y+z<40,
if x-a1<=0
then (x-a1) == 0
else (x-a1) == (x-a1),
if y-a2<=0
then (y-a2) == 0
else (y-a2) == (y-a2),
if z-a3<=0
then (z-a3) == 0
else (z-a3) == (z-a3),
(x-a1)+(y-a2)+(z-a3)<=n]
А если так? (сильно не бить, haskell давно не трогал :))
diff x a | x - а > 0 = х - а
| х - а <= 0 = 0
erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], x+y<40, x+z<40, y+z<40,
(diff x a1)+(diff y a2)+(diff z a3) <= n]
Но. Про варианты с двумя выброшенными единицами вы забыли
Вам надо бы что-то вроде (с case-ом вроде понятнее)
check x y z a1 a2 a3 n = case (x,y,z) of
(1,1,_) -> True
(1,_,1) -> True
(_,1,1) -> True
(20,20,_) -> False
(20,_,20) -> False
(_,20,20) -> False
(_,_,_) -> (diff x a1)+(diff y a2)+(diff z a3) <= n
и
erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], check x y z a1 a2 a3 n]
NEW 21.04.14 23:04
в ответ AlexOtt 21.04.14 20:25
Вот мой любительский перевод
Даны три характеристики (допустим Сила, Ловкость и Разум) и показатель сложности. Для каждой характеристики нужно бросить один раз двадцатисторонний кубик (1-20). Если кубик выдает число, большее чем показатель характеристики, то записывается разница меджу этими цифрами, в противном случае - ноль. Далее эти три разницы суммируются и сравниваются с показателем сложности. В случае, если сумма разниц меньше или равна показателю сложности, то это значит леведап.
По условиям задачи нужно показать все удачные комбинации и посчитать их. Но есть два исключения: 1. если кубик два раза из трех выпал на единицу - это считается тоже как победа, 2. если кубик два раза из трех выпал на двадцать - это неудача.
Про считалку не совсем понял, как это реализовать.
Даны три характеристики (допустим Сила, Ловкость и Разум) и показатель сложности. Для каждой характеристики нужно бросить один раз двадцатисторонний кубик (1-20). Если кубик выдает число, большее чем показатель характеристики, то записывается разница меджу этими цифрами, в противном случае - ноль. Далее эти три разницы суммируются и сравниваются с показателем сложности. В случае, если сумма разниц меньше или равна показателю сложности, то это значит леведап.
По условиям задачи нужно показать все удачные комбинации и посчитать их. Но есть два исключения: 1. если кубик два раза из трех выпал на единицу - это считается тоже как победа, 2. если кубик два раза из трех выпал на двадцать - это неудача.
Про считалку не совсем понял, как это реализовать.
NEW 21.04.14 23:12
в ответ MrSanders 21.04.14 22:19
Я сам с haskell и программированием в целом занимаюсь не больше недели :)
сегодня проверил еще раз список, как оказалось эта часть не нужна
аif x-a1<=0
then (x-a1) == 0
else (x-a1) == (x-a1),
if y-a2<=0
then (y-a2) == 0
else (y-a2) == (y-a2),
if z-a3<=0
then (z-a3) == 0
else (z-a3) == (z-a3),
Все условия уже выполняются. Осталост только счетчик прикрепить, а вот это пока для меня сложновато
сегодня проверил еще раз список, как оказалось эта часть не нужна
аif x-a1<=0
then (x-a1) == 0
else (x-a1) == (x-a1),
if y-a2<=0
then (y-a2) == 0
else (y-a2) == (y-a2),
if z-a3<=0
then (z-a3) == 0
else (z-a3) == (z-a3),
Все условия уже выполняются. Осталост только счетчик прикрепить, а вот это пока для меня сложновато
NEW 21.04.14 23:22
в ответ Kvint 21.04.14 23:12
Счетчик чего вам нужен-то?
AlexOtt уже ж спросил почему вас родной length для списка не устраивает.
Да, и если вы просто выбросите условия "if x-a1<=0 ..." ничем их не заменив, то у вас проблемы будут.
Пример:
(5,5,5) 10 - в вашем списке появится, например, (2,2,20), хотя он по условиям задачи не подходит (0+0+15>10). Понимаете почему?

Да, и если вы просто выбросите условия "if x-a1<=0 ..." ничем их не заменив, то у вас проблемы будут.
Пример:
(5,5,5) 10 - в вашем списке появится, например, (2,2,20), хотя он по условиям задачи не подходит (0+0+15>10). Понимаете почему?
NEW 22.04.14 00:01
в ответ MrSanders 21.04.14 23:22
Вы правы на счет нарушения условий задачи. Может быть как то так сделать?
Добавить три переменных, которые в зависимости от разницы будут единицей или нулем.
вот так:
(x-a1)<0 -> d1 == 0
(x-a1)>=0 -> d1 == 1
А потом эти переменные будут перемножать сами разницы:
d1*(x-a1)+d2*(y-a2)+d3*(z-a3) <= n
Добавить три переменных, которые в зависимости от разницы будут единицей или нулем.
вот так:
(x-a1)<0 -> d1 == 0
(x-a1)>=0 -> d1 == 1
А потом эти переменные будут перемножать сами разницы:
d1*(x-a1)+d2*(y-a2)+d3*(z-a3) <= n
NEW 22.04.14 00:06
мне нужно сумма всех удачных комбинаций, что бы вычислить вероятность поделив сумму удачных комбинаций на сумму всех существующих.
По последнему я сделал правиольно (я надеюсь)
allV = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20]]
summ :: [a] -> Int
summ [] = 0
summ allV = 1 + length (tail allV)
в ответ MrSanders 21.04.14 23:22
В ответ на:
Счетчик чего вам нужен-то?
Счетчик чего вам нужен-то?
мне нужно сумма всех удачных комбинаций, что бы вычислить вероятность поделив сумму удачных комбинаций на сумму всех существующих.
По последнему я сделал правиольно (я надеюсь)
allV = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20]]
summ :: [a] -> Int
summ [] = 0
summ allV = 1 + length (tail allV)
NEW 22.04.14 00:42
Я вам даже облегчу жизнь :)
То что вы считаете (длина этого списка) это количество элементов в упорядоченной выборке с возвращением. Формула - n^k. Так что ваше число всех возможных комбинаций - 20^3.
А это вообще фееричная ерунда.
Вы написали:
summ x =
ЕСЛИ x = [] ВЕРНИ 0
ЕСЛИ x = allv ВЕРНИ 1 + ДЛИНА allv БЕЗ ПЕРВОГО ЭЛЕМЕНТА
а что вернет ваша функция если её вызвать как
summ 1:2:3:[]
?
А просто написать length allv вам что мешает-то?
в ответ Kvint 22.04.14 00:06
В ответ на:
По последнему я сделал правиольно (я надеюсь)
allV = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20]]
По последнему я сделал правиольно (я надеюсь)
allV = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20]]
Я вам даже облегчу жизнь :)
То что вы считаете (длина этого списка) это количество элементов в упорядоченной выборке с возвращением. Формула - n^k. Так что ваше число всех возможных комбинаций - 20^3.
В ответ на:
summ [] = 0
summ allV = 1 + length (tail allV)
summ [] = 0
summ allV = 1 + length (tail allV)
А это вообще фееричная ерунда.
Вы написали:
summ x =
ЕСЛИ x = [] ВЕРНИ 0
ЕСЛИ x = allv ВЕРНИ 1 + ДЛИНА allv БЕЗ ПЕРВОГО ЭЛЕМЕНТА
а что вернет ваша функция если её вызвать как
summ 1:2:3:[]
?
А просто написать length allv вам что мешает-то?
22.04.14 09:58
в ответ Kvint 22.04.14 08:03
А тепень делаем еще два шага
1. Осознаем что функция summ не нужна. Вместо нее можно просто писать length
2. Понимаем что вообще весь список allv нам не нужен. Его размер = 20*20*20. Поэтому везьде где мы собирались писать length allv мы просто пишем 8000.
1. Осознаем что функция summ не нужна. Вместо нее можно просто писать length
2. Понимаем что вообще весь список allv нам не нужен. Его размер = 20*20*20. Поэтому везьде где мы собирались писать length allv мы просто пишем 8000.
NEW 22.04.14 12:01
в ответ MrSanders 22.04.14 09:58
Для того, что бы высчитать вероятность я написал следующее, но как обычно не верно 
chance (a1,a2,a3) n = summE/ 8000
where summE erfolgG (a1,a2,a3) n = length
where erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], check x y z a1 a2 a3 n]
where check x y z a1 a2 a3 n = case (x,y,z) of
(1,1,_) -> True
(1,_,1) -> True
(_,1,1) -> True
(20,20,_) -> False
(20,_,20) -> False
(_,20,20) -> False
пробовал просто написать chance (a1,a2,a3) n = length (erfolgG (a1,a2,a3) n) / 8000
но тоже провал

chance (a1,a2,a3) n = summE/ 8000
where summE erfolgG (a1,a2,a3) n = length
where erfolgG (a1,a2,a3) n = [(x,y,z) | x<-[1..20], y<-[1..20], z<-[1..20], check x y z a1 a2 a3 n]
where check x y z a1 a2 a3 n = case (x,y,z) of
(1,1,_) -> True
(1,_,1) -> True
(_,1,1) -> True
(20,20,_) -> False
(20,_,20) -> False
(_,20,20) -> False
пробовал просто написать chance (a1,a2,a3) n = length (erfolgG (a1,a2,a3) n) / 8000
но тоже провал
NEW 22.04.14 14:45
в ответ MrSanders 22.04.14 13:57
Вот что получается. как вы и говорили есть комбинации не удовлетворяющие условаиям задачи
[(1,1,1),(1,1,2),(1,1,3),(1,1,4),(1,1,5),(1,1,6),(1,1,7),(1,1,8),(1,1,9),(1,1,10),(1,1,11),(1,1,12),(1,1,13),(1,1,14),(1,1,15),(1,1,16),(1,1,17),(1,1,18),(1,1,19),(1,1,20),(1,2,1),(1,2,2),(1,2,3),(1,2,4),(1,2,5),(1,3,1),(1,3,2),(1,3,3),(1,3,4),(1,4,1),(1,4,2),(1,4,3),(1,5,1),(1,5,2),(1,6,1),(1,7,1),(1,8,1),(1,9,1),(1,10,1),(1,11,1),(1,12,1),(1,13,1),(1,14,1),(1,15,1),(1,16,1),(1,17,1),(1,18,1),(1,19,1),(1,20,1),(2,1,1),(2,1,2),(2,1,3),(2,1,4),(2,1,5),(2,2,1),(2,2,2),(2,2,3),(2,2,4),(2,3,1),(2,3,2),(2,3,3),(2,4,1),(2,4,2),(2,5,1),(3,1,1),(3,1,2),(3,1,3),(3,1,4),(3,2,1),(3,2,2),(3,2,3),(3,3,1),(3,3,2),(3,4,1),(4,1,1),(4,1,2),(4,1,3),(4,2,1),(4,2,2),(4,3,1),(5,1,1),(5,1,2),(5,2,1),(6,1,1),(7,1,1),(8,1,1),(9,1,1),(10,1,1),(11,1,1),(12,1,1),(13,1,1),(14,1,1),(15,1,1),(16,1,1),(17,1,1),(18,1,1),(19,1,1),(20,1,1)]
Я не могу понять, как добавить список еще три переменные для обозначения разницы
[(1,1,1),(1,1,2),(1,1,3),(1,1,4),(1,1,5),(1,1,6),(1,1,7),(1,1,8),(1,1,9),(1,1,10),(1,1,11),(1,1,12),(1,1,13),(1,1,14),(1,1,15),(1,1,16),(1,1,17),(1,1,18),(1,1,19),(1,1,20),(1,2,1),(1,2,2),(1,2,3),(1,2,4),(1,2,5),(1,3,1),(1,3,2),(1,3,3),(1,3,4),(1,4,1),(1,4,2),(1,4,3),(1,5,1),(1,5,2),(1,6,1),(1,7,1),(1,8,1),(1,9,1),(1,10,1),(1,11,1),(1,12,1),(1,13,1),(1,14,1),(1,15,1),(1,16,1),(1,17,1),(1,18,1),(1,19,1),(1,20,1),(2,1,1),(2,1,2),(2,1,3),(2,1,4),(2,1,5),(2,2,1),(2,2,2),(2,2,3),(2,2,4),(2,3,1),(2,3,2),(2,3,3),(2,4,1),(2,4,2),(2,5,1),(3,1,1),(3,1,2),(3,1,3),(3,1,4),(3,2,1),(3,2,2),(3,2,3),(3,3,1),(3,3,2),(3,4,1),(4,1,1),(4,1,2),(4,1,3),(4,2,1),(4,2,2),(4,3,1),(5,1,1),(5,1,2),(5,2,1),(6,1,1),(7,1,1),(8,1,1),(9,1,1),(10,1,1),(11,1,1),(12,1,1),(13,1,1),(14,1,1),(15,1,1),(16,1,1),(17,1,1),(18,1,1),(19,1,1),(20,1,1)]
Я не могу понять, как добавить список еще три переменные для обозначения разницы
NEW 22.04.14 20:17
в ответ MrSanders 22.04.14 19:13
Я сделал три функции diff1, diff2 и diff3. После этого все заработало в лучшем виде. Вот пример вывода при (2,2,2) 2
[(1,1,1),(1,1,2),(1,1,3),(1,1,4),(1,2,1),(1,2,2),(1,2,3),(1,2,4),(1,3,1),(1,3,2),(1,3,3),(1,4,1),(1,4,2),(2,1,1),(2,1,2),(2,1,3),(2,1,4),(2,2,1),(2,2,2),(2,2,3),(2,2,4),(2,3,1),(2,3,2),(2,3,3),(2,4,1),(2,4,2),(3,1,1),(3,1,2),(3,1,3),(3,2,1),(3,2,2),(3,2,3),(3,3,1),(3,3,2),(4,1,1),(4,1,2),(4,2,1),(4,2,2)]
Огромное спасибо за помощь, а то я уже отчаиваться начал. Не первый раз тут совет прошу, всегда выручают.
Осталось только вероятность посчитать, но это уж сам постараюсь сделать :)
[(1,1,1),(1,1,2),(1,1,3),(1,1,4),(1,2,1),(1,2,2),(1,2,3),(1,2,4),(1,3,1),(1,3,2),(1,3,3),(1,4,1),(1,4,2),(2,1,1),(2,1,2),(2,1,3),(2,1,4),(2,2,1),(2,2,2),(2,2,3),(2,2,4),(2,3,1),(2,3,2),(2,3,3),(2,4,1),(2,4,2),(3,1,1),(3,1,2),(3,1,3),(3,2,1),(3,2,2),(3,2,3),(3,3,1),(3,3,2),(4,1,1),(4,1,2),(4,2,1),(4,2,2)]
Огромное спасибо за помощь, а то я уже отчаиваться начал. Не первый раз тут совет прошу, всегда выручают.
Осталось только вероятность посчитать, но это уж сам постараюсь сделать :)