kmyk-jikka / jikka Goto Github PK
View Code? Open in Web Editor NEWan automated solver for problems of competitive programming
Home Page: https://kmyk-jikka.github.io/Jikka/playground
License: Apache License 2.0
an automated solver for problems of competitive programming
Home Page: https://kmyk-jikka.github.io/Jikka/playground
License: Apache License 2.0
選択肢は以下のふたつ。いまのところは入力コードの self-contained のために (1.) を推したい
a = int(input())
みたいな入力取得コードを解釈して変換するN A_1 A_2 ... A_N
みたいなのを書かせて生成する構文解析はだいたいできたので、型が付いていない λ 項が入力されていると見ることができる。したいのは式木を組み換えての最適化処理。なのでとりあえずいい感じに型再構築が必要。
どこかで機会を取って coverage を上げておきたい
core -> C++ の変換時に ad-hoc をやるのがよさそう
REP (i, n) REP (j, n) c[i + j] += a[i] * b[j]
があったら c = fft(a, b)
にするやつ
FFT
InverseFFT
みたいなやつを足す (あるいは Convolution
という組み込み関数を足す?) (Jikka.Core.Language.Expr)
$ jikka execute ...
で実行できるようにする (Jikka.Core.Execute)runtime/include/jikka/convoluion.hpp
を足して実装する#include "jikka/convolution.hpp"
とか #include <atcoder/convolution>
されるようにする (Jikka.CPlusPlus.Format)foldl (fun c i -> foldl (fun c j -> setAt c (i + j) a[i] b[j]) c (range n)) c (range n)
やあるいはこれと等価な部分式があれば、それを FFT
を使って書き直すような rewrite rule を足す (Jikka.Core.Convert.FFT みたいなのを足して Jikka.Core.Convert の中から呼び出す)テストにも使えるのであるとよい
再帰があると見積り不可能だけど、どうしよう
#133 で quasi quote を使って簡単に rewrite rule が書ける仕組みを追加したけど、これについてのドキュメントを書いておく必要がある
fact
とか choose
とかは jikka.fact
や jikka.choose
に rename してしまっていいと思うceildiv
とか ceilmod
とかも global で ceildiv = jikka.ceildiv
ってやってもらえばよいはずassert n == len(a)
を利用して map(lambda i: a[i], range(n))
を a
に変換するなどしたい
いまは restricted Python → core の変換時に無視してしまってる
C++ には計算量を考えたときに contraction が可能な型と不可能な型とがある。たとえば vector<int> xs;
のとき vector<int> ys = xs; ys.push_back(1); return f(ys, ys);
なら move を使って O(1) だが、vector<int> ys = xs; ys.push_back(1); return f(xs, ys);
ならば copy になって O(n) である。
この区別を中間言語あるいは Python の上でも持ちたい。contraction 不可能な型についての contraction を検出してエラーにし、そのような contraction をする rewrite rules を禁止して防ぎたい。
このために affine 型を利用したい。
依存型などは悪手だと考えているが、affine 型や線形型なら分かりやすいのでありだと思う。Rust での実績もある。
GHC の RULES pragma みたいに手軽に書きたい
{-# RULES
"map/map" forall f g xs. map f (map g xs) = map (f.g) xs
#-}
Template Haskell を使って準クオートで書けるようにするのがよい気がする
mapMapReduce :: Monad m => RewriteRule m
mapMapReduce = [rule| "map/map" forall f g xs. map f (map g xs) = map (f.g) xs |]
xs.count()
とか xs.append(x)
とかを書きたい。現在は Python パーサが method 呼び出しに対応していないので、そこから初める必要がある
とりあえず動かすことを優先で書いたものが v5.0.1.0 ですが、この上にものを積むには汚すぎてしんどいので仕様の再検討と実装の書き直しが必要そう。
Either String a
で頑張っているが、つらいJikka.Converter.Core
を Jikka.Core.Converter
にするなど他は多少は省略していいとしても、Jikka.Core.Convert
の中は手厚く書いておいた方がよい
不要な copy がたくさん挟まるせいで計算量が上がってしまっている
具体的には core の SetAt
関数がやばい。現在は Jikka.CPlusPlus.Convert.FromCore
で core から C++ への変換と諸々の inlining を同時に雑にやってしまっているが、できるだけ多くの情報を残したまま C++ に変換してさらにそこでもう一度いくらかの最適化をかけるようにする必要がありそう。「この変数が参照されるのはここが最後だから move してしまってよい」みたいなのを判断して最適化に使ったりしたい。
Knuth-Yao speedup - 週刊 spaghetti_source - TopCoder部
Monge 性の機械判定ってどうすればいいですか? HELP!
現状だと以下はすべて正しく動かない。そもそもそんな書き方をするのが悪いので、コンパイル時にエラーにしてしまいたい
c = 0
f = lambda x: x + c
c = 1
f(0) # => 1
f = lambda x: x + 1
f = lambda x: f(f(x))
f(0) # => 停止しない
def f(xs):
xs.append(0)
xs = []
f(xs)
xs # => [0]
アカウントの activation はしてもらった
現状だとたとえば以下のようなコードが書けてしまう。そして奥の方で分かりにくいエラーになるはず。これをちゃんと明示的に検出して分かりやすいエラーとして報告するようにしたい。
(lambda x: abs(x)) == (lambda y: y + 3)
(lambda x: abs(x)) < (lambda y: y + 3)
min(lambda x: abs(x)), (lambda y: y + 3))
邪魔なので消去したいのだけど、一般的な方法で消去するのが難しすぎて困っています。
ad-hoc に処理することはできるけどしんどいし役立つのか不明だしなのでできれば避けたい。
やること:
# https://atcoder.jp/contests/abc127/tasks/abc127_e
MOD: int = 10 ** 9 + 7
def solve(h: int, w: int, k: int) -> int:
ans = 0
for y1 in range(h):
for x1 in range(w):
for y2 in range(h):
for x2 in range(w):
if (y1, x1) < (y2, x2):
ans += choose(h * w - 2, k - 2) * (abs(y2 - y1) + abs(x2 - x1))
return ans % MOD
# https://atcoder.jp/contests/abc134/tasks/abc134_c
from typing import *
def solve(N: int, A: List[int]) -> List[int]:
assert 2 <= N <= 200000
assert len(A) == N
assert all(0 <= A_i <= 200000 for A_i in A)
ans = [-1 for _ in range(N)]
for i in range(N):
ans[i] = max((0 if j == i else A[j]) for j in range(N))
return ans
a == b
を true
にする0
にする。つまり a == b
を a - b == 0
にする
f
であって単射なものについて f(a) - f(b) == 0
を a - b == 0
にするnil == cons(x, xs)
を false
にcons(x, xs) == cons(y, ys)
を x == y && xs == ys
に展開するa == true
を a
にa == false
を not a
に再帰よりループの方が最適化しやすいのでほしい。
末尾再帰最適化というよりも停止性自動証明をやることになる。
ad-hoc に induction measure (つまり DP table の埋める順番) を総当たりして潰すことになりそう。
たとえば
def fact(n):
if n == 0:
return 1
else:
return n * fact(n - 1)
が
def fact(n):
dp = [-1 for _ in range(n + 1)]
dp[0] = 1
for i in range(n):
dp[n + 1] = (n + 1) * dp[n]
return dp[n]
になってほしい。
累積和を取ってある箇所を検出して、その累積和に対する更新が発生しているなら大域的に segment tree に書き換える、とかがよいかと思われる
方向付けのために胡乱なことを書いていたが、人目に付くところに置いておいても混乱を招くだけでよくなさそうなので消した。しかし重要なものでもあると考えているので、 Issue として残しておく。
4d6e5c3
slope trick の C++ 実装であってライセンスがはっきりしたもの (Apache 2.0 あるいはできれば CC0) を探しています。持ってる人がいればください
time limit 20 sec を使い切って落ちるのは何かがよくない。Ubuntu だと安定して通っていて特に macOS で遅い。詳しい理由は不明
言語機能
最適化
出力
周辺ツール
property-based なテストを足したい
int func(const std::vector<int> &a) { return [=]() { return a[0]; }(); }
ってやったときに O(n) になってそう。だめ
def main
があったら標準 Python に食わせて入出力を確認するのがよい
副作用を伴なうので厄介
The same with haskell/cabal#4739
Just execute the following on the environment mentioned below
stack build
environments:
$ stack --version
Version 2.7.1, Git revision 8afe0c2932716b0441cf4440d6942c59568b6b19 x86_64 hpack-0.34.4
macOS Catalina Version 10.15.5
build succeeds
$ stack build
Jikka> configure (lib + exe)
Configuring Jikka-5.0.5.0...
Jikka> build (lib + exe)
Preprocessing library for Jikka-5.0.5.0..
Building library for Jikka-5.0.5.0..
Preprocessing executable 'jikka' for Jikka-5.0.5.0..
Building executable 'jikka' for Jikka-5.0.5.0..
/Users/koki/programming/others/Jikka/<built-in>:15:10: error:
error: non-portable path to file '".stack-work/dist/x86_64-osx/Cabal-3.2.1.0/build/Jikka/autogen/cabal_macros.h"'; specified path differs in case from file name on disk [-Werror,-Wnonportable-include-path]
#include ".stack-work/dist/x86_64-osx/Cabal-3.2.1.0/build/jikka/autogen/cabal_macros.h"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
".stack-work/dist/x86_64-osx/Cabal-3.2.1.0/build/Jikka/autogen/cabal_macros.h"
1 error generated.
/Users/koki/programming/others/Jikka/.stack-work/dist/x86_64-osx/Cabal-3.2.1.0/build/jikka/autogen/Paths_Jikka.hs:1:1: error:
`gcc' failed in phase `C pre-processor'. (Exit code: 1)
|
1 | {-# LANGUAGE CPP #-}
| ^
-- While building package Jikka-5.0.5.0 (scroll up to its section to see the error) using:
/Users/koki/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_3.2.1.0_ghc-8.10.4 --builddir=.stack-work/dist/x86_64-osx/Cabal-3.2.1.0 build lib:Jikka exe:jikka --ghc-options " -fdiagnostics-color=always"
Process exited with code: ExitFailure 1
https://github.com/cannorin/FsCalc/blob/d6b0513f3c7c181a2051ca4497044387355ae4fb/FsCalc.fsproj#L6-L18 このようにえいっと書くと
$ dotnet tool -g install hogehoge [--add-source <custom-nuget-repo-url>]
のようにインストールできて$ hogehoge
で実行できるようになってよい
h_1[(i3 + 1)]
でなくて h3[i3 + 1]
ってなっててほしい
現状:
std::min<int64_t>(
x2[i3][1] + std::max<int64_t>(-h_1[(i3 + 1)] + h_1[(i3 + 2)],
h_1[(i3 + 1)] - h_1[(i3 + 2)]),
x2[i3][0] + std::max<int64_t>(-h_1[i3] + h_1[(i3 + 2)],
h_1[i3] - h_1[(i3 + 2)]))};
配る DP ともらう DP とを相互に変換する処理を書く。優先順位が高いのは配る形からもらう形へだけど、逆向きもあるとよい。普通のセグ木とか CHT とかだともらう形がうれしくて、双対セグ木だと配る形がうれしいので
もし
let x = e(...)
in let y = e(...)
in f(x, y)
があったら
let x = e(...)
in f(x, x)
にする
定数倍しか変わらないけど、違うループの中で別々に作られた同じ累積和とかはまとめたい
for i in range(n):
ans += sum(a[:i])
for i in range(n):
ans += sum(a[:i])
集めています。テストに使います。見つけたら教えてください。可能なら Python の愚直解やテストケースをプルリクしてくれるとよりうれしいです。
if(a, b, c) って書いたときに正格評価するのか遅延評価するのかが曖昧なのでよくない
GHC Core みたいに「型は項」をして高階型を足すのがよい
Currently we always use segment trees, but we replace them with binary indexed trees if possible because they have a little bit smaller constant-time factor.
-1 + a + b - a + 2
が b + 1
になってほしい
Jikka.Core.Language.ArithmeticalExpr
をするだけなのだけど、局所的な書き換えでは済まないから rewrite rule には落ちなさそう
現状 (v3.1.0
)
x + 0
→ x
とか if true then x else y
→ x
とか)sum (fun i -> A i + B i)
→ sum (fun i -> A i) + sum (fun j -> B j)
とか)max l r (fun i -> A i)
で l
が定数のときに累積和に書き直すとか)
xs.append(x)
だけでなく xs += [x]
や xs = xs + [x]
とも書けるようにしたい。特に xs = xs + [x]
は参照を破壊しないので互換性のために重要
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.