6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

今週のアルゴリズム:最短経路の計算!(D/Go/JavaScript/Lua/Rでnext_permutation)

Last updated at Posted at 2013-12-25
Permutation Iterator next_permutation URL
C#/Go/Python/Ruby/VB まとめ含む http://qiita.com/cielavenir/items/ac96da5e3040c2edb78c
Boo/C#/Nemerle/VB http://qiita.com/cielavenir/items/0e07a024049017f7dea2
Java/Groovy/Scala/Fortran/Pascal http://qiita.com/cielavenir/items/4347fd0c6c69fa60804a
D/Go/JavaScript/Lua/R http://qiita.com/cielavenir/items/9e821d04f574a6623d03
Perl HSP/PHP/Python/Ruby http://qiita.com/cielavenir/items/006a878292c5be209231
Go2/Crystal/Kotlin/Nim/Julia http://qiita.com/cielavenir/items/74f8d547437154c14e72
V/Rust http://qiita.com/cielavenir/items/cec1812999547909a9e4
D/Nemerle/JavaScript/Perl6/PHP C/C++/Crystal/Go2/Julia
Kotlin/Nim/Perl/Perl6
(github参照)

D
std.algorithmを使わないほうが速かった。
それにしても 配列の長さの型がバージョンによって違う ってどういうことだろう。

#!/usr/bin/rdmd
import std.stdio, std.algorithm;
const int N=6;
void my_reverse(T)(T[] a,int start,int size){
	int end=start+size-1;
	for(;start<end;start++){
		T z=a[start];a[start]=a[end];a[end]=z;
		end--;
	}
}
bool my_next_permutation(T)(T[] a,int n){
	int siz=cast(int)a.length;
	if(n<0||siz<n)return false;
	int i;
	my_reverse(a,n,siz-n);
	for(i=cast(int)siz-2;i>=0;i--)if(a[i]<a[i+1])break;
	if(i<0){
		my_reverse(a,0,siz);
		return false;
	}
	int k=i;
	for(i=cast(int)siz-1;i>=k+1;i--)if(a[k]<a[i])break;
	int l=i;
	T z=a[k];a[k]=a[l];a[l]=z;
	my_reverse(a,k+1,siz-(k+1));
	return true;
}
bool my_next_permutation(T)(T[] a){
	return my_next_permutation(a,cast(int)a.length);
}
int main(){
	int r=0,i;
	int[] e0=new int[N*2],f0=new int[N*2];
	for(i=0;i<N;i++)e0[N+i]=f0[N+i]=1;
	int[N*2+1] e,f;
	do{
		for(i=0;i<N*2;i++)e[i+1]=e[i]+e0[i];
		do{
			for(i=0;i<N*2;i++){
				f[i+1]=f[i]+f0[i];
				if(e[i]==f[i]&&e[i+1]==f[i+1])break;
			}
			if(i==N*2)r++;
		}while(my_next_permutation(f0));
		//}while(nextPermutation(f0));
	}while(my_next_permutation(e0));
	//}while(nextPermutation(e0));
	writeln(r);
	return 0;
}

Go

package main
import (
	"fmt"
	"sort"
)

func reverse(a sort.Interface,start int,size int){
	for end:=start+size-1;start<end;start++ {
		a.Swap(start,end)
		end--
	}
}
func next_permutation(a sort.Interface, n int) bool{
	if n<0||a.Len()<n {return false}
	reverse(a,n,a.Len()-n)
	i:=0
	for i=a.Len()-2;i>=0;i-- {if a.Less(i,i+1) {break}}
	if i<0 {
		reverse(a,0,a.Len())
		return false
	}
	k:=i
	for i=a.Len()-1;i>=k+1;i-- {if a.Less(k,i) {break}}
	l:=i
	a.Swap(k,l)
	reverse(a,k+1,a.Len()-(k+1))
	return true
}

func main(){
	N:=6
	e0:=make([]int,N*2)
	f0:=make([]int,N*2)
	i:=0
	r:=0
	for i=0;i<N;i++ {e0[N+i]=1;f0[N+i]=1}
	sort.Sort(sort.IntSlice(e0))
	sort.Sort(sort.IntSlice(f0))
	e:=make([]int,N*2+1);
	f:=make([]int,N*2+1);
	for {
		for i=0;i<N*2;i++ {e[i+1]=e[i]+e0[i]}
		for {
			for i=0;i<N*2;i++ {
				f[i+1]=f[i]+f0[i]
				if e[i]==f[i]&&e[i+1]==f[i+1] {break}
			}
			if i==N*2 {r++}
			if !next_permutation(sort.IntSlice(f0),len(f0)) {break}
		}
		if !next_permutation(sort.IntSlice(e0),len(e0)) {break}
	}
	fmt.Println(r)
}

