Fork me on GitHub
#meander
<
2022-05-03
>
wilkerlucio18:05:29

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)

wilkerlucio18:05:49

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

wilkerlucio18:05:56

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

wilkerlucio18:05:31

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

wilkerlucio18:05:59

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

wilkerlucio18:05:07

how would you guys go about this case?

Danny18:05:46

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

wilkerlucio18:05:04

but I want multiple instances of the thing

wilkerlucio18:05:19

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

Danny18:05:38

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

wilkerlucio18:05:10

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

Danny18:05:07

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

wilkerlucio18:05:22

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?

Danny18:05:10

Uhg PDFs … <ptsd dog gif/>

wilkerlucio18:05:10

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

Danny18:05:33

Just wondering because your current results look “exploded”

wilkerlucio18:05:09

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

wilkerlucio18:05:21

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

Danny18:05:24

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

Danny18:05:29

Do you even need ... ?

Danny18:05:33

(I’m a noob)

Danny18:05:49

..1 should probably filter out the empty matches

wilkerlucio19:05:11

which of the ...?

wilkerlucio19:05:22

..1 means 1 repetition

wilkerlucio19:05:36

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

Danny19:05:50

Docs say at least 1

wilkerlucio19:05:59

ah, yeah, zero could match too

wilkerlucio19:05:21

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

Danny19:05:47

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

Danny19:05:57

I need to get my hands on a repl again 😛

wilkerlucio19:05:07

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

Danny19:05:54

..1 = 1 or more things

wilkerlucio19:05:53

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

wilkerlucio19:05:04

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

wilkerlucio19:05:24

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
 ]

Danny19:05:40

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

wilkerlucio19:05:40

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)

Danny19:05:54

Did you play around with scan?

wilkerlucio19:05:17

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

wilkerlucio19:05:21

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
Danny19:05:22

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

wilkerlucio19:05:07

moving the ..1 inside m/pred?

wilkerlucio19:05:22

I think that's not valid syntax

Danny19:05:39

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

wilkerlucio19:05:47

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

1
Danny19:05:24

maybe not with ... then 😄

Ben Sless19:05:08

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

wilkerlucio19:05:47

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

Danny19:05:08

I got this far:

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

Ben Sless19:05:10

This match finds only the more next thing

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

Ben Sless19:05:07

Slightly more concise

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

Ben Sless19:05:03

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
  )

wilkerlucio19:05:21

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

wilkerlucio19:05:59

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

Ben Sless19:05:09

May not need the complement

Ben Sless19:05:58

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

Ben Sless19:05:25

problem is without it you get more than one success

Ben Sless19:05:47

What is this for?

wilkerlucio20:05:44

@UK0810AQ2 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 Sless20:05:38

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

Danny21:05:04

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

Danny21:05:25

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

Danny21:05:59

Seems like the regex $ (end) operator is missing