Rubí, 139 bytes
Función lambda, toma x e y como argumentos y devuelve una cadena
->x,y{c=y-2*n=y-(x>y ?1:0)>>1
x+=-c/2*s=[x-n,c*3].max
x<n||x>n*2?'~<.,,>~~':',<..>, '*(x-n)+'<.,.> '*(2*n-x)+"<%s.> "*c%[?,*s-=c/2*3,?,*3]}
Si existe una solución, se puede hacer con todos los koalas + commapillars o todos los koalas + cangrejos.
El principio es usar un mínimo de commapillars. Si el número es impar, usamos 1 commapillar. si incluso usamos 0 commapillars, a menos que haya más comas que puntos, en cuyo caso usamos 2.
El número de períodos utilizados en los no mapeadores (cangrejos + koalas) es necesariamente par, y el número de no mapeadores es la mitad (number of periods)-(number of commapillars)
. Si no hay comas suficientes para todos los koalas, o demasiados para todos los cangrejos, no hay solución posible. De lo contrario, devolvemos una solución.
Comentó en el programa de prueba
usa "falla" en lugar de camaleón para mayor claridad
f=->x,y{c=y-2*n=y-(x>y ?1:0)>>1
#n=noncommapillars=y>>1 as they have 2 periods. c=commapillars=y-2*n, 1 for odd y, 0 for even y.
#if x>y there are too many commas to have 0 commapillars for even y. noncommapillars= y-1 >> 1, so 2 commapillars
x+=-c/2*s=[x-n,c*3].max
# s=number of commas allocated to commapillars. x-n to allow all noncommapillars to be koalas, but at least 3 per commapillar.
#-c/2 == -1 if there are commapillars, 0 if not (Ruby truncates toward -inf). Subtract commas for commapillars from x if necessary
x<n||x>n*2?'fail':',<..>, '*(x-n)+'<.,.> '*(2*n-x)+"<%s.> "*c%[?,*s-=c/2*3,?,*3]}
#if x<n (insufficient commas for all koalas) or x>n*2 (too many for all crabs) return fail. Else...
#return string off crabs, koalas, and (using % operator like sprintf) c commapillars (0..2), the second with 3 commas (if present) and the first with the rest.
10.times{|j|10.times{|i|puts "%-20s %s"%[?.*j+?,*i,f[i,j]]}}
#all x,y from 0..9
Salida
, fail
,, fail
,,, fail
,,,, fail
,,,,, fail
,,,,,, fail
,,,,,,, fail
,,,,,,,, fail
,,,,,,,,, fail
. fail
., fail
.,, fail
.,,, <,,,.>
.,,,, <,,,,.>
.,,,,, <,,,,,.>
.,,,,,, <,,,,,,.>
.,,,,,,, <,,,,,,,.>
.,,,,,,,, <,,,,,,,,.>
.,,,,,,,,, <,,,,,,,,,.>
.. fail
.., <.,.>
..,, ,<..>,
..,,, fail
..,,,, fail
..,,,,, fail
..,,,,,, <,,,.> <,,,.>
..,,,,,,, <,,,,.> <,,,.>
..,,,,,,,, <,,,,,.> <,,,.>
..,,,,,,,,, <,,,,,,.> <,,,.>
... fail
..., fail
...,, fail
...,,, fail
...,,,, <.,.> <,,,.>
...,,,,, <.,.> <,,,,.>
...,,,,,, <.,.> <,,,,,.>
...,,,,,,, <.,.> <,,,,,,.>
...,,,,,,,, <.,.> <,,,,,,,.>
...,,,,,,,,, <.,.> <,,,,,,,,.>
.... fail
...., fail
....,, <.,.> <.,.>
....,,, ,<..>, <.,.>
....,,,, ,<..>, ,<..>,
....,,,,, fail
....,,,,,, fail
....,,,,,,, <.,.> <,,,.> <,,,.>
....,,,,,,,, <.,.> <,,,,.> <,,,.>
....,,,,,,,,, <.,.> <,,,,,.> <,,,.>
..... fail
....., fail
.....,, fail
.....,,, fail
.....,,,, fail
.....,,,,, <.,.> <.,.> <,,,.>
.....,,,,,, <.,.> <.,.> <,,,,.>
.....,,,,,,, <.,.> <.,.> <,,,,,.>
.....,,,,,,,, <.,.> <.,.> <,,,,,,.>
.....,,,,,,,,, <.,.> <.,.> <,,,,,,,.>
...... fail
......, fail
......,, fail
......,,, <.,.> <.,.> <.,.>
......,,,, ,<..>, <.,.> <.,.>
......,,,,, ,<..>, ,<..>, <.,.>
......,,,,,, ,<..>, ,<..>, ,<..>,
......,,,,,,, fail
......,,,,,,,, <.,.> <.,.> <,,,.> <,,,.>
......,,,,,,,,, <.,.> <.,.> <,,,,.> <,,,.>
....... fail
......., fail
.......,, fail
.......,,, fail
.......,,,, fail
.......,,,,, fail
.......,,,,,, <.,.> <.,.> <.,.> <,,,.>
.......,,,,,,, <.,.> <.,.> <.,.> <,,,,.>
.......,,,,,,,, <.,.> <.,.> <.,.> <,,,,,.>
.......,,,,,,,,, <.,.> <.,.> <.,.> <,,,,,,.>
........ fail
........, fail
........,, fail
........,,, fail
........,,,, <.,.> <.,.> <.,.> <.,.>
........,,,,, ,<..>, <.,.> <.,.> <.,.>
........,,,,,, ,<..>, ,<..>, <.,.> <.,.>
........,,,,,,, ,<..>, ,<..>, ,<..>, <.,.>
........,,,,,,,, ,<..>, ,<..>, ,<..>, ,<..>,
........,,,,,,,,, <.,.> <.,.> <.,.> <,,,.> <,,,.>
......... fail
........., fail
.........,, fail
.........,,, fail
.........,,,, fail
.........,,,,, fail
.........,,,,,, fail
.........,,,,,,, <.,.> <.,.> <.,.> <.,.> <,,,.>
.........,,,,,,,, <.,.> <.,.> <.,.> <.,.> <,,,,.>
.........,,,,,,,,, <.,.> <.,.> <.,.> <.,.> <,,,,,.>