多段階選抜 (Objective-C)


|多段階選抜|解答日|シリーズ:yieldの練習/ジェネレータを入れ子に/整数平方根・立方根の実装|
|:--|:--|:--|
|問題|　|http://nabetani.sakura.ne.jp/hena/ord24eliseq/<br>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)<br>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|
|Swift|2020/5/31|https://qiita.com/cielavenir/items/3b0b84a218e35d538f7f|
|Java/Groovy/Scala|2020/5/31|https://qiita.com/cielavenir/items/7f058203a8fd03b65870|
|V|2020/10/17|https://qiita.com/cielavenir/items/df30a6c101a97a713df5|
|Zig/Zen|2020/10/17|https://qiita.com/cielavenir/items/9cced9e4a94dcd70df0f|
|Pike|2020/11/2|https://qiita.com/cielavenir/items/3a8248f41611302b34fd|
|Vala/Smalltalk|2020/11/29|https://qiita.com/cielavenir/items/085dabe593cd916af5e8|
|Objective-C|2020/11/30|https://qiita.com/cielavenir/items/a1736e38789a3dd5cc5a|
|Ruby(Ractor)|2021/1/2|https://qiita.com/cielavenir/items/f493c6d512b63cc571cc|
|Python(_xxsubinterpreters)|2021/6/29|https://qiita.com/cielavenir/items/f1f581a055db918954f1|
|Falcon/Scheme|2021/9/5|https://qiita.com/cielavenir/items/c13d12cf44f0d17f4a94|
|Clojure/Lisp|2021/9/7|https://qiita.com/cielavenir/items/7458ba076f4e5bc0f196|
|(icbrtの実装に関する)補題|2017/5/11|整数除算であってもn/(x*y)はn/x/yに等しい(ことの証明)<br>https://qiita.com/cielavenir/items/21a6711afd6be8c18c55|

SmalltalkとSwiftで解けるならObjective-Cでも解けますよね…

```objc:tyama_hena24_enum.m
//usr/bin/true; tmpfile=$(mktemp); gcc -o $tmpfile -framework Foundation "$0" && $tmpfile; rm -f $tmpfile; exit

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

#import <stdio.h>
#import <Foundation/Foundation.h>

int isqrt(int n){
	if(n<=0)return 0;
	if(n<4)return 1;
	int x=0,y=n;
	for(;x!=y&&x+1!=y;)x=y,y=(n/y+y)/2;
	return x;
}
int icbrt(int n){
	if(n<0)return -icbrt(-n);
	if(n==0)return 0;
	if(n<8)return 1;
	int x=0,y=n;
	for(;x!=y&&x+1!=y;)x=y,y=(n/y/y+y*2)/3;
	return x;
}

typedef bool(*tbl)(long long);
typedef bool(*tbll)(long long,long long);

@interface generate_impl:NSEnumerator
-init;
-(NSNumber*)nextObject;
@end
@interface drop_prev_impl:NSEnumerator
-init:(tbl)check _:(id)prev;
-(NSNumber*)nextObject;
@end
@interface drop_next_impl:NSEnumerator
-init:(tbl)check _:(id)prev;
-(NSNumber*)nextObject;
@end
@interface drop_n_impl:NSEnumerator
-init:(tbll)check _:(long long)n _:(id)prev;
-(NSNumber*)nextObject;
@end

@implementation generate_impl
{
	long long i;
}
-init
{
	i=0;
	[super init];
	return self;
}
-(NSNumber*)nextObject;
{
	i+=1;
	return [NSNumber numberWithLongLong:i];
}
@end
id generate(){return [[[generate_impl alloc] init] autorelease];}

@implementation drop_prev_impl
{
	id prev;
	tbl check;
	long long a;
	long long b;
}
-init:(tbl)check_ _:(id)prev_
{
	prev=prev_;
	check=check_;
	a=0;
	b=[[prev nextObject] longLongValue];
	[super init];
	return self;
}
-(NSNumber*)nextObject;
{
	for(;;){
		a=b;
		b=[[prev nextObject] longLongValue];
		if(!check(b)){
			return [NSNumber numberWithLongLong:a];
		}
	}
}
@end
id drop_prev(tbl check,id prev){return [[[drop_prev_impl alloc] init:check _:prev] autorelease];}

@implementation drop_next_impl
{
	id prev;
	tbl check;
	bool first;
	long long a;
	long long b;
}
-init:(tbl)check_ _:(id)prev_
{
	prev=prev_;
	check=check_;
	first=true;
	a=0;
	b=0;
	[super init];
	return self;
}
-(NSNumber*)nextObject;
{
	for(;;){
		a=b;
		b=[[prev nextObject] longLongValue];
		if(first||!check(a)){
			first=false;
			return [NSNumber numberWithLongLong:b];
		}
	}
}
@end
id drop_next(tbl check,id prev){return [[[drop_next_impl alloc] init:check _:prev] autorelease];}

@implementation drop_n_impl
{
	id prev;
	tbll check;
	long long n;
	long long i;
}
-init:(tbll)check_ _:(long long)n_ _:(id)prev_
{
	prev=prev_;
	check=check_;
	n=n_;
	i=0;
	[super init];
	return self;
}
-(NSNumber*)nextObject;
{
	for(;;){
		i+=1;
		long long a=[[prev nextObject] longLongValue];
		if(!check(i,n)){
			return [NSNumber numberWithLongLong:a];
		}
	}
}
@end
id drop_n(tbll check,long long n,id prev){return [[[drop_n_impl alloc] init:check _:n _:prev] autorelease];}

bool is_sq(long long n){
	long long x=isqrt(n);
	return x*x==n;
}
bool is_cb(long long n){
	long long x=icbrt(n);
	return x*x*x==n;
}
bool is_multiple(long long i,long long n){return i%n==0;}
bool is_le(long long i,long long n){return i<=n;}

int main(){
	for(;;){
		id stream=generate();
		for(;;){
			char c=fgetc(stdin);
			if(c=='\n')break;
			else if(c=='S')stream=drop_next(is_sq,stream);
			else if(c=='s')stream=drop_prev(is_sq,stream);
			else if(c=='C')stream=drop_next(is_cb,stream);
			else if(c=='c')stream=drop_prev(is_cb,stream);
			else if(c=='h')stream=drop_n(is_le,100,stream);
			else if(c=='2')stream=drop_n(is_multiple,2,stream);
			else if(c=='3')stream=drop_n(is_multiple,3,stream);
			else if(c=='4')stream=drop_n(is_multiple,4,stream);
			else if(c=='5')stream=drop_n(is_multiple,5,stream);
			else if(c=='6')stream=drop_n(is_multiple,6,stream);
			else if(c=='7')stream=drop_n(is_multiple,7,stream);
			else if(c=='8')stream=drop_n(is_multiple,8,stream);
			else if(c=='9')stream=drop_n(is_multiple,9,stream);
			else return 0;
		}
		int ctr=0;
		for(NSNumber *num in stream){
			if(ctr>0)putchar(',');
			printf("%lld",[num longLongValue]);
			if(++ctr==10)break;
		}
		puts("");
		fflush(stdout);
	}
}
```