Skip to content

Commit

Permalink
Merge pull request #21 from kmyk/develop
Browse files Browse the repository at this point in the history
v5.0.5.0
  • Loading branch information
kmyk authored Jun 25, 2021
2 parents 1c3376d + 6280001 commit ac95068
Show file tree
Hide file tree
Showing 47 changed files with 1,768 additions and 336 deletions.
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,55 @@
# Changelog for Jikka

## 2021-06-25: v5.0.5.0

Some optimizations are implemented.
Now it can convert a O(N) Python code for fibonacci to O(log N) C++ code.

Input, O(N):

``` python
def f(n: int) -> int:
a = 0
b = 1
for _ in range(n):
c = a + b
a = b
b = c
return a

def solve(n: int) -> int:
return f(n) % 1000000007
```

Output, O(log N):

``` c++
#include "jikka/all.hpp"
#include <algorithm>
#include <cstdint>
#include <functional>
#include <iostream>
#include <numeric>
#include <string>
#include <tuple>
#include <vector>
int64_t solve(int64_t n_317) {
return jikka::modmatap<2, 2>(
jikka::modmatpow<2>(jikka::make_array<std::array<int64_t, 2>>(
jikka::make_array<int64_t>(1, 1),
jikka::make_array<int64_t>(1, 0)),
n_317, 1000000007),
jikka::make_array<int64_t>(1, 0), 1000000007)[1];
}
int main() {
int64_t x318;
std::cin >> x318;
int64_t x319 = solve(x318);
std::cout << x319;
std::cout << '\n';
}
```
## 2021-06-23: v5.0.4.0
Now executable C++ code is generated.
Expand Down
112 changes: 38 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ for users:

