Rust
どう書く
yhpg
Julia

多段階選抜 (Julia/Rust)

多段階選抜
解答日
シリーズ:yieldの練習/ジェネレータを入れ子に/整数平方根・立方根の実装

問題
 

http://nabetani.sakura.ne.jp/hena/ord24eliseq/
https://qiita.com/Nabetani/items/1c83005a854d2c6cbb69

Ruby
2014/8/2(当日)
https://qiita.com/cielavenir/items/9f15e29b73ecf98968a5

C#/Python
2014/8/4
https://qiita.com/cielavenir/items/a1156e6a4f71ddbe5dcb

 
ここから上はdrop_prev_square/drop_prev_cubicをまとめる前の答案

Go/C#/Ruby/Python
2014/8/5
https://qiita.com/cielavenir/items/2a685d3080862f2c2c47

PHP/JavaScript
2014/9/9
https://qiita.com/cielavenir/items/28d613ac3823afbf8407

VB
2014/9/10
https://qiita.com/cielavenir/items/cb7266abd30eadd71c04

D
2015/12/21
https://qiita.com/cielavenir/items/47c9e50ee60bef2847ec

Perl
2017/3/10
https://qiita.com/cielavenir/items/6dfbff749d833c0fd423

Lua
2017/3/13
https://qiita.com/cielavenir/items/c60fe7e8da73487ba062

C++20(TS)
2017/3/15

https://qiita.com/cielavenir/items/e1129ca185008f49cbab (MSVC)
https://qiita.com/cielavenir/items/1cfa90d73d11bb7dc3d4 (clang)

F#
2017/3/17
https://qiita.com/cielavenir/items/a698d6a26824ff53de81

Boo/Nemerle
2017/5/13
https://qiita.com/cielavenir/items/e2a783f0fe4b0fe0ed48

Perl6
2017/5/15
https://qiita.com/cielavenir/items/656ea17fa96c865c4498

Kotlin
2017/5/25
https://qiita.com/cielavenir/items/9c46ce8d9d12e51de285

Crystal
2018/5/8
https://qiita.com/cielavenir/items/1815bfa6a860fd1f90db

MoonScript
2018/6/16
https://qiita.com/cielavenir/items/8b03cce0386f4537b5ad

Julia/Rust
2018/12/20
https://qiita.com/cielavenir/items/3ddf72b06d625da0c4a5

Nim
2018/12/26
https://qiita.com/cielavenir/items/5728944867e609fd52a7

Tcl
2018/12/31
https://qiita.com/cielavenir/items/76cbd9c2022b48c9a2c9

Pascal/Cobra
2019/1/16
https://qiita.com/cielavenir/items/81b81baf8dfc1f877903

Icon
2019/1/17
https://qiita.com/cielavenir/items/889622dcc721f5a4da24

(icbrtの実装に関する)補題
2017/5/11
整数除算であってもn/(x*y)はn/x/yに等しい(ことの証明)
https://qiita.com/cielavenir/items/21a6711afd6be8c18c55

ついに20言語到達( すべて無限リスト )。


Julia


  • Goからの移植。

  • juliac.jl対応してます。


tyama_hena24_enum.jl

#!/usr/bin/env julia

# http://qiita.com/Nabetani/items/1c83005a854d2c6cbb69
# http://nabetani.sakura.ne.jp/hena/ord24eliseq/

function isqrt(n::Int)
if n<=0
return 0
end
if n<4
return 1
end
local x=0
local y=n
while x!=y&&x+1!=y
x=y
y=(n÷y+y)÷2
end
return x
end

function icbrt(n::Int)
if n<0
return icbrt(-n)
end
if n==0
return 0
end
if n<8
return 1
end
local x=0
local y=n
while x!=y&&x+1!=y
x=y
y=(n÷y÷y+y*2)÷3
end
return x
end

function is_sq(n::Int)
local x=isqrt(n)
return x*x==n
end
function is_cb(n::Int)
local x=icbrt(n)
return x*x*x==n
end
is_multiple(i::Int,n::Int) = i%n==0
is_le(i::Int,n::Int) = i<=n

function generate()
local ch = Channel{Int}(8)
function _producer()
local i=1
while true
put!(ch,i)
i+=1
end
end
@async _producer()
ch
end

function drop_prev(check::Function,prev::Channel{Int})
local ch = Channel{Int}(8)
function _producer()
local a=take!(prev)
local b=take!(prev)
while true
if !check(b)
put!(ch,a)
end
a=b
b=take!(prev)
end
end
@async _producer()
return ch
end

function drop_next(check,prev::Channel{Int})
local ch = Channel{Int}(8)
function _producer()
local a=take!(prev)
local b=take!(prev)
put!(ch,a)
while true
if !check(a)
put!(ch,b)
end
a=b
b=take!(prev)
end
end
@async _producer()
return ch
end

function drop_n(check,n::Int,prev::Channel{Int})
local ch = Channel{Int}(8)
function _producer()
local i=0
while true
i+=1
a=take!(prev)
if !check(i,n)
put!(ch,a)
end
end
end
@async _producer()
return ch
end

