from sequtils import map, mapIt, toSeq
from strutils import split, parseInt, parseFloat, parseBool, parseEnum #, #[if NimMinor >= 14:]# parseUint

import macros
# headaux macro -- https://stackoverflow.com/questions/31948131/unpack-multiple-variables-from-sequence
# unpack macro  -- https://chy72.hatenablog.com/entry/2017/12/16/214708
macro unpack*(input: array|seq|tuple; count: static[int]): untyped =
  var t = genSym()
  result = quote do: (let `t` = `input`; ())
  when NimMinor <= 17:
    for i in 0..<count: result[0][1].add quote do: `t`[`i`]
  else:
    for i in 0..<count: result[1].add quote do: `t`[`i`]

template input*(typ: static[typedesc]): seq =
  when typ is char:
    toSeq(stdin.readLine.items)
  elif typ is string:
    stdin.readLine.split
  else:
    stdin.readLine.split.map(`parse typ`)

# 2引数の input() は通常こちらが呼ばれる
template input*(typ: static[typedesc]; count: static[int]): untyped =
  input(typ).unpack(count)

# input(typ, [some integer].Positive) と指定しないとこちらは呼ばれない
template input*(typ: static[typedesc]; lineCount: Positive): untyped =
  (1..lineCount).mapIt(input(typ))

template input*(typ: static[typedesc]; count: static[int] = 1; lineCount: Positive): untyped =
  (1..lineCount).mapIt(input(typ, count))

macro inputs*(body: untyped): untyped =
  result = newNimNode(nnkStmtList)

  var letSection = newNimNode(nnkLetSection)

  var vars = newSeq[NimNode](body.len)
  for i, _ in vars:
    if body[i][0].len > 1: # (var1, var2, ...): int | float | string
      vars[i] = newNimNode(nnkVarTuple)
      for ident in body[i][0]:
        vars[i].add(ident)
      vars[i].add(newEmptyNode())
      vars[i].add(newNimNode(nnkCall)
                    .add(ident("input"))
                    .add(body[i][1][0])
                    .add(newLit(body[i][0].len))
                 )
    elif body[i][1][0].len == 0: # variable: int | float | string
      vars[i] = newIdentDefs(
        body[i][0],
        newEmptyNode(),
        newNimNode(nnkCall)
          .add(ident("input"))
          .add(body[i][1][0])
          .add(newLit(1))
      )
    elif body[i][1][0][0].len > 0: # variable: tuple[field1, field2, ...: T]
      var tupleIdents = newNimNode(nnkIdentDefs)
      for ident in body[i][1][0][0]:
        tupleIdents.add(ident)
      let tuplety = newNimNode(nnkTupleTy).add(tupleIdents)

      vars[i] = newIdentDefs(
        body[i][0],
        tuplety,
        newNimNode(nnkCall)
          .add(ident("input"))
          .add(body[i][1][0][0][^2])
          .add(newLit(body[i][1][0][0].len - 2))
      )
    elif body[i][1][0][0].len == 0: # seq
      if body[i][1][0].len == 2: # variable: seq[int | float | string | char]
        vars[i] = newIdentDefs(
          body[i][0],
          newEmptyNode(),
          newNimNode(nnkCall)
            .add(ident("input"))
            .add(body[i][1][0][1])
        )
      elif body[i][1][0].len == 3 and body[i][1][0][2].len == 0: # variable: seq[N, int | float | string | char]
        vars[i] = newIdentDefs(
          body[i][0],
          newEmptyNode(),
          newNimNode(nnkCall)
            .add(ident("input"))
            .add(body[i][1][0][2])
            .add(newLit(1))
            .add(body[i][1][0][1])
        )
      elif body[i][1][0][2].len == 2: # variable: seq[lineCount, seq[int | float | string | char]]
        vars[i] = newIdentDefs(
          body[i][0],
          newEmptyNode(),
          newNimNode(nnkCall)
            .add(ident("input"))
            .add(body[i][1][0][2][1])
            .add(newNimNode(nnkDotExpr)
              .add(body[i][1][0][1])
              .add(ident("Positive"))
            )
        )
      else: # variable: seq[lineCount, tuple[field1, field2, ...: T]]
        var tupleIdents = newNimNode(nnkIdentDefs)
        for ident in body[i][1][0][2][0]:
          tupleIdents.add(ident)
        let tuplety = newNimNode(nnkTupleTy).add(tupleIdents)

        vars[i] = newIdentDefs(
          body[i][0],
          newNimNode(nnkBracketExpr).add(body[i][1][0][0]).add(tuplety),
          newNimNode(nnkCall)
            .add(ident("input"))
            .add(body[i][1][0][2][0][^2])
            .add(newLit(body[i][1][0][2][0].len - 2))
            .add(body[i][1][0][1])
        )
    else:
      discard

  for `var` in vars:
    letSection.add(`var`)

  result.add(letSection)

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
template stderrEcho*(x: varargs[string, `$`]) =
  for v in x:
    stderr.write(v)
  stderr.writeLine ""

template stderrEcho*[T](x: seq[seq[T]]) =
  for v in x: stderrEcho v

template stderrEcho*(x: seq[string]) =
  for v in x: stderrEcho v

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
from math import `^`

inputs:
  K: int

proc f(): seq[int] =
  result = @[1, 2, 3, 4, 5, 6, 7, 8, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99, 199, 299, 399, 499, 599, 699, 799, 899, 999]
  for i in 3..16:
    let d = 10^i
    for j in 1..9:
      if j == 1:
        let e = 10^(i - 1)
        result.add(d + e - 1)
        for k in 1..9:
          result.add(result[^1] + e)
      else:
        result.add((j + 1) * d - 1)

const snukeNums = f()

for snukeNum in snukeNums[0..<K]:
  echo snukeNum


# from math import sum
# from sequtils import allIt

# proc S(n: int): int =
#   ($n).mapIt(($it).parseInt).sum

# var hoge = newSeq[float]()
# for i in 0..<30000:
#   hoge.add(i / S(i))

# var snukeNums = newSeq[int]()
# for i, h in hoge:
#   if hoge[(i + 1)..^1].allIt(h <= it):
#     snukeNums.add(i)

# stderrEcho snukeNums

# # 1, 2, 3, 4, 5, 6, 7, 8, 9, 19, 29, 39, 49, 59, 69, 79, 89, 99, 199, 299, 399, 499, 599, 699, 799, 899, 999, 1099, 1199, 1299, 1399, 1499, 1599, 1699, 1799, 1899, 1999, 2999, 3999, 4999, 5999, 6999, 7999, 8999, 9999, 10999, 11999, 12999, 13999, 14999, 15999, 16999, 17999, 18999, 19999, 20999, 21999, 22999, 23999, 24999, 25999, 26999, 27999, 28999, 29999
