J, 16 11 bytes
(+$:)^:=1+?
Try it online!
Explanation
TL;DR 1+? performs the die roll, (+$:)^:= reiterates only when it equals the input.
The function is a train of 4 verbs:
┌─ +
┌───┴─ $:
┌─ ^: ─┴─ =
│
──┤ ┌─ 1
└──────┼─ +
└─ ?
A train is when 2 or more verbs are concatenated. Here, the answer is of the form f g h j:
(+$:)^:= 1 + ?
f g h j
A so-called "4-train" is parsed as a hook and a fork:
f g h j ⇔ f (g h j)
Thus, the answer is equivalent to:
(+$:)^:= (1 + ?)
Hooks: (f g) x and x (f g) y
A monadic (one-argument) hook of two verbs, given an argument x, the following equivalence holds:
(f g) x ⇔ x f (g x)
For example, (* -) 5 evaluates to 5 * (- 5), which evaluates to _25.
This means that our 4-train, a hook of f and (g h j), is equivalent to:
(f (g h j)) x ⇔ x f ((g h j) x)
But what does f do here? (+$:)^:= is a conjunction of two verbs using the Power conjunction ^:: another hook ((+$:)) and a verb (=). Note here that f is dyadic—it has two arguments (x and (g h j) x). So we have to look at how ^: behaves. The power conjunction f^:o takes a verb f and either a verb or a noun o (a noun is just a piece of data) and applies f o times. For example, take o = 3. The following equivalences holds:
(f^:3) x ⇔ f (f (f x))
x (f^:3) y ⇔ x f (x f (x f y))
If o is a verb, the power conjunction will simply evaluate o over the arguments and use the noun result as the repeat count.
Для нашого дієслова o- =це дієслово рівності. Вона оцінюється як 0для різних аргументів, так і 1для рівних аргументів. Ми повторюємо гачок (+$:)один раз для рівних аргументів і не раз для різних. Для зручності позначення для пояснення нехай y ⇔ ((g h j) x). Пам'ятайте, що наш початковий гак рівнозначний цьому:
x (+$:)^:= ((g h j) x)
x (+$:)^:= y
Розширюючи сполучник, це стає:
x ((+$:)^:(x = y)) y
Якщо xі yоднакові, це стає:
x (+$:)^:1 y ⇔ x (+$:) y
В іншому випадку це стає:
x (+$:)^:0 y ⇔ y
Тепер ми бачили монадичні вилки. Ось у нас діадічна вилка:
x (f g) y ⇔ x f (g y)
Отже, коли xі yоднакові, ми отримуємо:
x (+$:) y ⇔ x + ($: y)
Що таке $:? Він відноситься до всього самого дієслова і допускає рекурсію. Це означає, що коли xі y are the same, we apply the verb toy and addx` до нього.
Вилки: (g h j) x
Тепер, що робить внутрішня вилка? Це було yв нашому останньому прикладі. Для монадичної вилки з трьох дієслів, заданих аргументом x, має місце наступна еквівалентність:
(g h j) x ⇔ (g x) h (j x)
Для такого прикладу припустимо, що ми дієслова з ім'ям SUM, DIVIDEі LENGTH, що робити то , що ви думаєте , що вони могли б. Якщо ми об'єднаємо трійку у виделку, отримуємо:
(SUM DIVIDE LENGTH) x ⇔ (SUM x) DIVIDE (LENGTH x)
Ця вилка оцінюється до середнього значення x(припускаючи x, що це список номерів). У J ми насправді запишемо це як приклад як +/ % #.
Останнє про вилки. Коли крайній лівий "зубчик" (у нашому символічному випадку вище g) є іменником, це трактується як постійна функція, що повертає це значення.
Маючи все це на місці, тепер ми можемо зрозуміти вищезгадану вилку:
(1 + ?) x ⇔ (1 x) + (? x)
⇔ 1 + (? x)
? тут дається випадкове ціле число в діапазоні [0,x), so we need to transform the range to represent dice; incrementing yields the range [1,x].
Putting it all together
Given all these things, our verb is equivalent to:
((+$:)^:=1+?) x ⇔ ((+$:)^:= 1 + ?) x
⇔ ((+$:)^:= (1 + ?)) x
⇔ x ((+$:)^:=) (1 + ?) x
⇔ x ((+$:)^:=) (1 + (? x))
⇔ x (+$:)^:(x = (1 + (? x))
(let y = 1 + (? x))
if x = y ⇒ x + $: y
otherwise ⇒ y
This expresses the desired functionality.