0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

リアルタイムどう書く過去問(第20回)

Last updated at Posted at 2018-07-15

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

論理問題を探していて見つけました、
問題を見たとき、1分ごとに続けて60分条件をクリアすれば成功という方法を思いつき、
どのくらい時間がかかるのか気になりコードを書いてみました。
この方法でも瞬時に解けましたが、問題10をパスしないことがわかり、
オーソドックスに?開始時間と終了時間で検証することにしました。
会議開始の時間は1分ごとに検証しています。
fil/3で各自の条件を取り出しています。
IさんとJさんはどちらかがいればよいのでorでつなぎ、
Zさんはtest/3をand(すべての条件をクリアすれば成功)で統一するためnotを使っていますので、
(TB<=N)->(TB>N)、(N+60<=TE)->(N+60>TE)、or-> andとなっています。
問題に数字、アルファベット、ハイフンが混在していて、入出力に苦労しました。

fil(_,[],[]).
fil(X:_,[H|T],L):-fil(X:_,T,L1),(H=X:_->L=[H|L1];L=L1).

test(_,_,[]):-!.
test(P,N,[P:TB-TE|T]):-P\=z,!,(TB>=N+60;N>=TE),test(P,N,T).
test(P,N,[P:TB-TE|T]):-(TB>N;N+60>TE),test(P,N,T).

se(P,N,L):-
     fil(P:_,L,L1),!,(L1==[]->(P==z->false;true);test(P,N,L1)).

solve(L,N):-
     between(600,1020,N),se(a,N,L),se(b,N,L),(se(i,N,L);se(j,N,L)),not(se(z,N,L)),!.
solve(_,0).

start:-str(S),split_string(S,"\n","",L),maplist(split,L,L1),pre(L1).

split(S,L):-split_string(S,"\s","\s",L).

pre([]).
pre([[_,B,Q]|T]):-concat_atom(B1,",",B),maplist(sp,B1,L),solve(L,R),disp(R,Q),pre(T).

disp(0,A):-
     !,S="-",disp1(S,A).
disp(R,A):-
     D is R div 60,M is R mod 60,N1 is D*100+M,N2 is N1+100,
     concat_atom([N1,N2],"-",S),atom_chars(X,A),disp1(X,S).

disp1(S,A):-(A==S->Str=" pass ";Str=" fail "),write(Str),writeln(S).

htom(N,R):-N1 is N div 100,N2 is N mod 100,R is N1*60+N2.

sp(B,R):-
     concat_atom([X,Y],'-',B),atom_codes(X,[H|T]),atom_codes(X1,T),
     atom_number(X1,N1),atom_number(Y,N2),htom(N1,NF),htom(N2,NT),
     atom_chars(H1,[H]),downcase_atom(H1,H2),R=H2:NF-NT.
     
%start.

