| Bytes | Lang | Time | Link |
|---|---|---|---|
| 044 | Ruby | 250507T170310Z | Jordan |
| 068 | Perl 5 MListUtil=max p | 190623T024110Z | Xcali |
| 010 | Brachylog | 190621T184650Z | Unrelate |
| 189 | Prolog | 151120T143549Z | Emigna |
| 055 | ><> | 151124T060849Z | torcado |
| 072 | ES6 | 151121T170144Z | Neil |
| 054 | Python 2/3 | 151121T235144Z | TLW |
| 070 | C | 151122T125352Z | han |
| 127 | Perl 5 | 151122T082526Z | msh210 |
| 119 | Minkolang 0.12 | 151120T091257Z | El'e |
| 059 | Ruby | 151120T232810Z | Neil Sla |
Perl 5 -MList::Util=max -p, 68 bytes
s|..(?=(.))|$t=max$t,ord($&)%15%4+ord($1)%15%4 .$&.$1|eg;$_=$t;s/.//
Grabs each set of three characters, ignores the . in the middle, maps the addition of the other two to an integer in the range 0-4, concatenates that to the front of the emoticon face, then sorts by that. Grabs the last entry (most awake), removes the number from the front, and outputs it.
Prolog, 205 189 bytes
Code
r([X|T],[N|B],M):-N=M,write(X);r(T,B,M).
p(X):-findall(S,sub_atom(X,_,3,_,S),L),findall(E,(nth1(I,L,E),I mod 2=\=0),R),maplist(atom_codes,R,Q),maplist(sum_list,Q,S),min_list(S,M),r(R,S,M).
Explanation
r([X|T],[N|B],M):-N=M,write(X);r(T,B,M).
p(X):-findall(S,sub_atom(X,_,3,_,S),L), % L = all sublists of length 3
findall(E,(nth1(I,L,E),I mod 2=\=0),R), % R = every other element of L
maplist(atom_codes,R,Q), % Q = list of decimal ascii codes
created from R
maplist(sum_list,Q,S), % S = list of sums of R's lists
min_list(S,M), % M = minimum sum
r(R,S,M). % Prints first element in R with sum M
Example
>p('-.=.-.o.o.=.o.-.o.=.-.o.=.o.-').
-.=
Edit: Saved 16 bytes by unifying r-clauses with OR.
><>, 55 bytes
<v~i:i&0"."0
>i:@+:&:@)?v&~i0(?v
^?)0i:r~r&~<;ooo$r<
Outputs most awake face.
Since the ASCII values for -, =, and o increase respectively, I could use that to my advantage. Basically it adds the values of the current and previous eye part, check if it's a higher value than before, if it is it saves the new value and updates what face that represents, then loops until the end of the input. Then outputs the face that remains. (I'm very pleased at how nicely all the code fits in place)
ES6, 81 72 bytes
a=>"-.-,-.=,=.-,-.o,=.=,o.-,=.o,o.=,o.o".split`,`.find(b=>a.includes(b))
Probably requires Chrome 45 or Firefox 41.
Thanks to @ETHproductions for saving 9 bytes.
Python 2/3, 54 56 bytes
lambda x:".".join(max(zip(x[::2],x[2::2]),key=sorted))
Just wanted to take an alternative tack to xsot's recursive answer.
This takes the best (or worst?) tuple of adjacent pairs of eyes and joins them together.
Replace max with min to return the most sleepy (as is this returns the most awake)
Seems to work, using the following test:
for line in """-.- GIVES -.-
=.- GIVES =.-
o.o GIVES o.o
o.-.= GIVES o.-
=.-.= GIVES =.- OR -.=
o.-.= GIVES o.-
-.-.= GIVES -.=
o.o.- GIVES o.o
=.=.=.o GIVES =.o
-.=.=.= GIVES =.=
=.o.-.= GIVES =.o
o.-.o.=.= GIVES o.=
-.o.-.=.= GIVES -.o OR o.- OR =.=
o.o.o.o.o GIVES o.o
-.-.-.-.- GIVES -.-
o.=.=.-.-.o.o GIVES o.o
-.=.-.o.o.=.o.-.o.=.-.o.=.o.- GIVES o.o""".splitlines():
inp, _, opts = line.partition(" GIVES ")
optst = opts.split(" OR ")
act = f(inp)
print(inp, "expected", opts, "got", act, "equal?", act in optst)
Which gives the following result:
-.- expected -.- got -.- equal? True
=.- expected =.- got =.- equal? True
o.o expected o.o got o.o equal? True
o.-.= expected o.- got o.- equal? True
=.-.= expected =.- OR -.= got =.- equal? True
o.-.= expected o.- got o.- equal? True
-.-.= expected -.= got -.= equal? True
o.o.- expected o.o got o.o equal? True
=.=.=.o expected =.o got =.o equal? True
-.=.=.= expected =.= got =.= equal? True
=.o.-.= expected =.o got =.o equal? True
o.-.o.=.= expected o.= got o.= equal? True
-.o.-.=.= expected -.o OR o.- OR =.= got =.= equal? True
o.o.o.o.o expected o.o got o.o equal? True
-.-.-.-.- expected -.- got -.- equal? True
o.=.=.-.-.o.o expected o.o got o.o equal? True
-.=.-.o.o.=.o.-.o.=.-.o.=.o.- expected o.o got o.o equal? True
C, 70 bytes
char*f(char*s){char*p=s[3]?f(s+2):s;return*s+s[2]>*p+p[2]?s[3]=0,s:p;}
The function returns the most awake face. It modifies the input string in place, so as to return a null-terminated string.
Perl 5, 127 bytes
%h=qw[- 2 = 1];sub r{$b=0;$b+=$h{$_}for split'',pop;$b}($_)=<>;@a='o.o';while(/.../g){push@a,$& if(r$&)>r$a[-1];--pos}say$a[-1]
(I'm sure it's doable more briefly.) How it works:
- Grab each three-character string from the string, with overlap by one (that's what the
--posdoes). - Append that three-character string to an array if its value exceeds that of the last element of the array; here, "value" is just the sum of its characters' values in sleepiness.
- Print the last element of the array.
Minkolang 0.12, 119 bytes
At first, I tried doing this short and really golfy. I gave up and went for something a bit more "fun", but still relatively golfy.
>2@fv$oI2:[9[i$z3[iciz1+q=]++3=tt"^"3zpt]$x$x]IX3140w
o.o1F
o.=1$
=.o1+
=.=12
o.-1:
-.o11
=.-1+
-.=13
-.-1[
/c0i<
\qO].
Explanation
But really, click on the link above and click Slow! Anyway...
>2@fv
This skips over the fv, which will be important later.
$o Read in whole input as characters
I2: Half the stack length
[ Open for loop (for each face)
9[ Open another for loop - 9 repeats
i$z Stores loop counter in register
3[ Open another for loop - 3 repeats
ic Copy char 1/2/3
iz1+q Retrieve char from lookup table
= 1 if equal, 0 otherwise
] Close for loop
++ Add twice
3= 1 if equal to 3, 0 otherwise
tt t Ternary - executes first part when 0,
second part otherwise
"^"3zp Put a ^ next to the face that matched
] Close lookup for loop
$x$x Dump first two characters
] Close for loop
IX Dump the whole stack
31 Push a 3, then a 1
40w Wormhole to (4,0) in the code
What all that did was put a ^ next to the faces that matched. So now the codebox might look like this:
>2@fv$oI2:[9[i$z3[iciz1+q=]++3=tt"^"3zpt]$x$x]IX3140w
o.o1F
o.=1$
=.o1+
=.=^2 <-- caret
o.-^: <-- caret
-.o11
=.-1+
-.=^3 <-- caret
-.-1[
/c0i<
\qO].
Without the comments, of course. Now, the 40w wormhole sent the instruction pointer to v, which immediately redirects it onto F. Now, F is a "gosub" command. It's like a goto, but you can return to where you called it. At the time F is encountered, the stack is [3,1], so it jumps to the 1 (maybe) on the second row. As the program counter was heading downwards, it continues, pushing 1s onto the stack along the way. That is...until it hits a ^, at which point it's redirected back up, where it pushes each 1 again. The instruction pointer then hits f, which restores its position and direction (when F was encountered earlier). For convenience, I will take the following code and change its layout. (The </\ serve to redirect the instruction pointer as needed.)
$+ Sum up the whole stack
2: Divide by 2 (because each 1 was pushed twice)
1+ Add 1 (shift down one row)
3[ Open for loop - 3 repeats
i Push loop counter
0c Copy top of stack
q Retrieve face character
O Output as character
]. Close for loop and stop when it's done.
I'm actually kinda proud of how I used multiple features unique to Minkolang that I haven't often used before. Mainly the ternary and the gosub. Anyway, there you have it!
Ruby, 59 bytes
Function returns sleepiest face, using the sorting trick.
f=->(s){s.split(?.).each_cons(2).min_by{|e|e.sort}.join(?.)}
Called like this:
f.call("o.=.=.-.-.o.o")
# => "-.-"
Works on awkward eye order due to internal sort of eyes:
f.call("=.-.o")
# => "=.-"