Finding the Most Beautiful APL Solution!

Поделиться
HTML-код
  • Опубликовано: 2 янв 2025

Комментарии • 37

  • @MrInsideEye
    @MrInsideEye 3 года назад +61

    It really is beautiful, although I would avoid calling an answer the "final solution"

  • @peetiegonzalez1845
    @peetiegonzalez1845 3 года назад +24

    Thank goodness. My immediate thought was the solution you gave last. I was watching the preceding solutions in confusion over how inefficient they were.

  • @gavintillman1884
    @gavintillman1884 3 года назад +6

    Pleased to see that my first reaction is the best answer! Still getting to grips with APL and wouldn’t have known the notation exactly but knew what I wanted it to do.

  • @jayantchoudhary1495
    @jayantchoudhary1495 3 года назад +1

    I quite like the 1st solution ,I for one would never have thought of using a Boolean mask for this problem

  • @woncoh1
    @woncoh1 Год назад

    The monadic fork!
    (f g h)Y → (f Y) g (h Y)
    Love your videos by the way
    Could you do more videos on BQN, Elixir, and programming linguistic typology and geneology?

  • @rhbvkleef
    @rhbvkleef 3 года назад +3

    I thought of the final solution immediately, when prompted with the problem, and wrote a solution in Elixir. Quite nice, though not as concise as in APL.

  • @夕阳-n1h
    @夕阳-n1h 3 года назад +2

    can you please make a video about using RIDE? There isn't much resources on that matter.
    Thank you

  • @foxoninetails_
    @foxoninetails_ 3 года назад +2

    This is one case where the J equivalent of the final solution surprisingly doesn't involve any wrangling to get a B-combinator instead of an S-combinator - the APL version perfectly translates character by character to the J solution */%]

  • @mdht
    @mdht 3 года назад +1

    The best video ever ❤️❤️❤️

  • @pamdemonia
    @pamdemonia 3 года назад

    I just realized there's only 2 more days until AoC! Commenting here because I figure y'all will understand! So exciting!

  • @michaelgrubb3508
    @michaelgrubb3508 3 года назад +1

    How do you get the boxes around the embedded vectors? I'm just starting to pick up APL and that makes visualizing the embedded vectors so much easier.

  • @jumbo_mumbo1441
    @jumbo_mumbo1441 2 года назад

    I was staring at this for a minute thinking "there should be a linear time solution for this. What am I missing" then it hit me haha

  • @bobdavelisafrank_4850
    @bobdavelisafrank_4850 3 года назад +3

    The solution I came up with in J is:
    [: */ ] (] + [ * [: -. ]) e. @ i. @ #
    It's the same idea as trying to filter out elements and taking the product over, but very different in how the filtering is done! It's done by replacing unwanted elements with 1 instead of removing them.
    The 'e. @ i.@ #' creates an identity matrix, and this is combined with the original list using '] + [ * [: -. ]'. This 'nots' the matrix, multiplies it by the original list (producing zeros at the removed elements!), then adds the original identity matrix to increment those zeros. Then, the product across the columns is taken.
    The thing I find neat about it is the use of a more involved function in the center of the fork -- normally I tend towards composing things onto the outer tines of the fork, but here it just felt natural to modify the center. This made it really easy to combine the list with its derived identity matrix!
    -Cassie

  • @cranknlesdesires
    @cranknlesdesires 3 года назад +7

    I just did this in lua, it was a bit verbose. It's amazing how much can be done in such little space with an array lang.
    That last solution is wizardly.

  • @Kh-ik3de
    @Kh-ik3de 5 месяцев назад

    Why is meli from toki pona in comments

  • @AMathMonkey
    @AMathMonkey 3 года назад

    It's unfortunate that a specific website featuring this problem disallows the last solution by forbidding you from using division, even though that method is the most efficient. But it is fun to see all the other ways you can do it.

  • @arraymac227
    @arraymac227 3 года назад +4

    Two notes:
    The ×/ may overflow, where the final answer doesn't.
    X≠Y ←→ ~X=Y

    • @bzboii
      @bzboii 3 года назад

      “running the tilde”

  • @lucasbss
    @lucasbss 3 года назад +1

    I stopped the video went to learn the basics of this alien language and came back, I'm still dizzy

  • @Shoecutter1
    @Shoecutter1 3 года назад

    Perhaps I'm biasing programmers to an education in mathematics, but isn't the last solution fairly straightforward from, say, factorials + algebra? I agree with your point about languages (both computer and natural) influencing how you think, but it seems APL lead the first 3 solutions down the garden path, no?

  • @cogspace
    @cogspace 3 года назад

    // My obligatory JS solution
    const arrayOfProduct = n => n.map((_, i) => n.filter((_, j) => i != j).reduce((n, m) => n * m))
    // Edit: Oh, that final solution is so much better. I didn't catch the significance of the positive integer constraint. JS equivalent is of course nowhere near as pretty as APL:
    const finalSolution = n => {
    const product = n.reduce((a, b) => a * b);
    return n.map(e => product / e);
    }

    • @ollejohannesson
      @ollejohannesson 2 года назад

      With some setup, we JS devs can also use those fancy combinators!
      const reduce = f => a => a.reduce(f)
      const mapIfArray = x => Array.isArray(x) ? f => x.map(f) : f => f(x)
      const multiplication = a => b => a * b
      const multiply = (a, b) => multiplication(a)(b)
      const division = a => b => a / b
      const divide = a => b => mapIfArray(b)(division(a))
      // chain combinator (a → b → c) → (b → a) → b → c
      const S_ = f => g => x => f (g (x)) (x)
      const solution = S_ ( divide ) ( reduce ( multiply ) )
      solution ( [5,2,1,4,3] )
      // [24, 60, 120, 30, 40]

  • @michaelmanti
    @michaelmanti 3 года назад

    I extended the last, most efficient solution in J to allow for zeroes in the input.
    case =: [: 2&