Вам нужно либо применить фильтр до join
:
join cc in CompanyCurrency.Where(e => e.CompanyId == 1)
, либо как часть соединения
on new { CurrencyId = c.ID, CompanyId = 1 } equals new { cc.CurrencyId, cc.CompanyId }
. Для inner join
s он не имеет значения, t действительно имеет значение, но для outer join
это важно (тот же btw применяется к SQL-запросам).
def f(g,W):w=g.find("\n")+1;L=len(W);print" --> ".join("row %s, column %s"%(x/w+1
,x%w+1)for i in range(len(g))for j in(-w-1,-w,-w+1,-1,1,w-1,w,w+1)for x in(i,i+(L
-1)*j)if g[i::j][:L]==W)
код тестирования:
grid="""A I Y R J J Y T A S V Q T Z E
X B X G R Z P W V T B K U F O
E A F L V F J J I A G B A J K
R E S U R E P U S C Y R S Y K
F B B Q Y T K O I K H E W G N
G L W Z F R F H L O R W A R E
J A O S F U E H Q V L O A Z B
J F B G I F Q X E E A L W A C
F W K Z E U U R Z R T N P L D
F L M P H D F W H F E C G W Z
B J S V O A O Y D L M S T C R
B E S J U V T C S O O X P F F
R J T L C V W R N W L Q U F I
B L T O O S Q V K R O W G N D
B C D E J Y E L W X J D F X M """.lower().replace(" ","")
f(grid,"codegolf")
f(grid,"serverfault")
f(grid,"superuser")
Эта версия имеет 196 символов и принимает сетку без дополнительных настроек
def f(g,W):w=g.find("\n")+1;L=len(W);print" --> ".join("row %s, column %s"%(x/w+1,x%w/2+1)for i in range(len(g))for j in(-w-2,-w,-w+2,-2,2,w-2,w,w+2)for x in(i,i+(L-1)*j)if g[i::j][:L].lower()==W)
код тестирования:
grid="""A I Y R J J Y T A S V Q T Z E
X B X G R Z P W V T B K U F O
E A F L V F J J I A G B A J K
R E S U R E P U S C Y R S Y K
F B B Q Y T K O I K H E W G N
G L W Z F R F H L O R W A R E
J A O S F U E H Q V L O A Z B
J F B G I F Q X E E A L W A C
F W K Z E U U R Z R T N P L D
F L M P H D F W H F E C G W Z
B J S V O A O Y D L M S T C R
B E S J U V T C S O O X P F F
R J T L C V W R N W L Q U F I
B L T O O S Q V K R O W G N D
B C D E J Y E L W X J D F X M """
f(grid,"codegolf")
f(grid,"serverfault")
f(grid,"superuser")
NF<2{l=split($1,w,"")}NF>1{for(i=1;i<=NF;)t[x=i++,y=NR]=$i}END{
for(i=1;i<=x;++i)for(j=0;++j<=y;)for(a=0;a<9;++a)if(t[I=i,J=j]==w[1])
for(k=1;k<l;){if(!(T=t[I+=int(a/3)-1,J+=a%3-1])||T!=w[++k])break;if(k==l)
print"row "j (B=", column ")i" --> row "J B I}}
Ввод должен быть в форме
....
B L T O O S Q V K R O W G N D
B C D E J Y E L W X J D F X M
CODEGOLF
Python, 318 штрихов.
from itertools import*
f=lambda x,y,i,j,n:(x-i+1,y-j+1)*(not n)or all((2*i+j,x+1,y+1,x<c,y<d))and a[x][y*2]==n[0]and f(x+i,y+j,i,j,n[1:])
w=raw_input
a=list(iter(w,''))
c=len(a)
d=len(a[0])/2
r=range
z=r(-1,2)
s='row %d, column %d'
for x in product(r(c),r(d),z,z,[w()]):
if f(*x):print s%(x[0]+1,x[1]+1),'-->',s%f(*x)
A I Y R J J Y T A S V Q T Z E
X C O D E G O L F B K U F O Z
E A F L V F J J I A G B A J K
R E S U R E P U S C Y R S Y K
F B B Q Y T K O I K H E W G N
G L W Z F R F H L O R W A R E
J A O S F U E H Q V L O A Z B
J F B G I F Q X E E A L W A C
F W K Z E U U R Z R T N P L D
F L M P H D F W H F E C G W Z
B J S V O A O Y D L M S T C R
B E S J U V T C S O O X P F F
R J T L C V W R N W L Q U F I
B L T O O S Q V K R O W G N D
B C D E J Y E L W X J D F X M
CODEGOLF
Вывод:
$ python wordsearch < wordsearchinput.txt
row 2, column 2 --> row 2, column 9
row 12, column 8 --> row 5, column 1
Выпущено под заголовком "редактировать-ответ-вместо-комментировать-как-я-должен-исправить- это "лицензия.
Я думаю, все еще есть возможности для улучшения, все комментарии приветствуются.
Стратегия: найти все вхождения первой буквы, а затем попытаться найти слово во всех направлениях.
import sys;r=range(-1,2);k=''.join;q="row %s, column %s"
a=[l[:-1:2]for l in sys.stdin]
b=sys.argv[1];c=len(a[0])
for x,y in[(x/c,x%c)for x,h in enumerate(k(map(k,a)))]:
for i,j in[(i,j)for i in r for j in r if i or j<>0]:
if k([a[x+z*i][y+z*j]for z in range(len(b))if 0<=x+z*i<c and 0<=y+z*j<len(a)])==b:print q%(x+1,y+1)+" --> "+q%(x+z*i+1,y+z*j+1)
Пример использования:
cat input.txt | python test.py CODEGOLF
Пример вывода:
строка 12, столбец 8 -> строка 5, столбец 1
sub h($){"row ",$%=1+($x=pop)/$W,", column ",1+$x%$W}
@S=map/[^ ]/g,<STDIN>;
B:for(@ARGV){
for$d(map{$_,-$_}1,$W=@S/$.,$W-1,$W+1){
A:for$s(0..$#S){
$t=$s-$d;for(/./g){next A if$S[$t+=$d]ne$_||$t<0}
print h$s,' --> ',h$t,$/;
next B
}}}
Счетчик символов не включает символы новой строки и отступы, которые включены для удобства чтения. Я предполагаю, что матрица букв указывается со стандартным вводом, а целевые слова являются аргументами командной строки.
Первая строка (после определения sub h
) отображает все непробельные символы в один массив @S
. Затем выполните итерацию по всем целевым словам, по возможным направлениям, в которых слова могут появляться ( $ W
- ширина головоломки), и по всем буквам в текущем целевом слове, пока не будет найдено совпадение. .
$ perl wordsearch.pl CODEGOLF RACECAR BYKLHQU <<EOF A I Y R J J Y T A S V Q T Z E X B X G R Z P W V T B K U F O E A F L V F J J I A G B A J K R E S U R E P U S C Y R S Y K F B B Q Y T K O I K H E W G N G L W Z F R F H L O R W A R E J A O S F U E H Q V L O A Z B J F B G I F Q X E E A L W A C F W K Z E U U R Z R T R A C E C A R P H D F W H F E C G W Z B J S V O A O Y D L M S T C R B E S J U V T C S O O X P F F R J T L C V W R N W L Q U F I B L R A C E C A R R O W G N D B C D E J Y E L W X J D F X M EOF row 12, column 8 --> row 5, column 1 row 14, column 3 --> row 14, column 9 row 3, column 12 --> row 9, column 6
(Не включая переводы строк, все из которых являются необязательными)
Код, в основном не связанный с гольфом, можно найти здесь .
$/="";@w=split//,pop;($b=<>)=~y/ //d;$W=1+index$b,"\n";
for(1,2){for(0,$W-2..$W){$p=join"."x$_,@w;
push@m,[$-[0],$+[0]-1]while$b=~/$p/sg}
@w=reverse@w;@m=map[reverse@$_],@m}
$t="row %d, column %d";
printf"$t --> $t\n",map{1+$_/$W,1+$_%$W}@$_ for@m;
Использование: запускать как сценарий. Либо wordsearch.pl поисковое слово файла доски
для чтения из файла, либо поисковое слово wordsearch.pl
для чтения доски из STDIN (эй, pop
на два символа короче, чем shift
!)
Идея состоит в том, что мы считываем доску в строку (отбрасывая лишние пробелы между буквами), а также отмечаем ее ширину (считая символы до первой новой строки ). Затем мы выполняем серию совпадений регулярного выражения, чтобы найти слово, используя модификатор регулярного выражения s
, чтобы позволить совпадению занимать строки. Имея доску шириной 4 буквы (так что каждая строка состоит из 5 символов, включая новую строку) и поисковое слово «CAR», мы можем сделать так, чтобы шаблоны / CAR /
соответствовали прямым, / C. ..A ... R /
соответствует движению на юго-запад, / C .... A .... R /
соответствует движению вниз, и / C .... .A ..... R /
, чтобы соответствовать движению на юго-восток. Для каждого матча мы записываем начальную и конечную позиции матча.
Затем мы меняем местами поисковое слово («CAR» -> «RAC») и делаем это снова, что позволяет нам сопоставить слово «влево, вверх, на северо-запад и северо-восток». Конечно, мы хотим убедиться, что начальная / конечная позиции также поменялись местами. Чтобы сохранить код, я дважды меняю местами совпадения ; совпадения для прямого слова меняются местами оба раза (поэтому они выходят без замены), тогда как совпадения для обратного слова меняются местами только один раз, поэтому они будут выходить поменяемыми местами.
Наконец, нужно просто взять смещения совпадений в строку платы и превратить их в пары строка / столбец и отформатировать вывод так, как того требует задача.
Моя первая попытка сыграть в гольф код.
#include<stdio.h>
main(){char m[999],w[99];int r,c,l=-1,x=-1,y=-1,i=0,j,k;scanf("%s %d %d"
,w,&r,&c);for(;w[l+1];++l);for(;i<r*c;scanf("%s",&m[i++]));for(;y<2;++y)
for(;x<2;++x)if(x|y)for(i=(y<0)*l;i<r-(y>0)*l;++i)for(j=(x<0)*l;j<c-(x>0
)*l;++j)for(k=0;k<=l&&w[k++]==m[(i+k*y)*c+j+k*x];)k>l?printf(
"row %i, column %i --> row %i, column %i\n",i+1,j+1,i+y*l+1,j+x*l+1):0;}
Он компилируется в gcc без предупреждений, без дополнительных флагов.
Вот версия с пробелами:
#include<stdio.h>
main() {
char m[999], w[99];
int r, c, l = -1, x = -1, y = -1, i = 0, j, k;
scanf("%s %d %d", w, &r, &c);
for (; w[l+1]; ++l);
for (; i < r*c; scanf("%s", &m[i++]));
for (; y < 2; ++y)
for (; x < 2; ++x)
if (x | y)
for (i = (y<0) * l; i < r - (y>0) * l; ++i)
for (j = (x<0) * l; j < c - (x>0) * l; ++j)
for (k = 0; k <= l && w[k++] == m[(i+k*y) * c + j+k*x];)
k > l ? printf("row %i, column %i --> row %i, column %i\n",
i + 1, j + 1, i + y*l + 1, j + x*l + 1)
: 0;
}
Ожидаемый ввод на стандартный ввод выглядит так:
CODEGOLF 15 15
A I Y R J J Y T A S V Q T Z E
X B X G R Z P W V T B K U F O
...
где 15 15
- это номера строк и столбцов соответственно.
Так как это мой первый раунд игры в гольф, и я мог найти в сети небольшие полезные общие приемы, я перечислю некоторые из найденных:
Старайтесь сводить тела цикла к одному оператору, чтобы сэкономить на усах ( 2 символа).
Пример : что угодно с использованием оператора запятой.
Используйте условное выражение (?:
) вместо if
, когда можно (1 символ).
Пример : вместо if (x) printf ("");
напишите x? Printf (""): 0;
. Это работает, потому что printf
возвращает int
.
Используйте тот факт, что логические значения равны 0
или 1
при использовании в качестве int
(? Символов).
Пример : вместо (y> 0? R-l: r)
напишите r- (y> 0) * l
. В скобках здесь указана экономия, которая была необходима в данной ситуации.
, а
циклы никогда не короче, чем для
циклов, и в большинстве случаев длиннее (> = 0 символов).
Пример : while (x) y;
такой же длинный, как для (; x; y);
, но с для
вы получите тело цикла, с которым тоже можно поиграть, не доплачивая за ;
.
Поместите приращения цикла в последнее выражение, которое использует счетчик цикла (1 символ).
Пример : вместо для (; x напишите
для (; x .
Не использовать возвращаемый тип main
(4 символа).
Оставьте оператор main
return
(9 символов).
По возможности используйте &
и |
вместо &&
и ||
(1 символ).
Пример : вместо if (x || y)
напишите if (x | y)
. Это работает, только если вы не зависите от поведения короткого замыкания &&
и ||
.
Вставьте функцию strlen
и удалите #include
(11 символов).
Если вас не интересуют предупреждения компилятора: