Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I had a similar thought a few years ago with an Advent of Code problem for which my solution in python might have been

  max(map(sum, input_list.split(None)))
To decipher this the eye has to jump to the middle of the line, move rightwards, then to the left to see the "map" then move right again to see what we are mapping and then all the way to the beginning to find the "max".

The author would probably suggest rust's syntax* of

  values.iter().split(None).map(Iterator::sum).max().unwrap_or(0)
but I was learning q at the time so came up with the much clearer /s, right to left

  max((0^+)\)l
*: Though neither python nor rust have such a nice `.split(None)` built in.


> Though neither python nor rust have such a nice `.split(None)` built in.

Sorry, I'm not sure I understand what `.split(None)` would do? My initial instinct is that would would return each character. i.e. `.chars()` in Rust or `list(s)` in Python.


>Sorry, I'm not sure I understand what `.split(None)` would do?

Reading the docs [0] it seems `.split(None)` returns an array of the indivual characters without whitespace - so something like [c in list(s) if not whitespace(c)]

[0] https://docs.python.org/3.3/library/stdtypes.html?highlight=...


It was intended to split a list of `int|None` into its non-none stretches. Much like how `string.split('x')` splits a string by matching the character 'x'


Gotcha! In python there is a `split_at` function for this in the more-itertools package, but I don't think there is a concise way to do it in the stdlib.


Is the q solution equivalent? In doing a plus scan, isn't the last element always going to be the largest? To find the largest subarray sum, I would think you'd want to split into a matrix along the `null`s first and then plus reduction and then a max of those results.

Say what you will about clarity, but my mind sort of glossed over the intention in the python and rust code, focusing instead on the syntax, while the q code made me consider what was actually happening.


It is equivalent because it's not a plus-scan but a (0^+)-scan which resets every time it hits a null (there's a more in depth explanation here https://robertandrewspencer.com/aoc_2022_1/ )

Perhaps q did both force you to consider what was happening, and hide it from you...


Thanks!

Though hopefully, once the idiom is learned, I'll be able to remember it :)

Curious as to why a scan \ rather than a reduction /?


Rust doesn't have it built in, but it's part of itertools: https://docs.rs/itertools/latest/itertools/trait.Itertools.h...

This may eventually be upstreamed: https://github.com/rust-itertools/itertools/issues/1026


Honestly, I find using intermediate variables more readable than a long chain of function invocations where you have to keep track of intermediate results in your head:

    input_groups = input_list.split(None)
    group_sums = map(sum, input_groups)
    max_sum = max(group_sums)
This also gives you a slightly higher-level view on how the algorithm proceeds just by reading the variable names on the LHS.


The problem with this approach for me is that I don't know which variables are important outside of this snippet or outside of the next line. Is input_groups something I should keep in my head or is it just an intermediate result that can be discarded from my attention right away? The pipe-like solutions are nice because they are self-contained and you know that you only care about the final result and can abstract away the implementation.

I prefer python comprehensions for the same reason. I can tell that they are about crating a list or a dict and I don't need to parse a bunch of operations in a loop to come to the same conclusion.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: