裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

カードを使って数を作ろう(簡単編)

2016年09月02日 | ブログラミング

締め切りが 09/02 10:00 AM に設定されている(ずいぶん先だなあ)

ということで 09/02 10:01 AM に投稿されるように予約(あとで,締め切りが延ばされても,それには関知しない)

【概要】
カードが何枚かあります。
カードには、一桁の数字が書いてあります。
カードを n 枚選んで並べて数を作ります。
たとえば、「3」「1」「4」「1」「5」が書いてあるカードから 3 枚(つまり、n=3)を選んで並べると「341」や「115」を作ることができます( 「334」や「31」は作れません)。
作れる数のうち、ある数 m にもっとも近い数を答えてください。

【入出力】
入力は
4,1234,1/2/2/3/9/9/9
のような感じです。
コンマ区切りで、n(カードの枚数)、m(この値に近い数を作る)、カード列 が並んでいます。
カード列は、カードに書いてある数字をスラッシュ区切りで並べたものです。

出力は、
1232
のような感じです。最も近い数が 2 つある場合は、小さい順に両方共出力してください。
1233,1235
のような感じです。
末尾の改行はあってもなくても構いません。
作れる数がひとつもない場合には、- を出力してください。
 
【例】
入力     出力
4,1234,1/2/2/3/9/9/9     1232
4,1234,1/2/2/3/3/5/5     1233,1235

 
【補足】
「01」のような、「0」で始まる二桁以上の数は作れません。一桁の「0」は OK です。
カードの枚数は8枚以下です。
n は 1 以上で、カードの枚数を超えることはありません。
m は 0 以上、10の9乗以下です。
6 のカードを逆さにして 9 として使ったりすることはできません。
不正な入力に対処する必要はありません。

【テスト用データ】
1,3,0/9/8
2,10,0/9/8
3,414,3/4/9/8/7
4,4981,4/5/0/1/2/3/8
5,12345,0/0/0/0/0/0/0
5,43103,3/5/0/2/1/4/9/4
6,172365,3/2/3/7/2/7/1/6
7,6523060,4/0/7/2/6/5/3/3
8,19069255,1/2/9/3/7/6/9/0
8,80465325,2/6/5/7/8/9/7/7
8,88888888,8/8/8/8/8/8/8/8
8,88888888,9/8/7/6/5/4/3/2

perm = function(n) {
    z = matrix(1)
    if (n > 1) {
        for (i in 2:n) {
            x = cbind(z, i)
            a = c(1:i, 1:(i - 1))
            z = matrix(0, ncol = ncol(x), nrow = i * nrow(x))
            z[1:nrow(x), ] = x
            for (j in 2:i - 1) {
                z[j * nrow(x) + 1:nrow(x), ] = x[, a[1:i + j]]
            }
        }
    }
    dimnames(z) = NULL
    return(z)
}

func = function(s) {
    t = as.integer(unlist(strsplit(s, "[,/]")))
    n = t[1]
    m = t[2]
    t = t[-(1:2)]
    k = length(t)
    p = matrix(t[perm(k)], ncol=k)[,1:n, drop=FALSE]
    p = unique(p)
    if (n > 1) {
        p = p[p[,1] != 0, , drop=FALSE]
    }
    if (nrow(p) == 0) return("-")
    fac = if (n == 0) 1 else 10^((n-1):0)
    d = p %*% fac
    diff = abs(d-m)
    suf = which(diff == min(diff))
    paste(d[suf], collapse=",")
}

con = file("stdin", "r")
cat(func(readLines(con)))


コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 変進小数の足し算 | トップ | パターゴルフのコース設計 »
最新の画像もっと見る

コメントを投稿

ブログラミング」カテゴリの最新記事