haven't finished latest advent prob, but felt I needed a more flexible replace function
Y =: (&{::)(@:]) X =: (&{::)(@:[) M=:@:] T=:(&{)(>@) R =: (&}.) M comments placed on following line to escape line breaks. blank lines are line breaks if it messes up. delitem =: ;@:((1 X {. ]) ; (0 X + 1 X) }. ]) NB. len idx :X str :Y delitemR =: ;@:((1 X {. ]) (,~ <)~ 2 R~ (, <) (0 X + 1 X) }. ]) NB. len idx item list:X str :Y Eli =: ((#M~ ;"0 0 I.@E.) ) NB. returns len idx of matches EliR =: (]delitemR~"1 (1 R)~,~("1)0 X Eli]) NB. replace based on Eli. 2items :X Eli/E. arg:0X list compatible with y :1X EliRI =: (]delitemR~"1 ([: 1 R 0 X) ,~("1 1) 1 X { (0; 0) X Eli]) :: ] NB. replace select indexes of Eli. 2 items tree :x EilR args :0X arg to { (0 first, _1 last etc) :1X. index error makes no replacement. The first delitem is not needed, as delitemR has an optional rest argument. The first 2 right arguments to these functions is length, index (2 1 ) delitemR 3 4,i.8 NB. no boxing needed if just deleting. 3 1 2 3 4 5 6 7 above is same result as delitem The 3rd argument if provided, inserts that at the deletion point. This works either as a boxed list of compatible type to y, or an unlimited amount of "Rest" boxes that are each a compatible type. Replace item can be different size. 2 ;1 ;99 ;44 ) delitemR 3 4,i.8 3 99 44 1 2 3 4 5 6 7 (2 ;1 ;99 44 11 ) delitemR 3 4,i.8 3 99 44 11 1 2 3 4 5 6 7 (_80 ; _5; 'ABCD' ) delitemR a. NB. negative length and idx do something. Other functions produce results compatible with the delitem, E.length-index 3 4 Eli 3 4,i.8 ┌─┬─┐ │2│0│ ├─┼─┤ │2│5│ └─┴─┘ EliR replaces 0X with 1X, but unlike rplc~ returns one string for each act. (3 4; 88 33 ) EliR 3 4,i.8 88 33 0 1 2 3 4 5 6 7 3 4 0 1 2 88 33 5 6 7 if just 1 replacement, still returns a list 61 }."1 ( 'ABCD' ;' XXFFGG' ) EliR a. =>?@ XXFFGGEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcde .... t =. <;._1 ' C Rn Ca Si Rn B Si Rn F Ar Ti B P Ti Ti B F Ar P B Ca Si Th Si Rn Ti' deleting string of boxed sequence 'Rn F' ( (;: 'Rn F') ; '' ) EliR t +-+--+--+--+--+-+--+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+--+--+ |C|Rn|Ca|Si|Rn|B|Si|Ar|Ti|B|P|Ti|Ti|B|F|Ar|P|B|Ca|Si|Th|Si|Rn|Ti| +-+--+--+--+--+-+--+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+--+--+ to replace, make 1 item of (list) compatible type (boxed to make 1 item) ( (;: 'Rn F') ; < ;: 'FFF Gg' ) EliR t +-+--+--+--+--+-+--+---+--+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+--+--+ |C|Rn|Ca|Si|Rn|B|Si|FFF|Gg|Ar|Ti|B|P|Ti|Ti|B|F|Ar|P|B|Ca|Si|Th|Si|Rn|Ti| +-+--+--+--+--+-+--+---+--+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+--+--+ EliRI selects the indexes of E. matches to delete/replace. indexes are in { format. The X argument becomes a tree of 2 items. the left branch is the same arg as EliR. consider these 4 matches (deletes) ( (;: 'Rn') ; '' ) EliR t +-+--+--+--+--+--+--+--+--+--+--+-+--+--+--+-+--+--+-+--+--+--+--+--+--+ |C|Ca|Si|Rn|B |Si|Rn|F |Ar|Ti|B |P|Ti|Ti|B |F|Ar|P |B|Ca|Si|Th|Si|Rn|Ti| +-+--+--+--+--+--+--+--+--+--+--+-+--+--+--+-+--+--+-+--+--+--+--+--+--+ |C|Rn|Ca|Si|B |Si|Rn|F |Ar|Ti|B |P|Ti|Ti|B |F|Ar|P |B|Ca|Si|Th|Si|Rn|Ti| +-+--+--+--+--+--+--+--+--+--+--+-+--+--+--+-+--+--+-+--+--+--+--+--+--+ |C|Rn|Ca|Si|Rn|B |Si|F |Ar|Ti|B |P|Ti|Ti|B |F|Ar|P |B|Ca|Si|Th|Si|Rn|Ti| +-+--+--+--+--+--+--+--+--+--+--+-+--+--+--+-+--+--+-+--+--+--+--+--+--+ |C|Rn|Ca|Si|Rn|B |Si|Rn|F |Ar|Ti|B|P |Ti|Ti|B|F |Ar|P|B |Ca|Si|Th|Si|Ti| +-+--+--+--+--+--+--+--+--+--+--+-+--+--+--+-+--+--+-+--+--+--+--+--+--+ replaces just first (if only 1 index, then return has no leading 1 shape) (0 ,&<~ (;: 'Rn') ; < ;: 'FFF Gg' ) EliRI t +-+---+--+--+--+--+-+--+--+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+--+--+ |C|FFF|Gg|Ca|Si|Rn|B|Si|Rn|F|Ar|Ti|B|P|Ti|Ti|B|F|Ar|P|B|Ca|Si|Th|Si|Rn|Ti| +-+---+--+--+--+--+-+--+--+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+--+--+ replace 2nd and last (and reorder last replace first) (_1 1 ,&<~ (;: 'Rn') ; < ;: 'FFF' ) EliRI t +-+--+--+--+---+-+--+--+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+---+--+ |C|Rn|Ca|Si|Rn |B|Si|Rn|F|Ar|Ti|B|P|Ti|Ti|B|F|Ar|P|B|Ca|Si|Th|Si|FFF|Ti| +-+--+--+--+---+-+--+--+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+---+--+ |C|Rn|Ca|Si|FFF|B|Si|Rn|F|Ar|Ti|B|P|Ti|Ti|B|F|Ar|P|B|Ca|Si|Th|Si|Rn |Ti| +-+--+--+--+---+-+--+--+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+---+--+ fold left recursive replace but only up to 2 times (0 ,&<~ (;: 'Rn') ; < ;: 'FFF' ) EliRI^:2 t +-+---+--+--+---+-+--+--+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+--+--+ |C|FFF|Ca|Si|FFF|B|Si|Rn|F|Ar|Ti|B|P|Ti|Ti|B|F|Ar|P|B|Ca|Si|Th|Si|Rn|Ti| +-+---+--+--+---+-+--+--+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+--+--+ fold right recursive replace all (_1 ,&<~ (;: 'Rn') ; < ;: 'FFF' ) EliRI^:_ t +-+---+--+--+---+-+--+---+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+---+--+ |C|FFF|Ca|Si|FFF|B|Si|FFF|F|Ar|Ti|B|P|Ti|Ti|B|F|Ar|P|B|Ca|Si|Th|Si|FFF|Ti| +-+---+--+--+---+-+--+---+-+--+--+-+-+--+--+-+-+--+-+-+--+--+--+--+---+--+ this differs from rplc~ in that a recursive approach has potential to create a new match on replaced text. infinite loop potential. use rplc if you want rplc behaviour. ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm