ついに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専用です
- 1.45で動作するように修正しました
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;
type BoxGeneratorI64Send = Box<dyn Generator<Yield=i64,Return=()>+Unpin+Send>;
fn isqrt(n:i64) -> i64{
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:i64) -> i64{
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:i64) -> bool{
let x=isqrt(n);
return x*x==n;
}
fn is_cb(n:i64) -> bool{
let x=icbrt(n);
return x*x*x==n;
}
fn is_multiple(i:i64,n:i64) -> bool{i%n==0}
fn is_le(i:i64,n:i64) -> bool{i<=n}
fn next<T>(mut gen:impl Generator<Yield=T,Return=()>+Unpin) -> Option<T>{
// acknowledgement: https://github.com/tinaun/gen-iter/blob/master/src/lib.rs
match std::pin::Pin::new(&mut gen).resume(()) {
GeneratorState::Yielded(n) => Some(n),
GeneratorState::Complete(_) => None,
}
}
fn generate() -> BoxGeneratorI64Send{
return Box::new(move || { // move is optional in this line
let mut i=1;
loop{
yield i;
i+=1;
}
});
}
fn drop_prev(check:fn(i64)->bool,mut prev:BoxGeneratorI64Send) -> BoxGeneratorI64Send{
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(i64)->bool,mut prev:BoxGeneratorI64Send) -> BoxGeneratorI64Send{
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(i64,i64)->bool,n:i64,mut prev:BoxGeneratorI64Send) -> BoxGeneratorI64Send{
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:std::collections::HashMap<char,fn(BoxGeneratorI64Send)->BoxGeneratorI64Send> = std::collections::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(_) => ()
}}
}
220329
Swift編で得た知見をもとに、drop_prev等をクロージャを使ったものに変更しました。(nightlyは不要になりました)
// http://qiita.com/Nabetani/items/1c83005a854d2c6cbb69
// http://nabetani.sakura.ne.jp/hena/ord24eliseq/
use std::io::BufRead;
type BoxFnMutI64 = Box<dyn FnMut()->i64>;
fn isqrt(n:i64) -> i64{
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:i64) -> i64{
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:i64) -> bool{
let x=isqrt(n);
return x*x==n;
}
fn is_cb(n:i64) -> bool{
let x=icbrt(n);
return x*x*x==n;
}
fn is_multiple(i:i64,n:i64) -> bool{i%n==0}
fn is_le(i:i64,n:i64) -> bool{i<=n}
fn generate() -> BoxFnMutI64{
let mut i=0;
return Box::new(move || {
i+=1;
return i
})
}
fn drop_prev(check:fn(i64)->bool,mut prev:BoxFnMutI64) -> BoxFnMutI64{
let mut a = 0;
let mut b = prev();
return Box::new(move || {
loop {
a = b;
b = prev();
if !check(b) {
return a
}
}
})
}
fn drop_next(check:fn(i64)->bool,mut prev:BoxFnMutI64) -> BoxFnMutI64{
let mut first = true;
let mut a = 0;
let mut b = 0;
return Box::new(move || {
loop {
a = b;
b = prev();
if first || !check(a) {
first = false;
return b
}
}
})
}
fn drop_n(check:fn(i64,i64)->bool,n:i64,mut prev:BoxFnMutI64) -> BoxFnMutI64{
let mut i=0;
return Box::new(move || {
loop{
i+=1;
let a=prev();
if !check(i,n) {
return a
}
}
})
}
fn main() {
// cannot initialize Generator trait's HashMap using vec![].into_iter().collect() [E0277]
let mut f:std::collections::HashMap<char,fn(BoxFnMutI64)->BoxFnMutI64> = std::collections::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!("{}", z());
}
println!("");
},
Err(_) => ()
}}
}