LoginSignup
9
1

More than 5 years have passed since last update.

KotlinのFizzBazzで35億になったら`ブルゾンちえみ With B` #teratail_kt

Last updated at Posted at 2018-04-15

#teratail_ktにて(UbuntuにKotlinをインストールしてハローワールドまでやってみた #teratail_kt)から引き続き。

FizzBazzだけだとつまらないので35で割り切れる場合にWith Bにします。

それだけなんだけど結構勉強になりました。

通常のFizzBazz

fizzbazz.kt
fun main(args: Array<String>) {
    for (i in 1..100) {
        when {
            i % 15 == 0 -> println("FizzBuzz")
            i % 3 == 0 -> println("Fizz")
            i % 5 == 0 -> println("Buzz")
             else -> println(i)
        }
    }
}

実行すると数字が100までカウントアップしていきFizzのときとBazzのときとFizzBazzのときは表示が変わります。

1
2
Fizz
4
Buzz
Fizz
7

Kotlinで35億を扱う

上記コードでそのまま35億(3500000000)を扱おうとしてみます。

35.kt
fun main(args: Array<String>) {
    for (i in 1..3500000000) {
        when {
            i % 15 == 0 -> println("FizzBuzz")
            i % 3 == 0 -> println("Fizz")
            i % 5 == 0 -> println("Buzz")
             else -> println(i)
        }
    }
}

エラーになりました。Intの桁数っぽいですね。

$ kotlinc ./35.kt -include-runtime -d 35.jar
35.kt:4:13: error: operator '==' cannot be applied to 'Long' and 'Int'
            i % 15 == 0 -> println("FizzBuzz")
            ^
35.kt:5:13: error: operator '==' cannot be applied to 'Long' and 'Int'
            i % 3 == 0 -> println("Fizz")
            ^
35.kt:6:13: error: operator '==' cannot be applied to 'Long' and 'Int'
            i % 5 == 0 -> println("Buzz")
            ^

型推論で変数iがInt型になっていますが、KotlinのInt型が32ビットということで範囲外のようです。

32ビット - Wikipedia
32ビットアーキテクチャ 32ビットに格納できる符号なし整数の範囲は、0 から 4,294,967,295 である。 2の補数で表現できる符号付き整数は −2,147,483,648 から 2,147,483,647 を格納できる。

KotlinのIntの最大値を調べてみる

Int.MAX_VALUEで調べることができます。

maxint.kt
fun main(args: Array<String>) {
    println(Int.MAX_VALUE)
}
$ kotlinc ./maxint.kt -include-runtime -d maxint.jar
$ kotlin maxint.jar
2147483647

実行すると2147483647が最大値ということが分かります。

ブルゾンちえみ風に言うと 21億と4000万ですね。

つまり35億はそのままでは扱えません。

ちなみに調べたら最初にあたったこちらの記事でJavaだとSystem.out.println(Integer.MAX_VALUE);で調べられるとあったのでKotlinのコードの中にそのまま記載してみましたが、問題なく動いてました。

やはり歴史的にJavaは記事の文献がかなり多いので、検索ヒットしやすいです。
Javaで調べつつそのコードをKotlinで試すというのがやりやすいかもと思いました。
Javaのコードがそのまま動くKotlinの利点ですね。

maxint.kt
fun main(args: Array<String>) {
    System.out.println(Integer.MAX_VALUE);
}

Int型ではなくLong型を使う

ということでLong型を利用します。

35.kt
fun main(args: Array<String>) {
        var i: Long = 3500000000
        println(i)
}
$ kotlinc ./35.kt -include-runtime -d 35.jar
$ kotlin 35.jar

3500000000

ちゃんと35億が表示されました。

35億の剰余演算(%)

まだ剰余演算で課題があります。

35.kt
fun main(args: Array<String>) {
    var input: Long = 3500000000
    val malePopulation: Long = 3500000000 //世界中の男

    if(input % malePopulation == 0){
        println("35億")
    }
}
35.kt:5:8: error: operator '==' cannot be applied to 'Long' and 'Int'
    if(input % malePopulation == 0){
       ^

この表記の場合0がIntと判定されてしまう模様です。

toLong()でキャストすることで回避できます。

35.kt
fun main(args: Array<String>) {
    val input: Long = 3500000000
    val malePopulation: Long = 3500000000 //世界中の男

    if(input % malePopulation == 0.toLong()){
        println("35億")
    }
}

35億のときにブルゾンちえみ With BするFizzBazz

改めて仕様です。

  • 3で割り切れる時は"Fizz"
  • 5で割り切れる時は"Bazz"
  • 3でも5でも割り切れるときは"FizzBazz"
  • 35億で割り切れる時は"With B"
35fizzbazz.kt
fun main(args: Array<String>) {
    val malePopulation: Long = 3500000000 //世界中の男
    for (i in 1..malePopulation) {
        when {
            i % malePopulation == 0.toLong() -> println("With B")
            i % 15 == 0.toLong() -> println("FizzBuzz")
            i % 3 == 0.toLong() -> println("Fizz")
            i % 5 == 0.toLong() -> println("Buzz")
             else -> println(i)
        }
    }
}

さて実行ですが、 35億ループを回すのでめっちゃ時間かかります。 苦笑

何分くらいかかるのか執筆しながら検証中...

FizzBazzを引数入力に対応させる

for文使うと処理時間的に大変なので、引数入力に対応させます。

main()の引数argsで利用可能みたいです。

kotlin hello.jar 35など実行時に引数を指定するとprintln(args[0])で取得できます。

35fizzbazz.kt
fun main(args: Array<String>) {
    println("input:" + args[0])
    val i: Long = args[0].toLong()
    val malePopulation: Long = 3500000000 //世界中の男

    when {
        i % malePopulation == 0.toLong() -> println("with B")
        i % 15 == 0.toLong() -> println("fizzbuzz")
        i % 3 == 0.toLong() -> println("fizz")
        i % 5 == 0.toLong() -> println("buzz")
        else -> println("特に無し")
    }
}

結果

$ kotlin 35fizzbazz.jar 2
input:2
特に無し

$ kotlin 35fizzbazz.jar 3
input:3
fizz

$ kotlin 35fizzbazz.jar 5
input:5
buzz

$ kotlin 35fizzbazz.jar 15
input:15
fizzbuzz

$ kotlin 35fizzbazz.jar 3500000000
input:3500000000
with B

お疲れ様でした。

所感

FizzBazzも桁数が増えるとハマりどころあるんですね。
Intだけでは出来ないってあたりに学びありだし、処理時間かかりすぎるので引数の取り方も覚えたし...あとJavaでの整数最大値のInteger.MAX_VALUEとJavaコードとKotlinの併用も

なんとなく思いついた35億ネタだけど35億はキャスト周りを教えるネタとしてはとっつきやすくてよいネタかもとか思ったりしました。笑

9
1
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
9
1