1. Euphoria sucks at golfing
- Posted by ghaberek (admin) May 07, 2014
- 1709 views
It's been a while since we've discussed code golf. I think it's a good mental exercise and quite a bit of fun. Unfortunately, due to its verbose nature, Euphoria results tend to be a worse than other languages, especially curly bracket languages that lack "end <construct>" type statements.
Here's a fun problem: Bring out the inner llama of a sentence
Your objective is to take input like
Pie is good. I just ate a bunch of pies early this morning. Actually, it was closer to the afternoon. Mornings are good.
and create an array of the indexes of the string where the letters that make up the word "Llama" appear (one of each in order). For example, let me show the letters pointed at with carets to show the indexes:
Pie is good. I just ate a bunch of pies early this morning. Actually, it was closer to the afternoon. Mornings are good. ^ ^ ^ ^ ^
So the array would look like:
[44, 67, 76, 105, 114]
(If your application uses a indexing that's not 0-based, the numbers will look different. That's fine.)
If the text has no llama, then the array should be empty, nil, null, or undefined.
Any code language is accepted. This is a code-golf contest, so the least characters win!
Here is my solution...
include std/text.e object T = gets(0), t = lower(T), L = "llama", X = repeat(0,5) for i = 1 to length(L) do if i = 1 then X[i] = find(L[i],t) else X[i] = find(L[i],t,X[i-1]+1) end if if X[i] = 0 then X = {} exit end if end for ? X
Output:
{45,68,77,106,115}
Total of 180 characters (worst by far according to other answers). It accepts a string via STDIN, e.g.
echo "Pie is good. I just ate a bunch of pies early this morning. Actually, it was closer to the afternoon. Mornings are good." | eui llama.ex
-Greg
2. Re: Euphoria sucks at golfing
- Posted by DerekParnell (admin) May 07, 2014
- 1652 views
Without rethinking your algorithm, I've managed to trim some off your code.
include std/text.e object t = lower(gets(0)), L = "llama", X = {0}, c for i = 1 to length(L) do c = find(L[i],t,X[$]+1) if c then X &= c else X = {0} exit end if end for ? X[2..$]
A better way to count it would be to count tokens rather than characters. That would make language to language comparisons more meaningful.
3. Re: Euphoria sucks at golfing
- Posted by jimcbrown (admin) May 07, 2014
- 1635 views
Here's my attempt:
include std/text.e object t = lower(gets(0)), L = "llama", X = 0&" " for i = 1 to length(L) do X[i+1] = find(L[i],t,X[i]+1) if X[i+1] = 0 then X = {0} exit end if end for ? X[2..$]
4. Re: Euphoria sucks at golfing
- Posted by gbonvehi May 07, 2014
- 1631 views
Well, it's more descriptive than others. If the include makes up the count, you could compare in uppercase by transforming the input with
t=and_bits(gets(0),#DF)
And here's my entry without much thinking on how to remove the duplicate if
object t=and_bits(gets(0),#DF),s="LLAMA",z=1,r={} for i=1 to length(t) do if t[i]=s[z] then r&=i z+=1 if z=6 then exit end if end if end for if z<6 then r={} end if ?r
Edit: removed unused var
object t=and_bits(gets(0),#DF),s="LLAMA",z=1,r={} for i=1 to length(t) do if and_bits(t[i]=s[z],z<6) then r&=i z+=1 end if end for if z<6 then r={} end if ?r
Edit2: one if removed :)
5. Re: Euphoria sucks at golfing
- Posted by jaygade May 07, 2014
- 1634 views
- Last edited May 08, 2014
I got it down to 150 characters (after whitespace removed). Here's the whitespace version:
object t=and_bits(gets(0),#DF),L="LLAMA",X={},i=1 while length(L) do i=find(L[1],t,i) if i=0 then X={} exit else L=L[2..$] X&=i i+=1 end if end while ?X
Edit: Shortened to 148:
object t=and_bits(gets(0),#DF),L="LLAMA",X={},i=1 while length(L)do i=find(L[1],t,i) if i then L=L[2..$] X&=i i+=1 else X={} exit end if end while ?X
Edit2 Got it down to 147. Here is the short version:
object t=and_bits(gets(0),#DF),L="LLAMA",X={},i=1 while length(L)do i=find(L[1],t,i)if i then L=L[2..$]X&=i i+=1 else X={}exit end if end while ?X
6. Re: Euphoria sucks at golfing
- Posted by DerekParnell (admin) May 07, 2014
- 1609 views
Not tested this one ...
object T = lower(gets(0)), X = {} X &= find('l', T) X &= find('l', T, X[$]+1) X &= find('a', T, X[$]+1) X &= find('m', T, X[$]+1) X &= find('a', T, X[$]+1) if find(0, X) then X = {} end if return X
7. Re: Euphoria sucks at golfing
- Posted by jaygade May 07, 2014
- 1607 views
Whittled down to 141:
object t=and_bits(gets(0),#DF),L="LLAMA",i=0,X={} while length(L) do i=find(L[1],t,i+1) X&=i L=L[2..$] end while if find(0,X) then X={} end if ?X
8. Re: Euphoria sucks at golfing
- Posted by gbonvehi May 07, 2014
- 1597 views
Whittled down to 141:
object t=and_bits(gets(0),#DF),L="LLAMA",i=0,X={} while length(L) do i=find(L[1],t,i+1) X&=i L=L[2..$] end while if find(0,X) then X={} end if ?X
Nice! You can make it even shorter using or to convert to lowercase instead of and to upper, here's one i was using to test:
object t=or_bits(gets(0),32),s="llama",z=1,r={} for i=1 to length(t) do if z<6 and t[i]=s[z] then r&=i z+=1 end if end for if z<6 then r={} end if
9. Re: Euphoria sucks at golfing
- Posted by jaygade May 07, 2014
- 1579 views
I'm not sure that or_bits would work. Aren't you only setting bit 4 and not masking any others?
Hmm, testing finds that you could get some errors, although it should work most of the time.
Edit: My testing finds an off-by-one error, but you might be able to correct for that.
10. Re: Euphoria sucks at golfing
- Posted by jaygade May 07, 2014
- 1568 views
- Last edited May 08, 2014
Not the shortest, but probably the most terse:
include std/regex.e include std/sequence.e include std/utils.e object X=regex:find(new("(?i)(l).*?(l).*?(a).*?(m).*?(a)"),gets(0)) ? iff(atom(X), {}, vslice(X[2..6],2))
Shorter:
include std/regex.e include std/sequence.e object X=regex:find(new("(?i)(l).*?(l).*?(a).*?(m).*?(a)"),gets(0)) if atom(X)then?{}else?vslice(X[2..6],2)end if
11. Re: Euphoria sucks at golfing
- Posted by mattlewis (admin) May 08, 2014
- 1560 views
This gets down to 130:
object o=and_bits(gets(0),#DF),l="LLAMA",x=0,y={} for i=1 to 5 do x=find(l[i],o,x+1)if x=0 then ?{}abort(0)end if y&=x end for ?y
Readable:
object o = and_bits(gets(0),#DF), l="LLAMA", x=0, y={} for i=1 to 5 do x=find(l[i],o,x+1) if x=0 then ?{} abort(0) end if y &= x end for ?y
12. Re: Euphoria sucks at golfing
- Posted by jaygade May 08, 2014
- 1613 views
I got it down to 129 126. Are there any more gains to be had?
object t=or_bits(gets(0),96),L="llama",i=0,X={}for j=1 to 5 do i=find(L[j],t,i+1)X&=i end for if find(0,X) then X={} end if?X -- Ungolfed object t=or_bits(gets(0),96), L="llama", i=0, X={} for j=1 to 5 do i=find(L[j],t,i+1) X&=i end for if find(0,X) then X={} end if ?X
Edit: Stole the "or_bits" idea from gbonhevi above the C example (58 bytes) on the page, using '96' instead of '32'. I'm still afraid of getting false positives, but so far it has proven to be correct.
Edit again: Found the failing sequence: ",,!-!" = "llama".
13. Re: Euphoria sucks at golfing
- Posted by PeteE May 08, 2014
- 1533 views
Are there any more gains to be had?
if find(0,X) then X={} end if ?X
could be replaced with
?X[1..$*not find(0,X)]
14. Re: Euphoria sucks at golfing
- Posted by jaygade May 08, 2014
- 1541 views
Oooh.
Thanks, Pete! That works great. 117 characters. I never think of using $ as an actual number.
15. Re: Euphoria sucks at golfing
- Posted by petelomax May 09, 2014
- 1506 views
This works in Phix (105 characters)
object t=lower(gets(0)),L="llama",i=0for j=1to 5do i=find(L[j],t,i+1)L[j]=i end for?L[1..-not find(0,L)]
Notes: lower() is an autoinclude, I overwrite L with the result as we go, and finally use negative indexes.
Pete
16. Re: Euphoria sucks at golfing
- Posted by mindwalker May 09, 2014
- 1507 views
This works in Phix (105 characters)
object t=lower(gets(0)),L="llama",i=0for j=1to 5do i=find(L[j],t,i+1)L[j]=i end for?L[1..-not find(0,L)]
Notes: lower() is an autoinclude, I overwrite L with the result as we go, and finally use negative indexes.
Pete
I don't have Phix or OpenEuphoria installed anywhere these days, but the "i" object isn't needed just put the initial start index value in L[1]. Try the code below to verify it works. (103 characters)
object t=lower(gets(0)),L=1&"llama"for j=2to 6do L[j]=find(L[j],t,L[j-1]) end for?L[2..-not find(0,L)]
17. Re: Euphoria sucks at golfing
- Posted by PeteE May 09, 2014
- 1491 views
I don't have Phix or OpenEuphoria installed anywhere these days, but the "i" object isn't needed just put the initial start index value in L[1]. Try the code below to verify it works. (103 characters)
object t=lower(gets(0)),L=1&"llama"for j=2to 6do L[j]=find(L[j],t,L[j-1]) end for?L[2..-not find(0,L)]
The first two 'L's will have the same position, since the find starts at the same position as the last letter found. Also when a letter is not found, the slice length will be negative L[2..0] resulting in an error.