| Bytes | Lang | Time | Link |
|---|---|---|---|
| 034 | Vyxal | 240922T061704Z | emanresu |
| 035 | Jelly | 210220T232839Z | caird co |
| nan | Nondeterministic Turing Machine | 150412T140411Z | jazzpi |
| nan | Python 3 | 180601T212803Z | Alexande |
| nan | I wasn't going for size | 150413T143807Z | Kenneth |
| 288 | Java | 150413T093501Z | Landei |
| 299 | Scala | 150412T203206Z | Dave Swa |
| 602 | ><> | 150412T144119Z | David D |
| 319 | C# | 150409T082815Z | VisualMe |
| 050 | Pyth | 150409T111510Z | isaacg |
| 135 | Javascript 122 | 150409T223454Z | Ismael M |
| 177 | Ruby | 150410T124223Z | Heals |
| 811 | Perl | 150409T233704Z | Ilmari K |
| 437 | fish yes | 150410T092551Z | xebtl |
| 164 | JavaScript ES6 | 150410T090523Z | edc65 |
| 146 | Haskell | 150409T152242Z | Zgarb |
| 156 | Python 3 | 150409T095526Z | xnor |
| nan | 150409T191822Z | franklyn | |
| 9162 | CJam | 150409T124544Z | Optimize |
| 234 | Python 2 | 150409T085351Z | Logic Kn |
| 262 | HaskellParsec | 150409T114428Z | swish |
| 142 | Haskell | 150409T110438Z | proud ha |
| 186 | Python 3 | 150409T091929Z | Sp3000 |
Vyxal, 34 bytes
Lƛ»√ĿẆ;»ðøḂτ`,<.`+øṀ⌈↔vṄ;f≬ȧ?=c¤$∨
I initially attempted to solve this with regex, but it's actually quite tricky, so this is a bruteforcer. Despite technically being \$O(9^n)\$ in the length of the input, thanks to Vyxal's laziness this will actually terminate within reasonable time for strings containing 5ish fish, although it will take ages for invalid strings. This could be 29 bytes with looser I/O (returning 0 in the fail case, returning a list of fish)
Lƛ ; # Over every integer from 1 to the input length
↔ # Get all combinations of that length of
»√ĿẆ;» # Compressed integer
τ # Converted to custom base
ðøḂ # "< >", yielding "><> >><> ><>> ><<<> "
`,<.`+ # Append ",<." (half a crab)
øṀ # Mirror
⌈ # Split on spaces
vṄ # And join each combination on spaces
f c # Out of all of those
≬--- # Find one where
ȧ # Removing whitespace
?= # Yields the input?
¤$∨ # Return nothing otherwise
Jelly, 35 bytes
“¦¿Æ×‘B;¬$ị⁾<>“,<..>,”ṭ
J¢ṗẎẎ⁼¥Ƈ⁸ḢK
This is brutally inefficient, clocking in at around (I believe) \$O(9^{n^2})\$, and times out on TIO for strings of length \$7\$ or more
Returns 0 if the input cannot be interpreted as fish
A much faster version is 38 bytes, timing out for length \$21\$ or more
How it works
Similar to isaacg's Pyth answer, we generate all possible fish strings, then look for the one(s) equal to the input
“¦¿Æ×‘B;¬$ị⁾<>“,<..>,”ṭ - Helper link. Returns a list of fish
“¦¿Æ×‘ - [5,11,13,17]
B - Convert to binary; [[1,0,1],[1,0,1,1],[1,1,0,1],[1,0,0,0,1]]
¬ - Logical NOT of each bit; [[0,1,0],[0,1,0,0],[0,0,1,0],[0,1,1,1,0]]
; $ - Concatenate to the bits; [[1,0,1],[1,0,1,1],...,[0,0,1,0],[0,1,1,1,0]]
ị⁾<> - Index into "<>", replacing 1 with < and 0 with >
“,<..>,” - Yield the crab
ṭ - Append it to the fish
J¢ṗẎẎ⁼¥Ƈ⁸ḢK - Main link. Takes a fish F of length n on the left
J - Yield [1, 2, ..., n]
¢ - Get the list of fish
ṗ - For each i in 1,2,...,n get the i'th Cartesian power of the fish
Ẏ - Concatenate into a list of lists
¥Ƈ - Keep those lists for which the following is true:
Ẏ - When concatenated into a flat list of characters,
⁼ - the list equals
⁸ - the input F
Ḣ - Take the first list of fish
K - Join by spaces
Non-deterministic Turing Machine, 20 states, 52 transitions (882 bytes maybe)
How do you convert this to bytes? I've written the files (absolutely not golfed) to execute this machine with Alex Vinokur's Simulator of a Turing Machine1. wc -c outputs the following (excluding the description file and the input files):
12 alphabet
49 meta
740 rules
81 states
882 total
Anyways, I was preparing for my Computer Science A-Levels, so I thought this would be a good exercise (I don't know what I was thinking). So here's the definition:
$$\begin{align*} M & = (Q, \Sigma, \iota, \sqcup, A, \delta) \\ Q & = \{q_{0},q_{1},q_{2},q_{3},q_{4},q_{5},q_{6},q_{7},q_{8},q_{9},q_{10},q_{11},q_{12},q_{13},q_{14},q_{15},q_{16},q_{17},q_{18},q_{19}\} \\ \Sigma & = \{< \: ; \: > \: ; \: , \: ; \: . \: ; \: X \: ; \: $\} \\ \iota & = q_0 \\ \sqcup & = $ \\ A & = \{q_0, q_5\} \end{align*}$$

(the transition function)
Excuse the bad image, but I couldn't be bothered with redrawing this thing on a computer. If you actually want to decipher the transition rules, I recommend you read through the rules file I linked above.
I've used Xs instead of spaces because spaces are hard to visualize here and the simulator doesn't accept spaces in the alphabet.
The concept is fairly simple - q1 to q4 are used to catch right-facing fishes, q11 to q14 are used to catch left-facing fishes, q15 to q19 for crabs and the q5 to q10 blob is simply for inserting a space and moving all following characters one to the right.
If the string is interpretable, it accepts the string and the tape contains the string with spaces inserted. Otherwise it rejects the string (I guess this counts as no output - emptying the tape would be pretty easy but would require lots of transition rules and I don't think it would make the transition function prettier to look at).
1 Note: It's difficult to compile. I had to edit the src/tape.cpp file and replace LONG_MAX with 1<<30 and then go to the demo directory, edit the Makefile to replace EXE_BASENAME with turing.exe and execute make. Then go to the directory with the files I've written and execute /path/to/turing/download/src/turing.exe meta.
Python 3, 166 164 bytes
def z(s,p=''):[z(s[len(f):],p+' '+s[:len(f)])for f in'<>< <><< <<>< <>>>< ><> >><> ><>> ><<<> ,<..>,'.split(' ')if s.startswith(f)]if s else print(p[1:])
z(input())
Recursive solution. Late to the party, but I thought I'd post it anyway since it beats Sp3000's by 20 22 bytes without having to brute-force the answer.
I wasn't going for size, but here is an easy to understand way of doing this in Dart.
const List<String> fish = const [
"><>",
"<><",
">><>",
"<><<",
"><>>",
"<<><",
"><<<>",
"<>>><",
",<..>,"
];
String fishy(String input) {
var chars = input.split("");
if (chars.isEmpty || !chars.every((it) => [">", "<", ",", "."].contains(it))) {
throw new Exception("Invalid Input");
}
var result = [];
var i = 0;
var buff = "";
while (i < chars.length) {
buff += chars[i];
if (fish.contains(buff)) {
result.add(buff);
buff = "";
} else if (chars.length == 6) {
return "";
}
i++;
}
return result.join(" ");
}
void main() {
print(fishy(",<..>,><<<>,<..>,><>,<..>,<>>><,<..>,><>>,<..>,<<><,<..>,<><,<..>,>><>"));
}
Java, 288 bytes
public class F{public static void main(String[]q){d("",q[0]);}static System y;static void d(String a,String b){if(b.isEmpty()){y.out.println(a);y.exit(0);}for (String s : "><> <>< >><> <><< ><>> <<>< ><<<> <>>>< ,<..>,".split(" "))if(b.startsWith(s))d(a+" "+s,b.substring(s.length()));}}
Formatted:
public class F {
public static void main(String[] q) {
d("", q[0]);
}
static System y;
static void d(String a, String b) {
if (b.isEmpty()) {
y.out.println(a);
y.exit(0);
}
for (String s : "><> <>< >><> <><< ><>> <<>< ><<<> <>>>< ,<..>,".split(" "))
if (b.startsWith(s)) d(a + " " + s, b.substring(s.length()));
}
}
Scala, 299 Bytes
type S=String
type L[T]=List[T]
def c(s:S):L[L[S]]={val f=List("><>","<><",">><>","<><<","><>>","<<><","><<<>","<>>><",",<..>,").filter(s.startsWith);if(f.isEmpty)List(List(s)) else f.flatMap(i => c(s.drop(i.size)).map(i::_))}
def p(s:S)=println(c(s).find(_.last.isEmpty).fold("")(_.mkString(" ")))
Test Cases
val tests = Seq("><>", "<><", ">><>", "<><<", ">><>", "<><<", "><<<>", "<>>><", ",<..>,", "><>><>", "><><><", ",<..>,<><", "<<<><><<<>>><>><>><><><<>>><>><>>><>>><>><>><<><", "<<><><<<>>><>><>><><><<>>><>><>>><>>><>><>><<><")
tests.foreach(p)
Output
><>
<><
>><>
<><<
>><>
<><<
><<<>
<>>><
,<..>,
><> ><>
><> <><
,<..>, <><
<<>< ><<<> >><> ><> ><> <>< <>>>< >><> >><> >><> ><>> <<><
><>, 602 bytes
0&>i:0)?vr>:5%4-?v}:5%?;}:5%1-?;}:5%1-?;}:5%2-?;}:5%4-?;}&~0& v
\ / >:5%2-?v}:5%2-?v}:5%?v}:5%2-?v} v
&:?v;>*} ^ v < >:5% ?v}:5%?v} :5% ?v}:5%2-?v}v
v&-1< ^48< >: 5%2-?v}:5%2- ?v&1+&0}}v
> :?v~^ >:5%?v}:5%?v}:5%2- ?v}:5% ?v} v
^~v?%8:< >:5%2-?v}: 5%2-?v} :5%2- ?v}:5%?v}v
^{< >0>=?;:v >: 5% ?v}:5% ?v&1+&0}}v
^lo~< < > > > > > > > 02.
\}*48^?=i: < <
A solution in Fish, probably very golfable but it's my first ><> program. It takes its input from the input stack and runs on the online ><> interpreter.
How it works :
A loop reads all the input and stacks it, reverse it and put a -1 on the bottom wich will mark that parsing is complete (all characters stay on the stack until the string is deemed parsable).
The parsing uses the fact all characters are different modulo 5, and all patterns are deterministic except <><< and ><>>. Parsed characters are put on the bottom of the stack.
When a pattern is complete, if -1 is on top, all characters are printed, otherwise a space is added and the program loops.
If <><< or ><>> are encountered, the register is incremented (0 at the start), and a 0 is placed on the stack before the last character (so that <>< or ><> stays after rollback). If an error appears afterwards during parsing, the register is decreased, all characters after the 0 are put back on top (except spaces thanks to a %8=0 test).
If an error is detected while the register is 0, or inside the crab, the program just ends immediately.
C# - 319 bytes
This solution is shamefully simple, hardly anything to Golf. It's a complete program, takes input as a line from STDIN, and outputs the result to STDOUT.
using C=System.Console;class P{static void Main(){C.Write(S(C.ReadLine()));}static string S(string c){int i=c.LastIndexOf(' ')+1;foreach(var o in"<>< ><> <<>< ><>> >><> <><< ><<<> <>>>< ,<..>,".Split()){string k=c+"\n",m=c.Substring(i);if(m==o||m.StartsWith(o)&&(k=S(c.Insert(i+o.Length," ")))!="")return k;}return"";}}
It simply attempts to match each fish to the first position after a space (or at the start of the string), and matches each type of fish with it. If the fish fits, then it recursively calls the solver after inserting a space after the fish, or simply returns it's input (with a \n for output reasons) if the unmatched string is literally the fish (i.e. we've found a solution).
I haven't made much of an attempt to give the fish string the usual kolmogorov treatment, because it isn't all that long, and I can't find a cheap way to reverse a string in C# (I don't think LINQ will pay), so there may be some opportunity there, but I somewhat doubt it.
using C=System.Console;
class P
{
static void Main()
{
C.Write(S(C.ReadLine())); // read, solve, write (no \n)
}
static string S(string c)
{
int i=c.LastIndexOf(' ')+1; // find start of un-matched string
// match each fish
foreach(var o in"<>< ><> <<>< ><>> >><> <><< ><<<> <>>>< ,<..>,".Split())
{
string k=c+"\n", // set up k for return if we have finished
m=c.Substring(i); // cut off stuff before space
if(m==o|| // perfect match, return straight away
m.StartsWith(o)&& // fish matches the start
(k=S(c.Insert(i+o.Length," "))) // insert a space after the fish, solve, assign to k
!="") // check the solution isn't empty
return k;
}
// no fish match
return"";
}
}
Pyth, 64 48 50 bytes
#jdhfqzsTsm^+msXtjCk2U2"<>""
\r.1"",<..>,"dlzB
Version that doesn't take forever (O(9n/3)) here, in 52 bytes.
This is the brute force approach, generate all sequences and check whether any sum to the input. Fish diagrams compressed as characters, whose binary representations are the > and <. The whole thing is wrapped in a try-catch block so that no output occurs when no results are found.
This is an O(9n) solution.
Some characters are stripped above, because control characters are used. They are reproduced faithfully at the link above.
xxd output:
0000000: 236a 6468 6671 7a73 5473 6d5e 2b6d 7358 #jdhfqzsTsm^+msX
0000010: 746a 436b 3255 3222 3c3e 2222 0a5c 7212 tjCk2U2"<>"".\r.
0000020: 141b 1d2e 3122 222c 3c2e 2e3e 2c22 646c ....1"",<..>,"dl
0000030: 7a42 zB
Javascript (122 135 bytes)
Not the most golfed here, could be stripped down a little.
This one is regex based, and a tad hard to figure out what is going on.
alert(prompt(R=RegExp,r='(<<?><|><>>?|,<\.\.>,|>><>|><<<>|<><<|<>>><)').match(R('^'+r+'+$'))[0].split(R(r+'(?=[>,]|$)','g')).join(' '))
This one is a one-liner.
Basically, I check the syntax and then I split the string based on the chars and join it together.
It throws an exception when you give it an invalid input.
If it can't throw exceptions (126 139 bytes):
(i=prompt(R=RegExp,r='(<<?><|><>>?|,<\.\.>,|>><>|><<<>|<><<|<>>><)')).match(R('^'+r+'+$'))&&alert(i.split(R(r+'(?=[>,]|$)','g')).join(' '))
Both are one-liners.
Both work the same way.
Thank you @edc65 for detecting the edge case that wasn't working well.
You can test it here (output will be written to the document).
It is based on the version that throws exceptions when you introduce invalid code.
var alert=console.log=function(s){document.write(s)+'<br>';};
try{
alert(prompt(R=RegExp,r='(<<?><|><>>?|,<\.\.>,|>><>|><<<>|<><<|<>>><)').match(R('^'+r+'+\x24'))[0].split(R(r+'(?=[>,]|\x24)','g')).join(' '));
}catch(e){console.log(e);}
(Currently, there's a bug on stack snippets, I've posted in on meta It was already asked yesterday. For it to work, I've replaced $ with \x24, which has the same output. You can read about the bug here: http://meta.codegolf.stackexchange.com/questions/5043/stack-snippets-messing-with-js)
Ruby, 177 bytes
Not the shortest but the first one in ruby:
def r(e,p,m)t='';p.each{|n|t=e.join;return r(e<<n,p,m)if m=~/^#{t+n}/};(m==t)?e:[];end
puts r([],%w(><<<> <>>>< ><>> <<>< >><> <><< ><> <>< ,<..>,),gets.strip).join(' ')
The attempt here is to recursively extend a regexp and match it against the input.
If a longer match is found r() will recurse, if not it will check if the last match consumes the whole input string and only then output it with added spaces.
Perl, 81 + 1 bytes
/^((>><>|><(|>|<<)>|<><<|<(|<|>>)><|,<\.\.>,)(?{local@a=(@a,$2)}))*$(?{say"@a"})/
This code expects the input in the $_ variable; run this with Perl's -n switch (counted as +1 byte) to apply it to each input line, e.g. like this:
perl -nE '/^((>><>|><(|>|<<)>|<><<|<(|<|>>)><|,<\.\.>,)(?{local@a=(@a,$2)}))*$(?{say"@a"})/'
This code uses Perl's regexp engine (and specifically its embedded code execution feature) to perform an efficient backtracking search. The individual fishes found are collected in the @a array, which is stringified and printed if the match is successful.
This code also uses the Perl 5.10+ say feature, and so must be run with the -E or -M5.010 switch (or use 5.010;) to enable such modern features. By tradition, such switches used solely to enable a particular version of the language are not included in the byte count.
Alternatively, here's a 87-byte version that requires no special command-line switches at all. It reads one line from stdin, and prints the result (if any) to stdout, without any trailing linefeed:
<>=~/^((>><>|><(|>|<<)>|<><<|<(|<|>>)><|,<\.\.>,)(?{local@a=(@a,$2)}))*$(?{print"@a"})/
Ps. If printing an extra space at the beginning of the output was allowed, I could trivially save two more bytes with:
/^((>><>|><(|>|<<)>|<><<|<(|<|>>)><|,<\.\.>,)(?{local$a="$a $2"}))*$(?{say$a})/
fish (yes, that fish), 437 bytes
This strikes me as one of those programming tasks where exactly one language is right.
#!/usr/bin/fish
set the_fishes "><>" "<><" ">><>" "<><<" "><>>" "<<><" "><<<>" "<>>><" ",<..>,"
set my_fishes
function startswith
set -l c (echo -n $argv[2]|wc -c)
echo $argv[1]|cut -c(math $c+1)-
test $argv[2] = (echo $argv[1]|cut -c-$c)
end
function pickafish
set -l fix 1
while true
if test $fix -gt (count $the_fishes); return 1; end
if not set rest (startswith $argv[1] $the_fishes[$fix])
set fix (math $fix+1)
continue
end
set my_fishes $my_fishes $the_fishes[$fix]
if test -z $rest
echo $my_fishes
exit
end
if not pickafish $rest
set my_fishes $my_fishes[(seq (math (count $my_fishes) - 1))]
set fix (math $fix+1)
continue
end
end
end
pickafish $argv[1]
The following version is still the longest answer to the challenge,
set t "><>" "<><" ">><>" "<><<" "><>>" "<<><" "><<<>" "<>>><" ",<..>,";set m;function p;set -l i 1;while true;test $i -gt 9; and return 1;if not set r (begin;set c (echo $t[$i]|wc -c);echo $argv[1]|cut -c$c-;test $t[$i] = (echo $argv[1]|cut -c-(math $c-1));end);set i (math $i+1);continue;end;set m $m $t[$i];if test -z $r;echo $m;exit;end;if not p $r;set m $m[(seq (math (count $m)-1))];set i (math $i+1);continue;end;end;end;p $argv[1]
but since this was done mostly for the pun (you'll excuse, I hope), better golfing is left as an exercise to the reader.
JavaScript (ES6), 164
Recursive, depth first scan.
As a program with I/O via popup:
alert((k=(s,r)=>'><>0<><0>><>0<><<0><>>0<<><0><<<>0<>>><0,<..>,'.split(0)
.some(w=>s==w?r=w:s.slice(0,l=w.length)==w&&(t=k(s.slice(l)))?r=w+' '+t:0)?r:'')
(prompt()))
As a testable function:
k=(s,r)=>'><>0<><0>><>0<><<0><>>0<<><0><<<>0<>>><0,<..>,'.split(0)
.some(w=>s==w?r=w:s.slice(0,l=w.length)==w&&(t=k(s.slice(l)))?r=w+' '+t:0)?r:''
Test suite (run in Firefox/FireBug console)
t=['<><><>', '><>><>>', '<><<<><',',<..>,><<<>,<..>,><>,<..>,<>>><,<..>,><>>,<..>,<<><,<..>,<><,<..>,>><>',
'<><>',',<..>,<..>,','>>><>','><<<<>',',','><><>',',<><>,',
'<<<><><<<>>><>><>><><><<>>><>><>>><>>><>><>><<><','<<><><<<>>><>><>><><><<>>><>><>>><>>><>><>><<><']
t.forEach(t=>console.log(t + ': ' +k(t)))
Output
<><><>: <>< ><>
><>><>>: ><> ><>>
<><<<><: <>< <<><
,<..>,><<<>,<..>,><>,<..>,<>>><,<..>,><>>,<..>,<<><,<..>,<><,<..>,>><>: ,<..>, ><<<> ,<..>, ><> ,<..>, <>>>< ,<..>, ><>> ,<..>, <<>< ,<..>, <>< ,<..>, >><>
<><>:
,<..>,<..>,:
>>><>:
><<<<>:
,:
><><>:
,<><>,:
<<<><><<<>>><>><>><><><<>>><>><>>><>>><>><>><<><:
<<><><<<>>><>><>><><><<>>><>><>>><>>><>><>><<><: <<>< ><<<> >><> ><> ><> <>< <>>>< >><> >><> >><> ><>> <<><
Ungolfed just the k function
function k(s)
{
var f='><>0<><0>><>0<><<0><>>0<<><0><<<>0<>>><0,<..>,'.split(0)
var i, w, l, t
for (w of f)
{
if (s == w)
{
return w
}
l = w.length
if (s.slice(0,l) == w && (t = k(s.slice(l))))
{
return w + ' ' + t
}
}
return ''
}
Haskell, 148 146 bytes
main=mapM_ putStr.take 1.filter(all(`elem`words"><> >><> ><>> ><<<> <>< <><< <<>< <>>>< ,<..>,").words).map concat.mapM(\a->[[a],a:" "])=<<getLine
Testing:
$ echo "><>><>>>" | runhaskell fishes.hs
$ echo "><>><>>" | runhaskell fishes.hs
<> ><>>
Explanation
Based on my earlier answer to a similar question. The algorithm runs in exponential time.
This reads from right to left.
=<<getLine -- Read a line from STDIN.
mapM(\a->[[a],a:" "]) -- Replace each letter 'a' by "a" or "a " in
-- all possible ways, collect results to a list.
map concat -- Concatenate those lists-of-strings into strings.
filter(all(...).words) -- Keep those whose words are correct fish.
take 1 -- Discard all but the first one.
mapM_ putStr -- Print each string in that 1- or 0-element list.
main= -- That is the main function.
This will not print a string that ends with a space, even though such strings are generated too, because its no-space counterpart is generated first.
Python 3, 156
*l,s=[],input()
for _ in s:l+=[y+[x]for x in"><> >><> ><>> ><<<> <>< <><< <<>< <>>>< ,<..>,".split()for y in l]
for y in l:
if"".join(y)==s:print(*y);break
The strategy is to generate lists of fish and compare their concatenation to the input string.
This takes impossibly long. If you actually want to see an output, replace for _ in s with for _ in [0]*3, where 3 is the upper bound for the number of fish. It works to use s because s contains at most one fish per char.
Thanks to Sp3000 for bugfixes and a char save on input.
Old 165:
f=lambda s:[[x]+y for x in"><> >><> ><>> ><<<> <>< <><< <<>< <>>>< ,<..>,".split()for y in f(s[len(x):])if s[:len(x)]==x]if s else[[]]
y=f(input())
if y:print(*y[0])
import sys
def unfish(msg,dict,start):
if(len(msg[start:])<3):
return "";
for i in range(3,6):
if (msg[start:start+i] in dict):
if(start+i==len(msg)):
return msg[start:start+i];
else:
ret = unfish(msg,dict,start+i);
if ret != "":
return msg[start:start+i]+" "+ret;
return ""
dict = {'><>':1,'<><':1,'>><>':1,'<><<':1,'><>>':1,'<<><':1,'><<<>':1,'<>>><':1,',<..>,':1};
print unfish(sys.argv[1],dict,0);
im a bit of a python noob so ignore the weirdness :P
CJam, 111 96 91 (or 62 bytes)
An iterative greedy approach to keep figuring out what all fish combinations are possible as you iterate. Really not golfed right now.
q_aa\,{{" È÷®µãÑø"255b5b" ><,."f=S/\f{)_3$#{;;;}{2$,>:P@a\a++}?PR+!{S:R*W<o}*}~}%}*];
The code contains some unprintable characters, so use the link below for reference.
Update Encoded the string
Will add explanation once done golfing
62 bytes
Super slow version. This basically creates all the combinations and checks which are equal to the input.
L"¬ééãLù:9$"255b6b5," ><,."erS/aq:Q,*{m*}*{sQ=}=`"[]\""-
This also contains unprintable characters, so rely on the below link.
Python 2, 234 bytes
I tried a Python regex solution first, but there seems to be no way to extract the groups after a match on multiple patterns. The following is a recursive search which seems to do well on the test cases.
a='><> >><> ><>> ><<<> <>< <><< <<>< <>>>< ,<..>,'.split()
def d(t,p=0):
if p<len(t):
for e in a:
z=p+len(e)
if e==t[p:z]:
if z==len(t):return[e]
c=d(t,z)
if c:return[e]+c
c=d(raw_input())
if c:
print' '.join(c)
An example test:
$ echo ",<..>,><<<>,<..>,><>,<..>,<>>><,<..>,><>>,<..>,<<><,<..>,<><,<..>,>><>" | python soln.py
,<..>, ><<<> ,<..>, ><> ,<..>, <>>>< ,<..>, ><>> ,<..>, <<>< ,<..>, <>< ,<..>, >><>
And the ungolfed version:
fishtypes = '><> >><> ><>> ><<<> <>< <><< <<>< <>>>< ,<..>,'.split()
def getfish(t, p=0):
if p < len(t):
for afish in fishtypes:
z = p+len(afish)
if afish == t[p:z]:
if z == len(t) :
return [afish]
fishlist = getfish(t, z)
if fishlist :
return [afish]+fishlist
fishlist = getfish(raw_input())
if fishlist:
print ' '.join(fishlist)
Haskell(Parsec) - 262
import Text.Parsec
c=words"><> >><> ><>> ><<<> <>< <><< <<>< <>>>< ,<..>,"
p c d=choice[eof>>return[],lookAhead(choice$map(try.string)d)>>=(\s->try(string s>>p c c>>=(\ss->return$s:ss))<|>p c(filter(/=s)c))]
main=interact$either show unwords.runParser(p c c)()""
Haskell, 148 142
p[]=[[]]
p s=[i:j|i<-words"><> >><> ><>> ><<<> <>< <><< <<>< <>>>< ,<..>,",i==map fst(zip s i),j<-p$drop(length i)s]
g s=unwords$head$p s++p[]
this uses list comprehensions to iterate over the fish, pick the ones who match the start and continue recursively.
Python 3, 196 186 bytes
F="><> >><> ><>> ><<<> <>< <><< <<>< <>>>< ,<..>,".split()
def g(s):
if s in F:return[s]
for f in F:
i=len(f)
if f==s[:i]and g(s[i:]):return[f]+g(s[i:])
R=g(input())
if R:print(*R)
Simple recursion. g either returns a list of parsed fish, or None if the input string is unparseable.