裏 RjpWiki

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

実力判定:Aランク-その2

2017年12月31日 | ブログラミング

極めよプログラミング道!【実力判定:Aランク】その2

締め切りが 2017/12/31 10:00 AM なので,その 1 分後に投稿されるように予約


【問題】
1階は1部屋、2階は1部屋、3階は2部屋、4階は3部屋、5階は5部屋、6階は8部屋、7階は13部屋と、増えていく塔があります。
3階以降は、下の2つの階にある部屋数の合計となります。ただし、部屋数が16以上になった場合は、合計を16で割った余りとなります。
ある階数が示された場合、その階に何部屋あるのか答えてください。
提示される階数は、1から1000000000の範囲とします。

【入力】
標準入力から、複数行のデータが与えられます。1行のデータが、1セットの数字になります。
1セットの数字は、1つの階数の数字です。

【出力】
1行ずつ計算して、答えとなる数字を1行ごと標準出力に出力します。

【入出力サンプル】
Input
4
5
6
8
 
Output
3
5
8
5
 
==========================================

周期24とは,短すぎるだろ。列挙しちゃうぞ。

g = function(n) {
    a = c(1, 1, 2, 3, 5, 8, 13, 5, 2, 7, 9, 0, 9, 9, 2, 11, 13, 8, 5, 13, 2, 15, 1, 0)
    cat(sprintf("%i\n", a[(n-1)%%24+1]))
}
arg = scan(file("stdin", "r"))
junk = sapply(arg, g)


コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

実力判定:Sランク

2017年12月31日 | ブログラミング

実力判定:Sランク

締め切りが 2017/12/31 10:00 AM なので,その 1 分後に投稿されるように予約

【問題】
0から9の整数を、縦横それぞれN個並べた四角形があります。
左上から右下に、右あるいは下へと移動しながら、数を足していきます。
複数ある経路のうち、最小合計値となる経路をたどった場合の、合計値を答えてください。
ただし、Nは、2≦N≦20 の範囲の整数とします。# 20 ではなく 1000 だ!
 

567
133
502
上記の場合の全経路と合計値。
route: 56732, sum: 23
route: 56332, sum: 19
route: 56302, sum: 16
route: 51332, sum: 14
route: 51302, sum: 11
route: 51502, sum: 13
上記の場合の、最小合計値となる経路の図示。
567
133
502
最小合計値は「11」。
 
【入力】
標準入力から、複数行のデータが与えられます。縦横同じ文字数で、1つの正方形が作られます。
【出力】
最小合計値となる経路をたどった場合の合計値を、標準出力に出力します。
【入出力サンプル】
Input
567
133
502
 
Output
11
 
================================

R では簡単に書けるが,時間制限に引っかかる

f = function(s) {
    x = t(sapply(s, function(t) as.integer(unlist(strsplit(t, "")))))
    n = nrow(x)
    x[1:n, 1] = cumsum(x[1:n, 1])
    x[1, 1:n] = cumsum(x[1, 1:n])
    for (i in 2:n) {
        for (j in 2:n) {
            x[i, j] = x[i, j] + min(x[i-1, j], x[i, j-1])
        }
    }
    x[n, n]
}

cat(f(readLines(file("stdin", "r"))))

Java で書き直して OK となる

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        int i, m;
        int n = 0;
        int[][] x = new int[1000][1000];

        Scanner cin = new Scanner(System.in);
        String line;
        while (cin.hasNextLine()) {
            line = cin.nextLine();
            if (line.length() == 0) {
                break;
            }
            String[] ch = line.split("");
            m = ch.length - 1;
            for (i = 0; i < m; i++) {
                x[n][i] = Integer.parseInt(ch[i + 1]);
            }
            n++;
        }
        System.out.println(f(x, n));
    }

    static int f(int[][] x, int n) {
        int i, j;
        for (i = 1; i < n; i++) {
            x[i][0] += x[i - 1][0];
            x[0][i] += x[0][i - 1];
        }
        for (i = 1; i < n; i++) {
            for (j = 1; j < n; j++) {
                x[i][j] += Math.min(x[i - 1][j], x[i][j - 1]);
            }
        }
        return x[n - 1][n - 1];
    }

}


コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

実力判定:Aランク

2017年12月31日 | ブログラミング

実力判定:Aランク

締め切りが 2017/12/31 10:00 AM なので,その 1 分後に投稿されるように予約

【問題】
1から1,000,000までの整数の範囲で、連続する2値を合計します。
2値の合計が、整数Nの倍数になる組み合わせを、数えてください。
ただし、整数Nは、2≦N≦1,000 の範囲とします。


整数Nが11の場合、「5, 6(合計は11)」、「16,17(合計は33)」……という組み合わせが、整数Nの倍数になります。
また、連続する2値の最小は「1, 2(合計は3)」、最大は、「999999, 1000000(合計は1999999)」になります。

【入力】
標準入力から、複数行のデータが与えられます。1行のデータが、1つの整数Nになります。

【出力】
1行ずつ処理を行ない、その答えを1行ごと標準出力に出力します。

【入出力サンプル】
Input
307
456
545
165

Output
3257
0
1835
6061

=======================

1000行のテストデータがあるんだけど,その中に同じ値が複数個ある。
テストデータの準備としては,漫然としており,だらしない。

期待される結果と違うといわれたのであるが,テストデータがあまりにも多いので,どれが間違えているのか(あるいは,プログラムに不備があるのか)なかなかわからなかった。
結果としては,答えが 200000 となる場合に R では 2e+5 と出力されることがあるのが原因であった(options(scipen=100) とでもしておけばよいのだが)。

