Live data from Hacker News

Designing a programming language to speedrun Advent of Code

blog.vero.site

31–40 of 101 posts

Re: Designing a programming language to speedrun Advent of Code

#31
One key point I overlooked on first reading:

> [--] I wanted access to Haskell’s list monad in a sloppier language.

> I like static types, but only if they’re sufficiently expressive and supported by good inference, and I like not having to implement any of that stuff even more, so I settled for dynamic typing.

Then it's some of the power of Haskell without any of the safeguards. Plus being able to write "x f y" to mean a function call to f with arguments x and y (whereas in Haskell you'd write "x `f` y").

Re: Designing a programming language to speedrun Advent of Code

#32

Earlier quoted context omitted.

reads a bit like javascript now. You might want to consider switching languages

Honestly I'm jealous of JavaScript's arrow syntax. I don't really need anything else but the arrows are nice (and Turing complete).

I always figured that once Python got the walrus operator it would be a matter of time until arrow functions of some sort made more and more sense on Python.

Re: Designing a programming language to speedrun Advent of Code

#33
post #7

> I solve and write a lot of puzzlehunts, and I wanted a better programming language to use to search word lists for words satisfying unusual constraints, such as, “Find all ten-letter words that contain each of the letters A, B, and C exactly once and that have the ninth letter K.” So... Perl?

grep { len($_) == 10 && /^[^a]*a[^a]*$/i && /^[^b]*b[^b]*$/i && /^[^c]*c[^c]*$/i && /k.$/i } @words; Is there a simpler way?

Not sure if it would be considered simpler but lookaheads can be used to express it in a single pattern.

    ^(?=.{8}k.$)(?=[^a]*a[^a]*$)(?=[^b]*b[^b]*$)(?=[^c]*c[^c]*$)

Re: Designing a programming language to speedrun Advent of Code

#34

Earlier quoted context omitted.

reads a bit like javascript now. You might want to consider switching languages

Oh it definitely does. The reason I stick with Python is that it has a somewhat decent standard library, and IMO fewer surprises (I don’t know Python or JavaScript all that well, since I basically never use it professionally, so I need to reduce footguns for myself).

Type cohersion and type juggling can bring a few surprises. But usually only when you do something weird to hit those edge cases. Otherwise, it's standard library is actually very decent now. Especially when working with arrays. You have all the nice to have methods, like, split, find, filter, map, reduce, every, some, etc... Which makes it a really nice language for these kind of tasks.

The example above would like this in modern javascript:

      str.split(',').map(char => Number(char)).filter(num => num > 5).length

Re: Designing a programming language to speedrun Advent of Code

#35
post #7

> I solve and write a lot of puzzlehunts, and I wanted a better programming language to use to search word lists for words satisfying unusual constraints, such as, “Find all ten-letter words that contain each of the letters A, B, and C exactly once and that have the ninth letter K.” So... Perl?

grep { len($_) == 10 && /^[^a]*a[^a]*$/i && /^[^b]*b[^b]*$/i && /^[^c]*c[^c]*$/i && /k.$/i } @words; Is there a simpler way?

  [me@fedora ~]$ time perl -n -e 'length($_) == 10 && /^[^a]*a[^a]*$/i && /^[^b]*b[^b]*$/i && /^[^c]*c[^c]*$/i && /k.$/i && print' /usr/share/dict/words | wc -l
  26

  real 0m0,168s
  user 0m0,162s
  sys 0m0,007s


  [me@fedora ~]$ time perl -n -e '/^(?=.{8}k.$)(?=[^a]*a[^a]*$)(?=[^b]*b[^b]*$)(?=[^c]*c[^c]*$)/ && print' /usr/share/dict/words | wc -l
  17

  real 0m0,260s
  user 0m0,254s
  sys 0m0,006s


  [me@fedora ~]$ time perl -n -e '/^.{8}k.$/ && /a/ && /b/ && /c/ && !/a.*a/ && !/b.*b/ && !/c.*c/ && print' /usr/share/dict/words | wc -l
