Problem:
FizzBuzz

FizzBuzzとは、1以上の整数を順に、以下のルールに従って発言していくゲームである。

3で割り切れる時には「Fizz」

5で割り切れる時には「Buzz」

3と5の両方で割り切れる時には「FizzBuzz」

それ以外の時はその数字

ゲームの進行状況の例を以下に示す。

1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16, …

得られた発言を1つの文字列に結合し得られた文字列をFizzBuzz Stringと呼ぶ。インデックスsが与えられるので、FizzBuzz Stringのs文字目から20文字を出力せよ。但し、インデックスは1から始まるものとし、得られた文字列の長さは十分に大きい（s+20以上）としてよい。

Input

入力は以下の形式で与えられる

s

Constraints

sは整数である

1 ≤ s ≤ 1018

Output

FizzBuzz Stringのs文字目から20文字を1行に出力せよ

Sample Input 1

1

Output for the Sample Input 1

12Fizz4BuzzFizz78Fiz

Sample Input 2

20

Output for the Sample Input 2

zzBuzz11Fizz1314Fizz

Sample Input 3

10000000000

Output for the Sample Input 3

93FizzBuzz1418650796

Solution in Scala (judge verdict: Accepted)

import scala.annotation.tailrec
import scala.collection.{immutable, mutable}


object Main extends App {

  import scala.io.StdIn._

  val idx = readLong()
  var min = 1L
  var max = idx
  while (min < max) {
    val mid = (min + max) / 2
    if (calDigitUnder(mid) < idx) min = mid + 1
    else max = mid
  }
  val rest = idx - calDigitUnder(min - 1) - 1
  println(toSequence(min, min + 20).substring(rest.toInt, rest.toInt + 20))
  def toSequence(from: Long, until: Long): String = {
    (from until until).map{
      case n if n % 15 == 0 ⇒ "FizzBuzz"
      case n if n % 3 == 0 ⇒ "Fizz"
      case n if n % 5 == 0 ⇒ "Buzz"
      case n ⇒ n.toString
    }.mkString("")
  }

  def calDigitJustDigit(digit: Int): Long = {
    val value = power(10, digit) - 1
    val nonStr = value - value / 3 - value / 5 + value / 15
    val underValue = value / 10
    val underNonStr = underValue - underValue / 3 - underValue / 5 + underValue / 15
    (nonStr - underNonStr) * digit + (value / 3 - underValue / 3) * 4 + (value / 5 - underValue / 5) * 4
  }

  def calDigitUnder(number: Long): Long = {
    val digit = calDigit(number)
    val under = power(10, digit - 1) - 1
    val underDigit = (1 until digit).map(calDigitJustDigit).sum
    val underStr = under / 3 + under / 5 - under / 15
    val str = number / 3 + number / 5 - number / 15 - underStr
    val nonStr = number - under - str
    underDigit + nonStr * digit + (number / 3 - under / 3 + number / 5 - under / 5) * 4
  }

  def calDigit(number: Long): Int = {
    if (number < 10) 1 else 1 + calDigit(number / 10)
  }

  def power(base: Long, exp: Int): Long = {
    exp match {
      case 0 ⇒ 1L
      case 1 ⇒ base
      case _ ⇒ power(base * base, exp / 2) * power(base, exp % 2)
    }
  }
}