f = function(N) {
    invisible(sapply(N, function(n) {
        if (n %% 2 == 0) {
            m = 0
        } else {
            m = (1999999 %/% n + 1) %/% 2
        }
        options(scipen=100)
        cat(m, "\n", sep="")
    }))
}
f(scan(file("stdin", "r")))

より簡単に書くとこうなる。

f = function(N) {
    options(scipen=100)
    cat((ifelse(N %% 2, 1999999, 0) %/% N + 1) %/% 2, sep="\n")
}
f(scan(file("stdin", "r")))

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

実力判定:Cランク

2017年12月31日 | ブログラミング

実力判定:Cランク

締め切りが 2017/12/31 10:00 AM なので,その 1 分後に投稿されるように予約
きっと,締め切りは,再来年,再々来年...と繰り延べられるのだろうけど

【問題】

「0123456789」の10枚のカードの内、4枚のカードが提示されます。

通常は、「最も数値が大きなカード」が勝利者のカードです。
4枚の中に0があれば、「0以外で最も小さなカード」が勝利者のカードです。

勝利者のカードの数値を割り出してください。

【入力】

標準入力から、複数行のデータが与えられます。1行のデータが、1セットのゲームになります。

1行のデータは、数字4文字の文字列になります。この1文字ずつが、1枚のカードになります。

【出力】

1行ずつ結果を判定して、その答えとなる数字を、1行ごと標準出力に出力します。
 
【入出力サンプル】

Input

1234
6745
0149
3705

Output

4
7
1
3

==============================================================

R

f = function(S) {
    for (s in S) {
        s = as.integer(unlist(strsplit(s, "")))
        i = which(s == 0)
        if (length(i) > 0) {
            x = min(s[-i])
        } else {
            x = max(s)
        }
        cat(x, "\n", sep="")
    }
}
f(readLines(file("stdin", "r")))

==============================================================

AWK

awk '{
    split($0, x, "")
    Min = 100
    Max = -100
    zero = 0
    for (i = 1; 4 >= i; i++) {
        if (x[i] == 0) {
            zero = 1
        }
        else {
            Min = Min < x[i] ? Min : x[i]
            Max = Max > x[i] ? Max : x[i]
        }
    }
    if (zero == 1) {
        print Min
    }
    else {
        print Max
    }
        
}
'

==============================================================

Perl

use strict;
use warnings;
use utf8;
use List::Util qw/max min/; # min, max 関数を使うため

my ($line, $i, @char, $Min, $Max, $zero);

while (defined(my $line = )) {
    #    print $line;
    @char = split(//, $line);
    $Min = 10;
    $Max = -10;
    $zero = 0;
    for ($i = 0; $i < 4; $i++) {
        if ($char[$i] == 0){
            $zero = 1;
        }
        else {
            $Min = min($Min, $char[$i]);
            $Max = max($Max, $char[$i]);
        }
    }
    if ($zero) {
        print $Min, "\n";
    }
    else {
        print $Max, "\n";
    }
}

==============================================================

VB.net

imports System
module Crank
    sub Main()
        dim line as String
        dim m as Integer
        dim Min, Max, ans as Integer
        dim zero as Boolean
    for i as integer = 1 to 100
            line = Console.ReadLine() ' コンソールから入力
               Min = 10
            Max = -10
            zero = False
            for i as integer = 1 to 4
                   m = Integer.Parse(mid(line, i, 1)) ' 文字列を整数に変換
                    if (m = 0) then
                           zero = True
                    else
                        Min = Math.min(Min, m)
                        Max = Math.max(Max, m)
                    end if
            next
            if (zero) then
                ans = Min
            else
                ans = Max
            end if
            Console.WriteLine(ans) ' コンソールに出力 改行しないなら Console.Write()
        next
    end sub
end module

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

実力判定:Bランク

2017年12月31日 | ブログラミング

実力判定:Bランク

締め切りが 2017/12/31 10:00 AM なので,その 1 分後に投稿されるように予約
きっと,締め切りは,再来年,再々来年...と繰り延べられるのだろうけど

【問題】
20桁の数字が提示されます。
一番左の桁を先頭として、右の桁へと順に見ていきます。
そして、隣り合った数が連続する数だった場合は、その双方を削除して先頭に戻ります。
最終的に、削除ができなくなった時点で数字を出力してください。


「95422357545868773174」→「95422357545868773174」→
「922357545868773174」→「922357545868773174」→
「9257545868773174」→「9257545868773174」→
「92575868773174」→「92575868773174」→
「925758673174」→「925758673174」→
「9257583174」(削除ができなくなったので、これが答え)

【入力】
標準入力から、複数行のデータが与えられます。1行のデータが、1つの20桁の数字になります。
 
【出力】
1行ずつ処理を行ない、その答えを1行ごと標準出力に出力します。
 
【入出力サンプル】
Input
95422357545868773174
24566191298259441958
34757881545564825469
86423251489513547814

Output
9257583174
26619259441958
75818269
8642511314

============================================

R による例解の一つ

f = function(S) {
    invisible(sapply(S, function(s) {
        x = as.integer(unlist(strsplit(s, "")))
        repeat {
            n = length(x)
            found = FALSE
            if (n == 1) break
            for (i in 1:(n - 1)) {
                if (abs(x[i] - x[i + 1]) == 1) {
                    found = TRUE
                    break
                }
            }
            if (!found) break
            x = x[-(i + 0:1)]
        }
        cat(paste(x, collapse = ""), "\n", sep = "")
    }))
}
f(readLines(file("stdin", "r")))

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村