Base.@ccallable function julia_main(args::Vector{String})::Cint
local f=Dict(
'S' => prev -> drop_next(is_sq,prev),
's' => prev -> drop_prev(is_sq,prev),
'C' => prev -> drop_next(is_cb,prev),
'c' => prev -> drop_prev(is_cb,prev),
'h' => prev -> drop_n(is_le,100,prev)
)
for j in 2:9
#ラムダ式のキャプチャはバグらないみたいですね
f[j+'0']=prev -> drop_n(is_multiple,j,prev)
end

local line=readline(stdin)
while line!=""
line=rstrip(line)
#cS => f['S'](f['c'](generate()))
local ch = generate()
for c in line
ch=f[c](ch)
end
for i in 0:9
if i>0
print(",")
end
a=take!(ch)
print(a)
end
print("\n")
flush(stdout)
line=readline(stdin)
end
return 0
end

if get(ENV, "COMPILE_STATIC", "false") == "false"
julia_main(ARGS)
end



Rust


  • (1.33時点で)nightly専用です


tyama_hena24_enum.rs

// http://qiita.com/Nabetani/items/1c83005a854d2c6cbb69

// http://nabetani.sakura.ne.jp/hena/ord24eliseq/

#![feature(generators, generator_trait)]
use std::ops::{Generator, GeneratorState};

use std::io::BufRead;
use std::collections::HashMap;

type BoxGeneratorI32Send = Box<dyn Generator<Yield=i32,Return=()>+Send>;

fn isqrt(n:i32) -> i32{
if n<=0 {
return 0;
}
if n<4 {
return 1;
}
let mut x=0;
let mut y=n;
while x!=y&&x+1!=y {
x=y;
y=(n/y+y)/2;
}
return x;
}

fn icbrt(n:i32) -> i32{
if n<0 {
return icbrt(-n);
}
if n==0 {
return 0;
}
if n<8 {
return 1;
}
let mut x=0;
let mut y=n;
while x!=y&&x+1!=y {
x=y;
y=(n/y/y+y*2)/3;
}
return x;
}

fn is_sq(n:i32) -> bool{
let x=isqrt(n);
return x*x==n;
}
fn is_cb(n:i32) -> bool{
let x=icbrt(n);
return x*x*x==n;
}
fn is_multiple(i:i32,n:i32) -> bool{i%n==0}
fn is_le(i:i32,n:i32) -> bool{i<=n}

fn next<T>(mut gen:impl Generator<Yield=T,Return=()>) -> Option<T>{
// acknowledgement: https://github.com/tinaun/gen-iter/blob/master/src/lib.rs
match unsafe {gen.resume()} {
GeneratorState::Yielded(n) => Some(n),
GeneratorState::Complete(_) => None,
}
}

fn generate() -> BoxGeneratorI32Send{
return Box::new(|| {// move is optional in this line
let mut i=1;
loop{
yield i;
i+=1;
}
});
}

fn drop_prev(check:fn(i32)->bool,mut prev:BoxGeneratorI32Send) -> BoxGeneratorI32Send{
return Box::new(move || {
let mut a=next(&mut prev).unwrap();
let mut b=next(&mut prev).unwrap();
loop{
if !check(b) {
yield a;
}
a=b;
b=next(&mut prev).unwrap();
}
});
}

fn drop_next(check:fn(i32)->bool,mut prev:BoxGeneratorI32Send) -> BoxGeneratorI32Send{
return Box::new(move || {
let mut a=next(&mut prev).unwrap();
let mut b=next(&mut prev).unwrap();
yield a;
loop{
if !check(a) {
yield b;
}
a=b;
b=next(&mut prev).unwrap();
}
});
}

fn drop_n(check:fn(i32,i32)->bool,n:i32,mut prev:BoxGeneratorI32Send) -> BoxGeneratorI32Send{
return Box::new(move || {
let mut i=0;
loop{
i+=1;
let a=next(&mut prev).unwrap();
if !check(i,n) {
yield a;
}
}
});
}

fn main() {
// cannot initialize Generator trait's HashMap using vec![].into_iter().collect() [E0277]
let mut f:HashMap<char,fn(BoxGeneratorI32Send)->BoxGeneratorI32Send> = HashMap::new();
f.insert('S',|e|{drop_next(is_sq,e)});
f.insert('s',|e|{drop_prev(is_sq,e)});
f.insert('C',|e|{drop_next(is_cb,e)});
f.insert('c',|e|{drop_prev(is_cb,e)});
f.insert('h',|e|{drop_n(is_le,100,e)});

//due to complicated lifetime, for now I don't use for-loop here
f.insert('2',|e|{drop_n(is_multiple,2,e)});
f.insert('3',|e|{drop_n(is_multiple,3,e)});
f.insert('4',|e|{drop_n(is_multiple,4,e)});
f.insert('5',|e|{drop_n(is_multiple,5,e)});
f.insert('6',|e|{drop_n(is_multiple,6,e)});
f.insert('7',|e|{drop_n(is_multiple,7,e)});
f.insert('8',|e|{drop_n(is_multiple,8,e)});
f.insert('9',|e|{drop_n(is_multiple,9,e)});

let stdin = std::io::stdin();
for line in stdin.lock().lines() {
match line {
Ok(s) => {
let mut z=generate();
for c in s.trim().chars() {
z=f[&c](z);
}
for i in 0..10 {
if i>0 {
print!(",");
}
print!("{}", next(&mut z).unwrap());
}
println!("");
},
Err(_) => ()
}}
}