meander 2022-05-03

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)

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

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

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

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

how would you guys go about this case?

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

but I want multiple instances of the thing

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

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

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

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

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?

Uhg PDFs … <ptsd dog gif/>

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

Just wondering because your current results look “exploded”

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

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

> 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.

Do you even need ... ?

(I’m a noob)

..1 should probably filter out the empty matches

which of the ...?

..1 means 1 repetition

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

Docs say at least 1

ah, yeah, zero could match too

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

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

I need to get my hands on a repl again 😛

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

..1 = 1 or more things

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

(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"])

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
 ]

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

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)

Did you play around with scan?

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

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

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

moving the ..1 inside m/pred?

I think that's not valid syntax

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

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

🐞 1

maybe not with ... then 😄

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"])

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

I got this far:

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

This match finds only the more next thing

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

Slightly more concise

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

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
  )

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

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

May not need the complement

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

problem is without it you get more than one success

What is this for?

@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
    )

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

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"])

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

Seems like the regex $ (end) operator is missing