str("0    A1050-1130,B1400-1415,I1000-1400,I1600-1800,J1100-1745,Z1400-1421,Z1425-1800    1425-1525
1       A1000-1200,B1300-1800,Z1000-1215,Z1230-1800     -
2       Z0800-2200      1000-1100
3       A1000-1700,Z0800-2200   1700-1800
4       A1000-1701,Z0800-2200   -
5       A1000-1130,B1230-1800,Z0800-2200        1130-1230
6       A1000-1129,B1230-1800,Z0800-2200        1129-1229
7       A1000-1131,B1230-1800,Z0800-2200        -
8       A1000-1130,B1229-1800,Z0800-2200        -
9       A1000-1130,B1231-1800,Z0800-2200        1130-1230
10      A1000-1130,B1230-1800,Z0800-1130,Z1131-2200     -
11      A1000-1130,B1231-1800,Z0800-1130,Z1131-2200     1131-1231
12      Z0800-0801      -
13      Z0800-1031,Z1129-1220,Z1315-1400,Z1459-1600     1459-1559
14      Z0800-2200,I1000-1600,J1030-1730        1600-1700
15      Z0800-2200,I1000-1600,J1130-1730        1000-1100
16      Z0800-2200,I1000-1600,J1130-1730,A0800-1025     1025-1125
17      Z0800-2200,I1000-1600,J1130-1730,A0800-1645     1645-1745
18      Z0800-2200,I1000-1600,J1130-1730,A0800-1645,I1735-2200  -
19      Z0800-2200,I1000-1600,J1130-1730,A0800-1645,J1735-2200  1645-1745
20      Z1030-2200,I1000-1600,J1130-1730        1030-1130
21      Z1035-1500,I1000-1600,J1130-1730,Z1644-2200     1644-1744
22      I2344-2350,A2016-2253,Z1246-1952        1246-1346
23      Z2155-2157,B1822-2032,Z1404-2000,Z2042-2147,Z2149-2154  1404-1504
24      Z2231-2250,Z2128-2219,B2219-2227,B2229-2230,Z0713-2121,A0825-1035,B1834-2001    1035-1135
25      J0807-1247,I0911-1414,B1004-1553,Z0626-1732,Z1830-1905,A1946-1954,A0623-1921    -
26      J1539-1733,J0633-1514,Z1831-1939,J1956-1959,I0817-1007,I1052-1524,Z1235-1756,Z0656-1144         1524-1624
27      Z2319-2350,B0833-2028,I2044-2222,A1410-2201,Z2044-2228,Z0830-2023,Z2242-2306,I2355-2359         -
28      B2001-2118,Z0712-1634,I1941-2102,B1436-1917     1000-1100
29      A0755-1417,B2303-2335,Z0854-2150,Z2348-2356,Z2156-2340,I1024-1307,Z2357-2359    1417-1517
30      A1958-1959,B0822-1155,I1518-1622,Z1406-1947,A1800-1822,A0904-1422,J1730-1924,Z1954-1958,A1946-1956      1422-1522
31      B1610-1910,I2121-2139,A0619-1412,I2147-2153,Z0602-2111,I0841-2031,A1657-1905,A1956-2047,J0959-1032,Z2131-2147   1412-1512
32      Z0623-1900,A0703-1129,I1815-1910,J1956-1957,I0844-1518,Z1902-1935,B1312-1342,J1817-1955         1129-1229
33      J1246-1328,B1323-1449,I1039-1746,Z1218-2111     1449-1549
34      A1958-1959,I1943-1944,I0731-1722,Z0845-1846,J1044-1513,Z1910-1923,B1216-1249    1513-1613
35      A1855-2047,Z0946-1849,Z2056-2059,I1855-1910,B1946-2058,I1956-2025,Z1905-2054,J0644-1800,I0720-1618      1618-1718
36      J1525-1950,Z0905-1933,A1648-1716,I2051-2054,I2015-2044,I0804-1958,B0934-1100,Z1953-2037         1100-1200
37      Z1914-1956,J0823-1610,Z0641-1841,J1800-1835,A0831-1346,I1926-1941,I1030-1558,I1738-1803         1558-1658
38      Z0625-1758,J1033-1351,B1816-2236,I0838-1615,J2247-2255  1351-1451
39      J0603-1233,A1059-1213,I1326-2103,Z0710-1459     1213-1313
40      B1302-1351,J1410-2038,A0755-1342,J0637-0658,Z2148-2159,Z1050-2131,A1543-1844,I1615-1810         1351-1451
41      Z0746-2100,A2122-2156,I1022-1144,J0947-1441,A1333-1949  1144-1244
42      J0718-1243,Z1443-1818,B2055-2057,A0714-1238,Z1045-1344,A1643-1717,B1832-2039,J1623-1931         1238-1338
43      Z1921-1933,A1208-1418,I0827-1940,Z0757-1917,J0653-1554,B1859-1909       1554-1654").

2018.7.17追加
Juliaに移してみました。
今までPrologでは問題のデータ数が不定のときの入力に苦労したのですが、Juliaのほうが楽です。
本体に関しては、引数の扱いに関して忘れていたことがあって引っ掛かりましたが、
そのほかは思ったより楽にできました。

str="10 	A1000-1130,B1230-1800,Z0800-1130,Z1131-2200 	-
11 	A1000-1130,B1231-1800,Z0800-1130,Z1131-2200 	1131-1231
12 	Z0800-0801 	-
13 	Z0800-1031,Z1129-1220,Z1315-1400,Z1459-1600 	1459-1559
14 	Z0800-2200,I1000-1600,J1030-1730 	1600-1700"

function solve(s2)
    function se(p,n)  #s2を引数にして関数を外に出しても s2 が変わる
        s=deepcopy(s2)
       if p=='Z'
           res=false
       else
          res=true
       end
       while s!=[]
          cond=pop!(s)
          if cond[1]==p
              from=parse(cond[2:5])
              to=parse(cond[7:10])
              tb=div(from,100)*60+mod(from,100)
              te=div(to,100)*60+mod(to,100)
              if p=='Z'
                 if tb<=n && n+60<=te
                    res=true
                    break
                 end
              else
                 if tb<n+60 && n<te
                    res=false
                    break
                 end
             end
         end
       end
       return res
    end

  ans="-"
  for i in 600:1020
      if se('A',i) && se('B',i) && se('Z',i) && (se('I',i) || se('J',i))
          i1=div(i,60)
          i2=mod(i,60)
          ans=string(i1*100+i2)*"-"*string((i1+1)*100+i2)
          break
      end
  end
  return ans
end

function main()
str0=split(str,"\n")
for s0 in str0
  s1=split(s0,"\t")
  s2=split(s1[2],",")
  ans=solve(s2)
  if s1[3]==ans
   print("ok ")
  else
   print("no" )
   end
   println(ans)
end
end

main()

2018.7.22追加。
すみません。prologのdisp/2の最後disp1(X,S)が間違っていました。
disp1(S,X)が正しいです。

disp(0,A):-
     !,S="-",disp1(S,A).
disp(R,A):-
     D is R div 60,M is R mod 60,N1 is D*100+M,N2 is N1+100,
     concat_atom([N1,N2],"-",S),atom_chars(X,A),disp1(S,X).

2018.7.24追加
すみません、もう少しましなコードにならないか考えていましたら、
またまたPrologのほうに間違いが見つかってしまいました。
Zさんの条件にnotを使っていますので、一日中暇なときfalse->trueになるのでした。
そのような条件のテストケースがありませんでしたので、パスしてしまいました。
テストケースの例と正しいse/3は次のようになります。

se(P,N,L):-fil(P:_,L,L1),test(P,N,L1).

%"44      A1208-1418,I0827-1940,J0653-1554,B1859-1909       -"

なお1分ごとに続けて60分条件をクリアすれば成功という方法も、少しの修正でOKでした。
「どう書く」の皆さんはこちらの方法で解かれた方が多いようです

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?