JavaScript

#!/usr/bin/node
var reverse=function(a,start,size){
	var end=start+size-1;
	for(;start<end;start++){
		var z=a[start];a[start]=a[end];a[end]=z;
		end--;
	}
}
var next_permutation=function(a,_n){
	var n=_n || a.length;
	if(n<0||a.length<n)return false;
	var i;
	reverse(a,n,a.length-n);
	for(i=a.length-2;i>=0;i--)if(a[i]<a[i+1])break;
	if(i<0){
		reverse(a,0,a.length);
		return false;
	}
	var k=i;
	for(i=a.length-1;i>=k+1;i--)if(a[k]<a[i])break;
	var l=i;
	var z=a[k];a[k]=a[l];a[l]=z;
	reverse(a,k+1,a.length-(k+1));
	return true;
}

var N=6;
var e0=[],f0=[],i,r=0;
for(i=0;i<N;i++){
	e0[i]=f0[i]=0;
	e0[N+i]=f0[N+i]=1;
}
var e=[0];
var f=[0];
do{
	for(i=0;i<N*2;i++)e[i+1]=e[i]+e0[i];
	do{
		for(i=0;i<N*2;i++){
			f[i+1]=f[i]+f0[i];
			if(e[i]==f[i]&&e[i+1]==f[i+1])break;
		}
		if(i==N*2)r++;
	}while(next_permutation(f0));
}while(next_permutation(e0));
console.log(r);

Lua
Luaの配列って1からでしたっけ…?

#!/usr/bin/lua
reverse=function(a,start,size)
	local end_=start+size-1
	for i=0,size/2-1 do
		z=a[start+i]
		a[start+i]=a[end_-i]
		a[end_-i]=z
	end
end
next_permutation=function(a,n)
	if not n then n=#a end
	if n<0 or #a<n then
		return false
	end
	local i=0
	reverse(a,n,#a+1-n)
	i=#a-1
	while i>=1 do
		if a[i]<a[i+1] then break end
		i=i-1
	end
	if i<1 then
		reverse(a,1,#a)
		return false
	end
	local k=i
	i=#a
	while i>=k+1 do
		if a[k]<a[i] then break end
		i=i-1
	end
	local l=i
	local z=a[k]
	a[k]=a[l]
	a[l]=z
	reverse(a,k+1,#a+1-(k+1))
	return true
end

N=6
e0={}
f0={}
r=0
for i=1,N do
	e0[i]=0
	f0[i]=0
	e0[N+i]=1
	f0[N+i]=1
end
table.sort(e0)
table.sort(f0)
e={}
f={}
e[1]=0
f[1]=0
repeat
	for i=1,N*2 do
		e[i+1]=e[i]+e0[i]
	end
	repeat
		x=1
		for i=1,N*2 do
			f[i+1]=f[i]+f0[i]
			if e[i]==f[i] and e[i+1]==f[i+1] then
				x=0
				break
			end
		end
		r=r+x
	until not next_permutation(f0)
until not next_permutation(e0)
print(r)

R
とにかく遅い。Rはこういう処理には不向きな言語なのだということを改めて認識。

#!/usr/bin/Rscript
next_permutation<-function(env,name,n=NA){
	a=get(name,env)
	if(is.na(n))n<-length(a)
	if(n<0||length(a)<n)return(FALSE)
	i<-0
	a<-c(a[1:n],rev(a[-n:0]))
	for(i in rev(1:(length(a)-1)))if(a[i]<a[i+1])break # r doesn't go beyond the range
	if(a[i]>=a[i+1]){
		assign(name,rev(a),env)
		return(FALSE)
	}
	k<-i
	for(i in rev((k+1):length(a)))if(a[k]<a[i])break
	l<-i
	z<-a[k];a[k]<-a[l];a[l]<-z
	assign(name,a<-c(a[1:k],rev(a[-k:0])),env)
	return(TRUE)
}

env<-new.env()
N<-6
e0<-1:(N*2)
f0<-1:(N*2)
i<-0
r<-0
for(i in 1:N){
	e0[i]=f0[i]=0
	e0[N+i]=f0[N+i]=1
}
e=0:(N*2)
f=0:(N*2)
assign("e0",e0,env)
assign("f0",f0,env)
repeat{
	e0=get("e0",env)
	for(i in 1:(N*2))e[i+1]<-e[i]+e0[i]
	repeat{
		f0=get("f0",env)
		x<-1
		for(i in 1:(N*2)){
			f[i+1]<-f[i]+f0[i]
			if(e[i]==f[i]&&e[i+1]==f[i+1]){x<-0;break}
		}
		r<-r+x
		if(!next_permutation(env,"f0"))break
	}
	if(!next_permutation(env,"e0"))break
}
cat(r)
cat("\n")
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?