r-statistics-fanの日記

統計好きの現場の臨床医の覚書のようなもの

CodeIQ 7を数える

CodeIQ - 裏 RjpWiki

で面白そうなことをやっていた。

締め切りは過ぎたようなので、自分でもやってみる。

かぞえるのではなく、計算する感じにしたので、違反かもしれぬ。

一応文字列で入力することにより相当な桁数まで対応。

f5(カウントする数字、"12312312345123123123123")みたいな感じ。

合っているかどうかは、、、、わからぬ。

 

 

#「7」をカウントする場合は大丈夫のようですが、「0」をカウントする場合エラーが判明しました。訂正後のコードはこちら

 

f5 <- function(suuji, z){
if (nchar(z) == 1) {
if (suuji == 0){
return(0)
}else{
return(as.numeric(as.numeric(z) >= suuji))}}
else{
x <- rev(as.numeric(unlist(strsplit(z, "")))) #分解してベクトルに
keta <- length(x) #計算する数の桁数
ans <- numeric(keta) #答えのベクトル

ans[1] <- ans[1] + as.numeric(x[1] >= suuji) #1桁目
#a桁目がb 未満の数まで何個含むか(a>=2):
for (i in 2:keta){
ans[i -1] <- ans[i - 1] + (i - 1) * x[i]
if (x[i] > suuji){
ans[i] <- ans[i] + 1
}else if(x[i] == suuji){
ans[1:(i-1)] <- ans[1:(i-1)] + x[1:(i-1)]
ans[1] <- ans[1] + 1
}
}

for (j in 1:(keta - 1)){
ans[j + 1] <- ans[j + 1] + floor(ans[j] %/% 10)
ans[j] <- ans[j] - floor(ans[j] %/% 10) * 10
}
if (suuji == 0){
ans <- numeric(keta)
if (nchar(z) == 2){
ans[1] <- x[2]
return(paste(rev(ans), collapse = ""))
}else if(nchar(z) == 3 & x[3] == 1 & x[2] == 0){
return( 11 + x[1])
}else{
ans[1:(keta - 1)] <- ans[1:(keta - 1)] + x[2:keta]
for(k in 3:keta){
if (x[k] == 0){
ans[(k-1):(keta-1)] <- ans[(k-1):(keta-1)] + x[k:keta]
ans[k - 1] <- ans[k - 1] - 1
}else{
ans[(k-1):(keta-1)] <- ans[(k-1):(keta-1)] + x[k:keta]
}
}


for (j in 1:(keta - 1)){
ans[j + 1] <- ans[j + 1] + floor(ans[j] %/% 10)
ans[j] <- ans[j] - floor(ans[j] %/% 10) * 10
}
return(paste(rev(ans), collapse = "")) #rev:逆むき
}}else{
return(paste(rev(ans), collapse = "")) #rev:逆むき
}
}
}

 

> f5(7, "99")
[1] "20"
> f5(7, "77777")
[1] "38890"
> f5(7, "23678947")
[1] "16140633"
> f5(7, "732465890")
[1] "614891670"
> f5(7, "1912478368")
[1] "1728439836"
> f5(7, "1231321321321321231231231321231231231231321231231321321231231231231231321231231321231")
[1] "10316668271875478469099730892991622252883911144775722325667297928559189947451081758343"