This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

## 2018-08-21

## Channels

- # bangalore-clj (11)
- # beginners (82)
- # boot (1)
- # braveandtrue (29)
- # cider (16)
- # cljdoc (2)
- # cljs-dev (2)
- # clojure (74)
- # clojure-dev (3)
- # clojure-italy (2)
- # clojure-mke (1)
- # clojure-nl (4)
- # clojure-sg (1)
- # clojure-spec (1)
- # clojure-uk (53)
- # clojure-ukraine (1)
- # clojurescript (33)
- # cursive (29)
- # datomic (59)
- # editors (4)
- # emacs (14)
- # fulcro (2)
- # graphql (12)
- # hoplon (2)
- # nyc (4)
- # onyx (5)
- # parinfer (10)
- # pedestal (22)
- # re-frame (11)
- # reagent (35)
- # ring-swagger (5)
- # shadow-cljs (150)
- # tools-deps (9)
- # vim (1)
- # yada (20)

Are you doing the online version of Brave? Can you link to the part you’re having trouble with?

Yeah, I’m doing the online version. https://www.braveclojure.com/do-things/#Hobbit_Violence

actually, maybe I’m jumping to asking questions too soon. 🙂 I’ll keep struggling some more

Back to the violence here: https://www.braveclojure.com/do-things/#Hobbit_Violence

I think I figured it out, but I don’t understand how it weights the hits based on the body part size

```
; here we define a function called hit that takes one parameter asym-body-...;
; it's going to return the body part that we want to hit
(defn hit
[asym-body-parts]
; let defines 3 scoped variables, it looks like it happens in order
; first, sym-parts is defined as the output of the better-sym... function
; second, body-part-size is the sum of all body parts
; target is a number < body-part-size...
(let [sym-parts (better-symmetrize-body-parts asym-body-parts)
body-part-size-sum (reduce + (map :size sym-parts))
target (rand body-part-size-sum)]
; now we start he loop, the [[]] causes destructuring, we take just the
; first element from sym parts and assign it to "part" and "remaining"
; for tail-recursion
; we accumulate size
(loop [[part & remaining] sym-parts
accumulated-size (:size part)]
(if (> accumulated-size target)
; if acc-size > target, then we've found a large enough body part
part
; otherwise recurse and add up the size of the next remaining item
(recur remaining (+ accumulated-size (:size (first remaining))))))))
```

it seems to me like this will hit the next body part in the list after the accumulated weight of those parts listed beforehand reaches the target

No, I think you're understanding it correctly. Maybe it would help to picture it graphically. Imagine we've got 4 body parts of different sizes, represented by an vector like this: [1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 3 3 3 4 4 ]. Body part #1 is the biggest, so it takes up twice as much space in the vector as body part #2 for example. If I've counted right, that's 20 elements in the array. So now we pick a random number between 0 and 19 (since vectors are zero based). On average, it'll pick body part 1 half the time since it occupies half the vector. Body part 2 occupies about 25% of the vector, so it would get picked a quarter of the time.

So the code above is basically walking through the vector and saying "Did our random target land in the first 10 element of the vector? No? Ok, let's look at the other half of the vector."

By subtracting 10 from the target, and dropping off the first 10 elements of the vector, we can continue to check whether the target landed in the next 5 elements, i.e. body part 2.

Is that clear? It all seems so clear in my head, but it's been a long day and I'm afraid I'm just confusing the issue with my graphical metaphor.

Let me try an even more graphical example. Suppose `target`

is 13. So, to use my graph metaphor, that would look like this:

```
[1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 3 3 3 4 4 ]
[= = = = = = = = = = = = = ^ ] ;; target
```

So `target`

is 13, and the `:size`

of body part 1 is 10. So we know it didn't hit body part number 1, and we can discard it

```
[X X X X X X X X X X 2 2 2 2 2 3 3 3 4 4 ]
[X X X X X X X X X X = = ^ ] ;; target
```

Let's just remove all those X's to clean things up.

```
[ 2 2 2 2 2 3 3 3 4 4 ]
[ = = ^ ] ;; target
```

So, we removed 10 from `target`

to account for the 10 elements we deleted, since they were body part 1. That leaves us with a `target`

of 3, and we're ready to check body part 2. The `:size`

of body part 2 is 5, and the target is less than that, so boom, there's our hit.

Or another way to put it is that by subtracting the `:size`

of body part 1 from the `target`

of 13, we're keeping the pointer lined up with the original target.

Does that help or am I just muddying the waters here?

@manutter51 that made sense. But is that vector sorted? I thought it wasn’t sorted which makes it like:

`[1 1 1 1 1 1 1 2 2 3 3 3 3 3 3 3 3 3 4 4 4 5 5 5 5 5 5 5 5 5 ]`