Problem:
Score : 300 points

Problem Statement

You are given an integer N. Among the integers between 1 and N (inclusive), how many Shichi-Go-San numbers (literally "Seven-Five-Three numbers") are there?

Here, a Shichi-Go-San number is a positive integer that satisfies the following condition:

When the number is written in base ten, each of the digits 7, 5 and 3 appears at least once, and the other digits never appear.

Constraints

1 \leq N < 10^9

N is an integer.

Input

Input is given from Standard Input in the following format:

N

Output

Print the number of the Shichi-Go-San numbers between 1 and N (inclusive).

Sample Input 1

575

Sample Output 1

4

There are four Shichi-Go-San numbers not greater than 575: 357, 375, 537 and 573.

Sample Input 2

3600

Sample Output 2

13

There are 13 Shichi-Go-San numbers not greater than 3600: the above four numbers, 735, 753, 3357, 3375, 3537, 3557, 3573, 3575 and 3577.

Sample Input 3

999999999

Sample Output 3

26484

Solution in Scala (2.11.7) (judge verdict: Accepted)


object Main extends App {

  import scala.io.StdIn._
  import scala.math._

  val n = readLine.trim.toCharArray.map{_.asDigit}.toList
  val length = n.length
  implicit val memo = Array.tabulate(length + 1){_ ⇒ Array.tabulate(2){_ ⇒ Array.tabulate(2){_ ⇒ Array.tabulate(2){_ ⇒ None: Option[Long]}}}}

  println(
    count(n) + (3 until length).map{it ⇒ countWhole(it, false, false, false)}.sum
  )
  def count(digits: List[Int], useThree: Boolean = false, useFive: Boolean = false, useSeven: Boolean = false)(implicit memo: Array[Array[Array[Array[Option[Long]]]]]): Long = {
    digits match {
      case d::t ⇒
        (for (i ← List(3, 5, 7).filter(it ⇒ it <= d)) yield {
          if (d == i) count(t, useThree || i == 3, useFive || i == 5, useSeven || i == 7)
          else countWhole(t.length, useThree || i == 3, useFive || i == 5, useSeven || i == 7)
        }).sum
      case Nil if useThree && useFive && useSeven ⇒ 1L
      case _ ⇒ 0L
    }
  }
  def countWhole(digits: Int, useThree: Boolean, useFive: Boolean, useSeven: Boolean)(implicit memo: Array[Array[Array[Array[Option[Long]]]]]): Long = {
    if (digits != 0) {
      memo(digits)(if (useThree) 1 else 0: Int)(if (useFive) 1 else 0: Int)(if (useSeven) 1 else 0: Int) match {
        case Some(r) ⇒ r
        case None ⇒ (countWhole(digits - 1, true, useFive, useSeven) + countWhole(digits - 1, useThree, true, useSeven) + countWhole(digits - 1, useThree, useFive, true)).also{it ⇒
          memo(digits)(if (useThree) 1 else 0: Int)(if (useFive) 1 else 0: Int)(if (useSeven) 1 else 0: Int) = Some(it)
        }
      }
    }else {
      if (useThree && useFive && useSeven) 1L
      else 0L
    }
  }

  implicit class Extenion[T](val value :T){
    def also(func: T ⇒ Unit): T = {
      func(value)
      value
    }
    def let[R](func: T ⇒ R): R = func(value)
  }
}