- [docs/language.md](https://github.com/kmyk/Jikka/blob/master/docs/language.md)
- [CHANGELOG.md](https://github.com/kmyk/Jikka/blob/master/CHANGELOG.md)
- blog article [競技プログラミングの問題を自動で解きたい - うさぎ小屋](https://kimiyuki.net/blog/2020/12/09/automated-solvers-of-competitive-programming/)

for developpers:

Expand All @@ -37,87 +38,50 @@ for developpers:
- [Haddock](https://kmyk.github.io/Jikka/)


## Examples (`v3.1.0`)
## Examples (`v5.0.5.0`)

The below are examples of old the version (at `v3.1.0`). The input was a ML code.
Input, O(N):

### Sum of Max

Problem:
You are given a natural number K and a sequence A = (a₀, a₁, …, aₙ) of length N.
Compute the value of ∑ᵢ˱ₖ maxⱼ˱ₙ (i + 2 aⱼ).

Input, O(K N):

``` sml
let K = 100000 in
let given N : Nat in
let given A : N -> Nat in
sum K (fun i -> max N (fun j -> i + 2 * A j))
``` python
def f(n: int) -> int:
a = 0
b = 1
for _ in range(n):
c = a + b
a = b
b = c
return a

def solve(n: int) -> int:
return f(n) % 1000000007
```

Output, O(K + N):
Output, O(log N):

``` c++
int64_t solve(int64_t N, const vector<int64_t> & A) {
int64_t K = 100000;
int64_t a2 = 0;
for (int64_t i2 = 0; i2 < K; ++ i2) {
a2 += i2;
}
int64_t a1 = INT64_MIN;
for (int64_t i1 = 0; i1 < N; ++ i1) {
a1 = max(a1, 2 * A[i1]);
}
return a2 + K * a1;
}
```
### AtCoder Beginner Contest 134: C - Exception Handling
Problem: <https://atcoder.jp/contests/abc134/tasks/abc134_c>
Input, O(N^2):
``` sml
let given N : [2, 200001) in
let given A : N -> 200001 in
let f (i : N) = max N (fun j -> if j = i then 0 else A j) in
f
```

Output, O(N): <https://atcoder.jp/contests/abc134/submissions/6526623>


## Examples (`v5.0.1.0`)

``` console
$ cat examples/fact.py
def f(n: int) -> int:
if n == 0:
return 1
else:
return n * f(n - 1)

$ stack run convert examples/fact.py
int64_t f0_f(int64_t a1_n) {
bool x2 = a1_n == 0;
if (x2) {
return 1;
} else {
int64_t x3 = - 1;
int64_t x4 = x3;
int64_t x5 = x4;
int64_t x6 = a1_n + x5;
int64_t x7 = x6;
int64_t x8 = f0_f(x7);
return a1_n * x8;
}
#include "jikka/all.hpp"
#include <algorithm>
#include <cstdint>
#include <functional>
#include <iostream>
#include <numeric>
#include <string>
#include <tuple>
#include <vector>
int64_t solve(int64_t n_317) {
return jikka::modmatap<2, 2>(
jikka::modmatpow<2>(jikka::make_array<std::array<int64_t, 2>>(
jikka::make_array<int64_t>(1, 1),
jikka::make_array<int64_t>(1, 0)),
n_317, 1000000007),
jikka::make_array<int64_t>(1, 0), 1000000007)[1];
}
int64_t solve(int64_t a9) {
return f0_f(a9);
int main() {
int64_t x318;
std::cin >> x318;
int64_t x319 = solve(x318);
std::cout << x319;
std::cout << '\n';
}
```
Expand Down
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions examples/fib.2.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
100
1 change: 1 addition & 0 deletions examples/fib.2.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
687995182
1 change: 1 addition & 0 deletions examples/fib.large.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1000000000
1 change: 1 addition & 0 deletions examples/fib.large.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
21
5 changes: 4 additions & 1 deletion examples/fib.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
def solve(n: int) -> int:
def f(n: int) -> int:
a = 0
b = 1
for _ in range(n):
c = a + b
a = b
b = c
return a

def solve(n: int) -> int:
return f(n) % 1000000007
17 changes: 11 additions & 6 deletions examples/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@
set -ex
tempdir=$(mktemp -d)
trap "rm -rf $tempdir" EXIT
for f in examples/*.in ; do
diff <(stack --system-ghc run -- execute --target rpython ${f%.in}.py < $f) ${f%.in}.out
diff <(stack --system-ghc run -- execute --target core ${f%.in}.py < $f) ${f%.in}.out
stack --system-ghc run -- convert --target cxx ${f%.in}.py > $tempdir/$(basename $f .in).cpp
g++ -std=c++17 -Wall -O2 -Iruntime/include $tempdir/$(basename $f .in).cpp -o $tempdir/$(basename $f .in)
diff <($tempdir/$(basename $f .in) < $f) ${f%.in}.out
for input in examples/*.*.in ; do
output=${input%.in}.out
code=${input%.*.in}.py
name=$(basename ${input%.*.in})
if [[ ! $input =~ large ]] ; then
diff <(stack --system-ghc run -- execute --target rpython $code < $input) $output
fi
diff <(stack --system-ghc run -- execute --target core $code < $input) $output
stack --system-ghc run -- convert --target cxx $code > $tempdir/$name.cpp
g++ -std=c++17 -Wall -O2 -Iruntime/include $tempdir/$name.cpp -o $tempdir/$name
diff <($tempdir/$name < $input) $output
done
2 changes: 1 addition & 1 deletion package.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Jikka
version: 5.0.4.0
version: 5.0.5.0
github: "kmyk/Jikka"
license: Apache
author: "Kimiyuki Onaka"
Expand Down
137 changes: 137 additions & 0 deletions runtime/include/jikka/all.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#ifndef JIKKA_ALL_HPP
#define JIKKA_ALL_HPP
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdint>
#include <functional>
#include <numeric>
#include <vector>

Expand Down Expand Up @@ -41,6 +43,84 @@ inline int64_t pow(int64_t x, int64_t k) {
return y;
}

template <class T> inline T natind(T x, std::function<T(T)> f, int64_t n) {
if (n < 0) {
return x;
}
while (n--) {
x = f(x);
}
return x;
}

template <typename T, size_t H, size_t W>
using matrix = std::array<std::array<T, W>, H>;

template <class T, class... Args>
std::array<T, sizeof...(Args)> make_array(Args... args) {
return {args...};
}

template <size_t H, size_t W>
std::array<int64_t, H> matap(const matrix<int64_t, H, W> &a,
const std::array<int64_t, W> &b) {
std::array<int64_t, H> c = {};
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y] += a[y][x] * b[x];
}
}
return c;
}

template <size_t N> matrix<int64_t, N, N> matzero() { return {}; }

template <size_t N> matrix<int64_t, N, N> matone() {
matrix<int64_t, N, N> a = {};
for (size_t i = 0; i < N; ++i) {
a[i][i] = 1;
}
return a;
}

template <size_t H, size_t W>
matrix<int64_t, H, W> matadd(const matrix<int64_t, H, W> &a,
const matrix<int64_t, H, W> &b) {
matrix<int64_t, H, W> c;
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y][x] = a[y][x] + b[y][x];
}
}
return c;
}

template <size_t H, size_t N, size_t W>
matrix<int64_t, H, W> matmul(const matrix<int64_t, H, N> &a,
const matrix<int64_t, N, W> &b) {
matrix<int64_t, H, W> c = {};
for (size_t y = 0; y < H; ++y) {
for (size_t z = 0; z < N; ++z) {
for (size_t x = 0; x < W; ++x) {
c[y][x] += a[y][z] * b[z][x];
}
}
}
return c;
}

template <size_t N>
matrix<int64_t, N, N> matpow(matrix<int64_t, N, N> x, int64_t k) {
matrix<int64_t, N, N> y = matone<N>();
for (; k; k >>= 1) {
if (k & 1) {
y = matmul(y, x);
}
x = matmul(x, x);
}
return y;
}

inline int64_t modinv(int64_t value, int64_t MOD) {
assert(0 < value and value < MOD);
int64_t a = value, b = MOD;
Expand Down Expand Up @@ -77,6 +157,63 @@ inline int64_t modpow(int64_t x, int64_t k, int64_t MOD) {
return y;
}

template <size_t H, size_t W>
std::array<int64_t, H> modmatap(const matrix<int64_t, H, W> &a,
const std::array<int64_t, W> &b, int64_t MOD) {
std::array<int64_t, H> c = {};
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y] += a[y][x] * b[x] % MOD;
}
c[y] = floormod(c[y], MOD);
}
return c;
}

template <size_t H, size_t W>
matrix<int64_t, H, W> modmatadd(const matrix<int64_t, H, W> &a,
const matrix<int64_t, H, W> &b, int64_t MOD) {
matrix<int64_t, H, W> c;
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y][x] = floormod(a[y][x] + b[y][x], MOD);
}
}
return c;
}

template <size_t H, size_t N, size_t W>
matrix<int64_t, H, W> modmatmul(const matrix<int64_t, H, N> &a,
const matrix<int64_t, N, W> &b, int64_t MOD) {
matrix<int64_t, H, W> c = {};
for (size_t y = 0; y < H; ++y) {
for (size_t z = 0; z < N; ++z) {
for (size_t x = 0; x < W; ++x) {
c[y][x] += a[y][z] * b[z][x] % MOD;
}
}
}
for (size_t y = 0; y < H; ++y) {
for (size_t x = 0; x < W; ++x) {
c[y][x] = floormod(c[y][x], MOD);
}
}
return c;
}

template <size_t N>
matrix<int64_t, N, N> modmatpow(matrix<int64_t, N, N> x, int64_t k,
int64_t MOD) {
matrix<int64_t, N, N> y = matone<N>();
for (; k; k >>= 1) {
if (k & 1) {
y = modmatmul(y, x, MOD);
}
x = modmatmul(x, x, MOD);
}
return y;
}

template <class T> std::vector<T> cons(T x, const std::vector<T> &xs) {
std::vector<T> ys(xs.size() + 1);
ys[0] = x;
Expand Down
Loading

0 comments on commit ac95068

Please sign in to comment.