17

  real 0m0,115s
  user 0m0,109s
  sys 0m0,008s


  [me@fedora ~]$ time bash -c "grep '^........k.\$' /usr/share/dict/words | grep a | grep b | grep c | grep -v 'a.*a' | grep -v 'b.*b' | grep -v 'c.*c'" | wc -l
  17

  real 0m0,015s
  user 0m0,010s
  sys 0m0,020s

  [me@fedora ~]$ time awk '/^.{8}k.$/ && /a/ && /b/ && /c/ && !/a.*a/ && !/b.*b/ && ! /c.\*c/ { print }' /usr/share/dict/words | wc -l
  17

  real 0m0,129s
  user 0m0,124s
  sys 0m0,006s

  [me@fedora ~]$ time perl -n -e 'local $_ = lc; length == 11  && substr($_,8,1) eq "k" && join("",sort [/([abc])/g]->@*) eq "abc" && print' /usr/share/dict/words | wc -l
17

  real 0m0,234s
  user 0m0,228s
  sys 0m0,007s

Re: Designing a programming language to speedrun Advent of Code

#36
post #15
post #3

> Before we move on, I want to point out that “being able to write code from left to right without backtracking” is a completely bonkers thing to optimize a programming language for. This should not be anywhere in the top hundred priorities for any “serious programming language”! There are plenty of serious languages that are written this way. Most noticeably are shell scripting languages but I’ve seen stack based an…

Talking of shell, the preference for left-to-right is often used to justify "useless use of cat", i.e. `cat file | command` instead of `command <file`, but it can just be written `<file command` instead.

Is `<file` shorthand for `cat file`, or is that only true when used in a sub-shell?

Re: Designing a programming language to speedrun Advent of Code

#37
post #7

> I solve and write a lot of puzzlehunts, and I wanted a better programming language to use to search word lists for words satisfying unusual constraints, such as, “Find all ten-letter words that contain each of the letters A, B, and C exactly once and that have the ninth letter K.” So... Perl?

  W in Wordlist,
  length(W,10),
  maplist(\L^memberchk(L,W),[a,b,c]),
  nth(10,W,k).

Re: Designing a programming language to speedrun Advent of Code

#38
post #15

Earlier quoted context omitted.

Talking of shell, the preference for left-to-right is often used to justify "useless use of cat", i.e. `cat file | command` instead of `command <file`, but it can just be written `<file command` instead.

Is `<file` shorthand for `cat file`, or is that only true when used in a sub-shell?

I guess it's equivalent to `: <file` i.e. hooking up the stdin of the no-op command.

Re: Designing a programming language to speedrun Advent of Code

#39

Earlier quoted context omitted.

grep { len($_) == 10 && /^[^a]*a[^a]*$/i && /^[^b]*b[^b]*$/i && /^[^c]*c[^c]*$/i && /k.$/i } @words; Is there a simpler way?

[me@fedora ~]$ time perl -n -e 'length($_) == 10 && /^[^a]*a[^a]*$/i && /^[^b]*b[^b]*$/i && /^[^c]*c[^c]*$/i && /k.$/i && print' /usr/share/dict/words | wc -l 26 real 0m0,168s user 0m0,162s sys 0m0,007s [me@fedora ~]$ time perl -n -e '/^(?=.{8}k.$)(?=[^a]*a[^a]*$)(?=[^b]*b[^b]*$)(?=[^c]*c[^c]*$)/ && print' /usr/share/dict/words | wc -l 17 real 0m0,260s user 0m0,254s sys 0m0,006s [me@fedora ~]$ time perl -n -e '/^.{8}…

You can also do:

    sed -e '/^........k.$/!d; /a/!d; /b/!d; /c/!d; /a.*a/d; /b.*b/d; /c.*c/d' /usr/share/dict/words 
I wouldn't expect it to be much faster than AWK, but not much slower either.

Interesting that the pipeline is the fastest! I would expect the sheer number of separate processes to slow things down considerably, but apparently it doesn't really matter. Probably because the first `grep` already filters out most of the dictionary, so there isn't a lot of I/O through the pipes.

Re: Designing a programming language to speedrun Advent of Code

#40

Earlier quoted context omitted.

grep { len($_) == 10 && /^[^a]*a[^a]*$/i && /^[^b]*b[^b]*$/i && /^[^c]*c[^c]*$/i && /k.$/i } @words; Is there a simpler way?

Not sure if it would be considered simpler but lookaheads can be used to express it in a single pattern. ^(?=.{8}k.$)(?=[^a]*a[^a]*$)(?=[^b]*b[^b]*$)(?=[^c]*c[^c]*$)

It does lead to a very concise invocation:

    $ perl -ne 'print if /^(?=.{8}k.$)(?=[^a]*a[^a]*$)(?=[^b]*b[^b]*$)(?=[^c]*c[^c]*$)/' /usr/share/dict/words
Post reply on HN