今年、流行った「五つの問題」を今頃、知りました。
色々な言語での解答が発表されていますが、おそらく誰もやらないであろう、VBAで挑戦してみました。
私がVBAの最大の弱点だと思うのが配列。ところがこの「五つの問題」はどれも配列を使わないと解けません。これに苦戦しました。
Five programming problems every Software Engineer should be able to solve in less than 1 hour – Shifted Up
目次
- 1. Write three functions that compute the sum of the numbers in a given list using a for-loop, a while-loop, and recursion.
- 2. Write a function that combines two lists by alternatingly taking elements. For example: given the two lists [a, b, c] and [1, 2, 3], the function should return [a, 1, b, 2, c, 3].
- 3. Write a function that computes the list of the first 100 Fibonacci numbers.
- 4. Write a function that given a list of non negative integers, arranges them such that they form the largest possible number.
- 5. Write a program that outputs all possibilities to put + or – or nothing between the numbers 1, 2, …, 9 (in this order) such that the result is always 100.
1. Write three functions that compute the sum of the numbers in a given list using a for-loop, a while-loop, and recursion.
「forループ、whileループ、再帰を使って、与えられた数を合計する三つの関数を書け。」という問題です。VBAで再帰が使えるのかと思いましたができました。
Function sum_for(a)
s = 0
For i = 0 To UBound(a)
s = s + a(i)
Next i
sum_for = s
End Function
Function sum_while(a)
s = 0
i = 0
Do
s = s + a(i)
i = i + 1
Loop While i <= UBound(a)
sum_while = s
End Function
Function sum_recursion(a)
U = UBound(a)
If U = 0 Then
sum_recursion = a(U)
Else
x = a(U)
ReDim Preserve a(U - 1)
sum_recursion = sum_recursion(a) + x
End If
End Function
s = 0
For i = 0 To UBound(a)
s = s + a(i)
Next i
sum_for = s
End Function
Function sum_while(a)
s = 0
i = 0
Do
s = s + a(i)
i = i + 1
Loop While i <= UBound(a)
sum_while = s
End Function
Function sum_recursion(a)
U = UBound(a)
If U = 0 Then
sum_recursion = a(U)
Else
x = a(U)
ReDim Preserve a(U - 1)
sum_recursion = sum_recursion(a) + x
End If
End Function
2. Write a function that combines two lists by alternatingly taking elements. For example: given the two lists [a, b, c] and [1, 2, 3], the function should return [a, 1, b, 2, c, 3].
「交互に要素を取って二つのリストを結合する関数を書け」という問題。
Function func(a, b)
U = UBound(a)
ReDim c(U * 2 + 1)
For i = 0 To U
c(i * 2) = a(i)
c(i * 2 + 1) = b(i)
Next i
func = c
End Function
U = UBound(a)
ReDim c(U * 2 + 1)
For i = 0 To U
c(i * 2) = a(i)
c(i * 2 + 1) = b(i)
Next i
func = c
End Function
3. Write a function that computes the list of the first 100 Fibonacci numbers.
「初めから100個のフィボナッチ数のリストを求める関数を書け」という問題。実際に実行すると桁が足りませんが無視しました。
Function func(n)
ReDim a(n - 1)
a(0) = 0
a(1) = 1
For i = 2 To n - 1
a(i) = a(i - 2) + a(i - 1)
Next i
func = a
End Function
ReDim a(n - 1)
a(0) = 0
a(1) = 1
For i = 2 To n - 1
a(i) = a(i - 2) + a(i - 1)
Next i
func = a
End Function
4. Write a function that given a list of non negative integers, arranges them such that they form the largest possible number.
「負でない整数を並び替えて最大となる数を求める関数を書け」という問題。これに苦労しました。順列を調べて片端から比較していけばいいのですが、そもそも順列を求めないといけません。それで書いたのが次の記事。
VBAで順列 | You Look Too Cool
これを使えば簡単です。
Function func(a)
x = junretsu(a)
m = 0
For i = 0 To UBound(x)
temp = Join(x(i), "")
If temp - m > 0 Then
m = temp
End If
Next i
func = m
End Function
x = junretsu(a)
m = 0
For i = 0 To UBound(x)
temp = Join(x(i), "")
If temp - m > 0 Then
m = temp
End If
Next i
func = m
End Function
5. Write a program that outputs all possibilities to put + or – or nothing between the numbers 1, 2, …, 9 (in this order) such that the result is always 100.
「1から9までの数字の間に「プラス」「マイナス」「なし」を挟んで100になるすべての式を出力するプログラムを書け」という問題。
9個の数字の間は8か所あり3種類の記号があるので3の8乗で6561通りの式が考えられます。
VBAにはEvaluateという与えられた式を計算する仕組みがあるのでこれを使います。
Function func()
a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
b = Array("+", "-", "")
ReDim r(100)
k = 0
For i = 0 To 6560
n = i
t = a(0)
For j = 1 To 8
x = n Mod 3
n = (n - x) / 3
t = t & b(x) & a(j)
Next j
If Evaluate(t) = 100 Then
r(k) = t
k = k + 1
End If
Next i
ReDim Preserve r(k - 1)
func = r
End Function
a = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
b = Array("+", "-", "")
ReDim r(100)
k = 0
For i = 0 To 6560
n = i
t = a(0)
For j = 1 To 8
x = n Mod 3
n = (n - x) / 3
t = t & b(x) & a(j)
Next j
If Evaluate(t) = 100 Then
r(k) = t
k = k + 1
End If
Next i
ReDim Preserve r(k - 1)
func = r
End Function
コメント