オフラインどう書く第19回問題解答

問題はこちら->http://nabetani.sakura.ne.jp/hena/ord19nebasec/

内側と外側のセクタの境界が一致するところがないのを利用
中からD番目のセクタの中心角を 2*W,W=12 div Dとしても問題ないので、
内外のセクタの間のきちんとした式は、100*D番のセクタの中心を貫く線の座標を0として、
時計回りにX番目のセクタの座標の大きいほうの境界は
X*W*2+Wと表せることを利用して立てることができますが、
より簡単な式がないかと思い、しばらく図を眺め少し試行錯誤をして解にある式を導きました。
find/3で、入力のセクタの前後のセクタを調べ、
入力のセクタの最初と最後の座標をそれぞれ含む外側と内側のセクタを求め、
add/5でその間にあるセクタを集めます。
この時マイナス値を防ぐためその列のセクタの数で割った剰余を用います。
すべての入力に繰り返してセクタを集めて、複数存在するセクタのみ残し、
さらに入力にあるセクタを除きます。

```Prolog
%SWI-Prolog v 7.42,7.64
%start.
%initialization(start).   %ideone

add(L,Y1,Y1,D,R):-Y is 100*D+ Y1 mod (D*8),R=[Y|L].
add(L,Y1,Y2,D,R):-Y21 is Y2-1,add(L,Y1,Y21,D,L1),Y is 100*D  + Y2 mod (D*8),R=[Y|L1].

find(N,L,R):-
     divmod(N,100,D,M),X1 is 100*D+(M-1) mod (D*8),
     X2 is 100*D+(M+1) mod (D*8),append([X1,X2],L,L1),   % X ha ryougawa
     (D=:=4->R1=L1;(D1 is D+1,Y1 is D1*(M-1) div D +1,
     Y2 is D1*M div D+1,add(L1,Y1,Y2,D1,R1))),   % Y ha sotogawa
     (D=:=1->R=R1;(D2 is D-1,Z1 is D2*M div D ,
     Z2 is D2*(M+1) div D,add(R1,Z1,Z2,D2,R))).         % Z ha utigawa

sel([_],R,R).
sel([H|T],L,R):-(member(H,T)->L1=[H|L];L1=L),sel(T,L1,R).       %tyouhuku nomi nokosu

del([],R,R).
del([H|T],L,R):-delete(L,H,L1),del(T,L1,R).          %nyuurokuti wo sakujo

solve(L,R):-foldl(find,L,[],L1),del(L,L1,L2),msort(L2,L3),sel(L3,[],L4),sort(L4,R).
     
start:-
     str(S),split_string(S,"\s\n","\s",L),pre(L),!.
     
pre([]):-!.
pre([_,S,A|T]):-
     atomics_to_string(L,",",S),maplist(atom_number,L,L1),
     solve(L1,R),disp(R,A),pre(T).
     
disp(R,A):-
     (R==[]->S="none";atomics_to_string(R,",",S)),
     (S==A->write("pass ");write(" fail ")),writeln(S),!.
     
str("0  400,401,302     300,301,402
1       105,100,306,414         none
2       100     none
3       211     none
4       317     none
5       414     none
6       100,106         107
7       205,203         102,204
8       303,305         304
9       407,409         306,408
10      104,103         207
11      204,203         102,305
12      313,314         209,418
13      419,418         314
14      100,102,101     201,203
15      103,206,309     205,207,308,310
16      414,310,309     206,311,413
17      104,102,206,307,102,202         101,103,203,204,205,207,308
18      104,206,308,409,407     103,205,207,306,307,309,408,410
19      313,406,213,301,409,422,412,102,428     none
20      101,300,210,308,423,321,403,408,415     none
21      304,316,307,207,427,402,107,431,412,418,424     none
22      205,408,210,215,425,302,311,400,428,412         none
23      200,311,306,412,403,318,427,105,420     none
24      105,305,407,408,309,208,427     104,209,306,406
25      311,304,322,404,429,305,316     203,303,321,405,406,430
26      210,401,316,425,101     211,315
27      414,403,404,416,428,421         303,415
28      207,300,103,211,428     104,206
29      322,314,310     none
30      427,200,215     100,323
31      311,402,424,307,318,430,323,305,201     200,204,301,302,306,322,423,425,431
32      425,430,408     none
33      202,320,209,426         319,427
34      430,209,302,310,304,431,320     202,303,323
35      208,206,406,424,213,312         207,311,313
36      420,302,313,413,317,402         301,403
37      319,306,309,418,204,411         305,307,308,412
38      400,308,105,430,203,428,209     104,210,429,431
39      200,305,214     215
40      214,408,410,407,317,422         306,316,409,423").
```