meander

wilkerlucio 2022-05-03T18:11:29.234849Z

hello folks, I have a meander puzzle I'm trying to solve and hope you can me figure it 🙂 this is what I have now:

(m/search
    [1
     2
     true
     3
     "foo"
     "bar"
     4
     5
     "not after thing"
     6
     true
     34
     "more"
     "text"
     "thing"
     4
     5]
    
    [_ ... true _ . (m/pred string? !n) ... . _ ...]
    !n)

Danny 2022-05-05T22:35:01.610469Z

@wilkerlucio 🙂

👍 1
Danny 2022-05-04T13:28:07.879869Z

@jimmy 😅 ?

wilkerlucio 2022-05-03T18:12:49.967799Z

so, what I'm trying to extract here are the strings, that occur after a true entry and skipping the item right after it

wilkerlucio 2022-05-03T18:12:56.580549Z

current result: => ([] ["foo"] ["foo" "bar"] [] ["more"] ["more" "text"] ["more" "text" "thing"])

wilkerlucio 2022-05-03T18:13:31.335279Z

the string "not after thing" should not match because it doesn't fits in the true + any criteria

wilkerlucio 2022-05-03T18:13:59.131669Z

my target goal here is to have: => (["foo" "bar"] ["more" "text" "thing"])

wilkerlucio 2022-05-03T18:14:07.517839Z

how would you guys go about this case?

Danny 2022-05-03T18:36:46.450839Z

Isn’t search supposed to find multiple instances of the given pattern? Try find?

wilkerlucio 2022-05-03T18:37:04.454609Z

but I want multiple instances of the thing

wilkerlucio 2022-05-03T18:37:19.763459Z

the pattern happens multiple times in the sequence, and I want all of them

Danny 2022-05-03T18:37:21.041499Z

ah

Danny 2022-05-03T18:41:38.287859Z

Why do you have string? !n) ... . _ ...] when you only want to drop the item after true if I understand correctly?

wilkerlucio 2022-05-03T18:42:10.644959Z

I want to drop 1 line after the true, and get all the items that are strings after that, a non-string should stop the capture of that group

Danny 2022-05-03T18:43:07.578229Z

but a non string won’t match pred string? what’s the . _ for after the pred?

wilkerlucio 2022-05-03T18:43:22.302569Z

my real case is some text processing that I'm doing (from PDF's, which are very messy :P), so I'm looking for a start condition to find something (the true is an example here), then I have to skip some lines, start grabbing all the items that match a condition in sequence, stop, and look for that pattern down again, makes sense?

Danny 2022-05-03T18:44:10.257149Z

Uhg PDFs … <ptsd dog gif/>

wilkerlucio 2022-05-03T18:44:10.931769Z

. _ after the pred is to allow for extra items after, the . partitions it, and _ ... allow for other things after my match

Danny 2022-05-03T18:45:33.391929Z

Just wondering because your current results look “exploded”

wilkerlucio 2022-05-03T18:46:09.782799Z

yeah, I dont fully understand what I'm doing, but this is the best aproximation of what I need that I could figure 😛

wilkerlucio 2022-05-03T18:46:21.904229Z

removing the . _ .... results in nothing matching

Danny 2022-05-03T18:51:24.848259Z

> The . operator, read as “partition”, partitions the collection into two parts: left and right. This operator is used primarily to delimit the start of a variable length subsequence. It is important to note that both ... and ..n act as partition operators as well.

Danny 2022-05-03T18:51:29.696719Z

Do you even need ... ?

Danny 2022-05-03T18:51:33.056009Z

(I’m a noob)

Danny 2022-05-03T18:53:49.059759Z

..1 should probably filter out the empty matches

wilkerlucio 2022-05-03T19:03:11.143729Z

which of the ...?

wilkerlucio 2022-05-03T19:03:22.641849Z

..1 means 1 repetition

wilkerlucio 2022-05-03T19:03:36.044139Z

(so its same as not using it at all :P)

Danny 2022-05-03T19:03:50.213509Z

Docs say at least 1

wilkerlucio 2022-05-03T19:03:59.917019Z

ah, yeah, zero could match too

wilkerlucio 2022-05-03T19:04:21.948829Z

you can play with my example if you like to try a bit, but in my tests here, removing any of hte things breaks the match

Danny 2022-05-03T19:04:47.111559Z

if you put ..1 after string pred does it keep the empty matches still?

Danny 2022-05-03T19:04:57.504699Z

I need to get my hands on a repl again 😛

wilkerlucio 2022-05-03T19:05:07.690869Z

..1 there would match at max 1 item, and I want many there

Danny 2022-05-03T19:05:54.102729Z

..1 = 1 or more things

wilkerlucio 2022-05-03T19:06:53.282329Z

ah, you right, yeha, that's better, it removes the empty cases

wilkerlucio 2022-05-03T19:07:04.022089Z

(m/search
    [1
     2
     true
     3
     "foo"
     "bar"
     4
     5
     "not after thing"
     6
     true
     34
     "more"
     "text"
     "thing"
     4
     5]

    [_ ... true _ . (m/pred string? !n) ..1 . _ ...]
    !n)
=> (["foo"] ["foo" "bar"] ["more"] ["more" "text"] ["more" "text" "thing"])

wilkerlucio 2022-05-03T19:07:24.352869Z

this is my though process on the current matcher:

[_ ... ; allow for precedent items
 true _ . ; find my starting point
 (m/pred string? !n) ..1 . ; matches every string in sequence
 _ ... ; allow for successor items
 ]

Danny 2022-05-03T19:08:40.212959Z

Ok now we just need to make !n greedy I guess?

wilkerlucio 2022-05-03T19:09:40.225149Z

yeah, I also wonder if there is a completly different solution that I'm just not aware of (some operator on meander that may be able to handle it)

Danny 2022-05-03T19:09:54.479319Z

Did you play around with scan?

wilkerlucio 2022-05-03T19:10:17.189109Z

yeah, but scan is for more regular things on a sequence afaik

wilkerlucio 2022-05-03T19:16:21.742289Z

this works, but its quite ugly XD

(->> (m/search
         [1
          true
          3
          "a"
          true
          3
          "b"
          2
          true
          3
          "foo"
          "bar"
          4
          5
          "not after thing"
          6
          true
          34
          "more"
          "text"
          "thing"
          4
          5]

         [_ ... true _ . (m/pred string? !n) ..1 . _ ...]
         !n)
       (partition-all 2 1)
       (filter #(or (nil? (second %))
                    (>= (count (first %))
                      (count (second %)))))
       (map first))
=> (["a"] ["b"] ["foo" "bar"] ["more" "text" "thing"])

😬 1
Danny 2022-05-03T19:18:22.213699Z

What would this do: (m/pred string? !n ..1)

wilkerlucio 2022-05-03T19:19:07.364549Z

moving the ..1 inside m/pred?

wilkerlucio 2022-05-03T19:19:22.568319Z

I think that's not valid syntax

Danny 2022-05-03T19:19:39.693429Z

pred can take multiple patterns and they all must match the predicate

wilkerlucio 2022-05-03T19:19:47.486489Z

No method in multimethod 'compile-specialized-matrix' for dispatch value: :dt+

🐞 1
Danny 2022-05-03T19:20:04.255959Z

wew

Danny 2022-05-03T19:20:24.341939Z

maybe not with ... then 😄

Ben Sless 2022-05-03T19:40:08.613549Z

This is close

(m/search
  [1
   2
   true
   3
   "foo"
   "bar"
   4
   5
   "not after thing"
   6
   true
   34
   "more"
   "text"
   "thing"
   4
   5]
  [_ ... true _ (m/pred string? !s) . (m/pred string? !s) ... _ ...] !s
  )
The problem is getting all intermeadiate states
(["foo"] ["foo" "bar"] ["more"] ["more" "text"] ["more" "text" "thing"])

wilkerlucio 2022-05-03T19:40:47.444779Z

@ben.sless we got the same by replace the original ... after the pred with ..1

Danny 2022-05-03T19:41:08.739559Z

I got this far:

=> (m/search input [_ ... true _ (m/pred string? !n) ..1 . _ ...] !n)
(["foo"] ["more"])

Ben Sless 2022-05-03T19:47:10.844879Z

This match finds only the more next thing

[_ ... true _ (m/pred string? !s) . (m/pred string? !s) ... (m/pred (complement string?)) _ ...] !s

Ben Sless 2022-05-03T19:53:07.332269Z

Slightly more concise

[_ ... true _ . (m/pred string? !s)  ... (m/pred (complement string?)) _ ...] !s
still wrong

Ben Sless 2022-05-03T19:55:03.568469Z

GOT IT

(m/search
  [1 2 true 3 "foo" "bar" 4 5 "not after thing" 6 true 34 "more" "text" "thing" 4 5]
  [_ ... true _ . (m/pred string? !s)  ... (m/pred (complement string?)) . _ ...] !s
  )

wilkerlucio 2022-05-03T19:56:01.566319Z

nice!

wilkerlucio 2022-05-03T19:56:21.631199Z

I think we can extract this pattern somehow in a syntax thing, to avoid writing the pred + complement pred

wilkerlucio 2022-05-03T19:57:59.725769Z

humm, but now not sure if that works, it needs to splice the thing

Ben Sless 2022-05-03T19:58:09.771209Z

May not need the complement

Ben Sless 2022-05-03T19:58:58.990409Z

Important part was judicious use of dot, which is a stop point for the regex pattern looking left

Ben Sless 2022-05-03T19:59:25.933989Z

problem is without it you get more than one success

Ben Sless 2022-05-03T19:59:47.765409Z

What is this for?

wilkerlucio 2022-05-03T20:00:44.993509Z

@ben.sless there is a problem also when the matching is at the end of the collection, in this example it fails to get the correct results:

(m/search
    [1 2 true 3 "foo" "bar" 4 5 "not after thing" 6 true 34 "more" "text" "thing"]
    [_ ... true _ . (m/pred string? !s) ... . (m/pred (complement string?)) . _ ...] !s
    )

Ben Sless 2022-05-03T20:03:38.397169Z

Fun! Try to add another pattern where the vector ends before the complement

Danny 2022-05-03T21:47:04.833609Z

Basically this but how to DRY it?

(m/search
  [1 2 true 3 "foo" "bar" 4 5 "not after thing" 6 true 34 "more" "text" "thing"]

  [_ ... true _ . (m/pred string? !s) ..1] !s
  [_ ... true _ . (m/pred string? !s) ..1 (m/pred (complement string?)) . _ ...] !s)
=>
(["foo" "bar"] ["more" "text" "thing"])

Danny 2022-05-03T21:48:25.064689Z

Can’t seem to splice ~@ patterns defined with m/with

Danny 2022-05-03T21:48:59.351099Z

Seems like the regex $ (end) operator is missing