%!PS % begin included library code % see https://codeberg.org/Firedrake/postscript-libraries/ /strconcat % (a) (b) -> (ab) { [ 3 -1 roll s2a aload length 2 add -1 roll s2a aload pop ] a2s } bind def /a2s { 2 dict begin /i exch def i length dup string /o exch def 1 sub 0 exch 1 exch { dup i 3 -1 roll get o 3 1 roll put } for o end } bind def /test.end { ( ) print test.count 0 gt { (Passed ) print test.pass (...) cvs print (/) print test.count (...) cvs print ( \() print test.pass 100 mul test.count idiv (...) cvs print (%\)) print (\r\n) print } if } bind def /toset { % array -> dict of (value, true) << exch { true } forall >> } bind def /test.start { print (:) print /test.pass 0 def /test.count 0 def } bind def /test { /test.count test.count 1 add def { /test.pass test.pass 1 add def } { ( ) print test.count (....) cvs print (-fail) print } ifelse } bind def /enumerate.array { 1 dict begin /a exch def [ 0 1 a length 1 sub { [ exch dup a exch get ] } for ] end } bind def /strsplit % (ajbjc) (j) -> [ (a) (b) (c) ] { 1 dict begin /sep exch def [ exch { dup length 0 eq { pop exit } { sep search { exch pop dup length 0 eq { pop } { exch } ifelse } { () } ifelse } ifelse } loop ] end } bind def /s2a { [ exch { } forall ] } bind def /strjoin % [(a) (b) (c)] (j) -> (ajbjc) { 3 dict begin /j exch def dup 0 get /out exch def /first true def { first { pop /first false def } { out j strconcat exch strconcat /out exch def } ifelse } forall out end } bind def % end included library code /goatlatin { 0 dict begin /vowels (aeiouAEIOU) s2a toset def [ exch ( ) strsplit enumerate.array { aload pop /c exch s2a def /i exch def [ c aload pop vowels c 0 get known not { c length -1 roll } if 109 97 i 1 add { 97 } repeat ] a2s } forall ] ( ) strjoin end } bind def (goatlatin) test.start (I love Perl) goatlatin (Imaa ovelmaaa erlPmaaaa) eq test (Perl and Raku are friends) goatlatin (erlPmaa andmaaa akuRmaaaa aremaaaaa riendsfmaaaaaa) eq test (The Weekly Challenge) goatlatin (heTmaa eeklyWmaaa hallengeCmaaaa) eq test test.end