20200216のC#に関する記事は6件です。

AtCoder Beginner Contest 155 参戦記

AtCoder Beginner Contest 155 参戦記

ABC155A - Poor

2分で突破. 書くだけ. 前回に引き続き、set での重複判定.

ABC = list(map(int, input().split()))

if len(set(ABC)) == 2:
    print('Yes')
else:
    print('No')

ABC155B - Papers, Please

2分半で突破. 書くだけ.

N = int(input())
A = list(map(int, input().split()))

for a in A:
    if a % 2 == 1:
        continue
    if a % 3 == 0 or a % 5 == 0:
        continue
    print('DENIED')
    exit()
print('APPROVED')

ABC155C - Poll

8分半で突破. 書くだけ……といいつつそれなりに時間がかかったけど(汗). C# 使いが壊滅状態と聞いて、AC した人のコードを眺めると 全員 string 配列のソートに自前の comparer を使っていたので、Mono は string の比較がヤバイのかなと思った.

N = int(input())

d = {}
for _ in range(N):
    S = input()
    if S in d:
        d[S] += 1
    else:
        d[S] = 1

m = max(d.values())
for s in sorted(k for k in d if d[k] == m):
    print(s)

追記: C# で通している人、みんな自前の comparer を使ってソートしてたけど、標準の StringComparer.Ordinal (これは、実質的には C ランタイムの strcmp 関数の呼び出し)で通るなあ.

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var N = int.Parse(Console.ReadLine());

            var d = new Dictionary<string, int>();
            for (var i = 0; i < N; i++)
            {
                var S = Console.ReadLine();
                if (!d.ContainsKey(S)) d[S] = 0;
                d[S]++;
            }

            var m = d.Values.Max();
            var l = new List<string>();
            foreach (var kv in d)
            {
                if (kv.Value != m) continue;
                l.Add(kv.Key);
            }

            l.Sort(StringComparer.Ordinal);
            Console.WriteLine(string.Join("\n", l));
        }
    }
}

ABC155D - Pairs

敗退. Eの方が解いてる人が多いので、Eに行った. にぶたんかなあと思った.

ABC155E - Payment

敗退. 入力例1, 入力例2 は突破したものの、入力例3が243ではなく、249になってしまって、自分のロジックでうまく行かないパターンを考えていたけど思いつかなかった.

追記1: ぐぬぬ.

N = input()

N = '0' + N
result = 0
carry = 0
for i in range(len(N) - 1, 0, -1):
    c = int(N[i]) + carry
    n = int(N[i - 1])
    if c < 5 or (c == 5 and n < 5):
        result += c
        carry = 0
    else:
        result += 10 - c
        carry = 1
result += carry
print(result)

追記2: クレバーにうまく行かないパターンを考えるのではなく、すべての桁でその桁の紙幣で払うのと上の桁の紙幣で払うの両方を試行して小さい方を取ればよかった……. これなら知性はいらなかった…….

N = input()

a = 0  # その桁の紙幣で払う
b = 0  # 上の桁の紙幣で払う

t = int(N[-1])
a, b = a + t, a + (10 - t)

for i in range(len(N) - 2, -1, -1):
    t = int(N[i])
    a, b = min(a + t, b + (t + 1)), min(a + (10 - t), b + (10 - (t + 1)))
print(min(a, b + 1))
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

unityでとりあえずプレイヤーを動かすスクリプト

始めに

フライトゲームやFPSでプレイヤーを動かすスクリプトを書きました。
プレイヤーの動かし方が分からない人は必見です!
(これはmacで開発することが前提となっています)

下準備

  1. unityのnewを選択 スクリーンショット 2020-02-16 20.28.41.png
  2. Project nameを決めてCreate projectを押すスクリーンショット 2020-02-16 20.31.50.png
  3. Create -> 3D Object -> Planeをクリック、地面を作ります。 スクリーンショット 2020-02-16 20.45.42.png
  4. Create -> 3D Object -> Cube、今回はこれを動かします。 スクリーンショット 2020-02-16 20.46.41.png
  5. Cube -> Add Componentをクリック'Rigidbody'と検索Rigidbodyをクリックして追加する スクリーンショット 2020-02-16 20.54.18.png
  6. Main CameraをドラクアンドドロップでCubeに入れる
    スクリーンショット 2020-02-16 20.59.28.png
  7. ProjectのCreateからC#Scriptを選択してクリック
    スクリーンショット 2020-02-16 21.03.09.png
  8. デリートキーを押し、'Player_controller'と入力
    スクリーンショット 2020-02-16 21.44.32.png

  9. 作成したスクリプトをダブルクリックで開く
    スクリーンショット 2020-02-16 21.13.27.png
    これで下準備はOKです。

スクリプト

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player_controller : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKey(KeyCode.UpArrow))
        {
            transform.position += new Vector3(0,0,0.1f);
        }
        if (Input.GetKey(KeyCode.DownArrow))
        {
            transform.position += new Vector3(0,0,-0.1f);
        }
        if (Input.GetKey(KeyCode.RightArrow))
        {
            transform.position += new Vector3(0.1f,0,0);
        }
        if (Input.GetKey(KeyCode.LeftArrow))
        {
            transform.position += new Vector3(-0.1f,0,0);
        }
    }

}

開いたプログラムの内容を全て削除して上のスクリプトをコピペしてコマンドSで保存。
unityに戻りこのスクリプトをCubeにドラクアンドドロップをする。
これで上の三角のボタンを押せば終了です。
もし、Cubeにスクリプトを入れられなかったらスクリプトを右クリック -> Remameを押して'Player_controller'と入れてみてください!

最後に

最後まで見てくださってありがとうございます。
Qiitaは始めたばかりなので間違っていたら遠慮なく指摘してください!よろしくお願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【C#】時刻文字列を時刻の昇順にソートする

はじめに

以下は、佐賀県小城市(おぎし)のコミュニティバス広域循環バスの時刻表です。

この時刻表では、発車時刻が左から右に並んでいるもの(※赤い矢印)と、右から左に並んでいるもの(※青い矢印)が同じ時刻表に混在しています。
このような表があった時、多くの人は「目線が左から右に動く」と思うので、青い矢印のような表現だと時刻が逆転していて分かりづらく感じると思います。

少々話が飛躍してしまいますが、この時刻表を見て「時刻文字列の順に時刻表のデータをソートする」ことにトライしてみました。

image.png

コード

  • LINQを使って簡潔に書くことを目指しました。
  • DepatureTimeクラスは「時刻文字列」と「0時0分からの経過時間(分)」を入れるだけの"箱"のような扱いになっています。
DapartureTime.cs
    /// <summary>
    /// 発時刻での並び替え用クラス。
    /// </summary>
    public class DepatureTimeLogic
    {
        /// <summary>
        /// 引数の発時刻の昇順に並べ替えた結果を返す。
        /// </summary>
        /// <param name="times">発時刻リスト。各要素はHH:MM形式の時刻文字列で表される。</param>
        /// <returns></returns>
        public List<string> Sort(List<string> times)
        {
            // 発時刻クラス型に変換した後、経過時間(分)の昇順でソートして、
            // 最後に時刻文字列に戻してList化している。
            var sortedTimes = times.Select(time => new DepatureTime(time))
                .OrderBy(dTime => dTime.PassageTime)
                .Select(dTime => dTime.TimeString).ToList();

            return sortedTimes;
        }
    }

    /// <summary>
    /// 発時刻クラス。
    /// </summary>
    public class DepatureTime
    {
        /// <summary>
        /// 発時刻。HH:MM形式の時刻文字列で表される。
        /// </summary>
        public string TimeString { get; set; }

        /// <summary>
        /// 経過時間(分)。TimeStringを00:00からの経過時間(分)で表した値。
        /// </summary>
        public int PassageTime { get; set; }

        /// <summary>
        /// コンストラクタ。
        /// </summary>
        /// <param name="timeString">HH:MM形式の時刻文字列。</param>
        public DepatureTime(string timeString)
        {
            this.TimeString = timeString;
            var hhmm = timeString.Split(':');
            this.PassageTime = int.Parse(hhmm[0]) * 60 + int.Parse(hhmm[1]);
        }
    }

テストコード

  • 上記の「佐賀県小城市(おぎし)のコミュニティバスの広域循環バスの時刻表」から、一便目と二便目の時刻をテストに用いました。
    • 一便目:時刻文字列が時刻の昇順に並んでいます。
    • 二便目:時刻文字列が時刻の降順に並んでいます。
DepatureTimeLogicTest
    [TestClass]
    public class DepatureTimeLogicTest
    {
        /// <summary>
        /// 始発(第一便)のバス
        /// </summary>
        private readonly List<string> firstBus = new List<string>(){
            "9:15", "9:19", "9:20", "9:24", "9:32", "9:35", "9:44", "9:47", "9:51", "9:55", "10:07"
        };

        /// <summary>
        /// 第二便のバス
        /// </summary>
        private readonly List<string> secondBus = new List<string>() {
            "11:12", "11:08", "11:07", "11:03", "10:55", "10:52", "10:43", "10:40", "10:36", "10:32", "10:20"
        };

        [TestMethod]
        public void TestMethod1() {
            DepatureTimeLogic logic = new DepatureTimeLogic();
            var sortedFirstBus = logic.Sort(firstBus);
            System.Console.WriteLine("第一便");
            System.Console.WriteLine(string.Join(", ", sortedFirstBus));

            var sortedSecondBus = logic.Sort(secondBus);
            System.Console.WriteLine("第二便");
            System.Console.WriteLine(string.Join(", ", sortedSecondBus));
        }
    }
  • 元から時刻の昇順に並んでいた第一便はそのまま出力されています。
  • 一方で、時刻の降順に並んでいた第二便は、時刻の昇順にソートされていることが分かります。
テスト結果(標準出力)
第一便
9:15, 9:19, 9:20, 9:24, 9:32, 9:35, 9:44, 9:47, 9:51, 9:55, 10:07
第二便
10:20, 10:32, 10:36, 10:40, 10:43, 10:52, 10:55, 11:03, 11:07, 11:08, 11:12
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Visual Studio 2019 でBlazor WebAssemblyプロジェクトを作る

はじめに

先日、Blazorなるものを知り、調べてみることに。
ただ、バージョンの更新が活発なタイミングだったようで、Blazorで検索して出てくるサイトだと情報が少し古いものが多かったので、自分が成功した方法をまとめてみる。
VisualStudioを使ったのだ大分久しぶりなので、もっと良い方法などあれば教えてください。

Visual Studioの用意

Visual Studioをインストールしましょう。
私が試したのは以下のバージョンです。
Image 2020-02-15 11.03.03.png
※なんかバージョン更新されてますね。あとでアップデートします。
 リリースノート見る限り、16.4.5でもやり方は変わらないと思います。

Blazorで開発するには以下のワークロードが必要になります。
Image 2020-02-15 11.03.55_02.png
詳しい人は必要なものだけ個別のコンポーネントをインストールする方がよいかもしれませんが、私のようにこの辺に詳しくない人はこのワークロードをインストールすれば確実です。

以上で、VisualStudioのインストールは完了になります。

プロジェクトの作成

Blazorプロジェクトを作成します。
VisualStudioの使い方については他の人の開設に任せますので、この記事ではBlazorに特化した部分のみ書いていきます。

上記のVisualStudioのバージョンであれば、Blazorテンプレートがすでにあると思いますので、それを選びます。
Image 2020-02-16 12.39.42.png

テンプレートがあるならそれ選んで終わりじゃんと思いきや、そううまくも行きません。
おそらく、設定を進めていっても、下記のWebAssembly用のアプリが表示されてないんじゃないでしょうか。
私は最初、表示されていませんでした。
Image 2020-02-16 12.48.07.png
Blazor Serverを実装したい場合は「Blazor サーバー アプリ」を選択すれば問題ないです。
「Blazor WebAssembly App」が表示されている人もこれ以降読む必要はないかと思います。

表示されなかった人は、プロジェクトの作成をいったんキャンセルして、以下の手順を踏む必要があります。

Blazorのプレビュー版テンプレートをインストールする

Blazor WebAssemblyは私が試した時点でまだプレビュー版だそうで、WebAssembly用アプリを作成するには、対応したプレビュー版のテンプレートをインストールする必要があります。

ここで結構詰まったんですが、色々な記事を読むと、「プレビュー版テンプレートをインストールするにはコマンドを叩くだけ!」と教えてくれるのですが、バージョン指定されたそのコマンドだと古かったりして、エラーが出る場合があります。
ですので、最新のバージョンのテンプレートを手に入れましょう。
最新のテンプレートはこちらのサイトから取得可能です。
「Version History」にある最新バージョンのリンクをクリックします。
Image 2020-02-16 12.57.16.png

遷移した先に記載されているコマンドを叩いてプレビュー版のテンプレートをインストールしましょう。
Image 2020-02-16 12.59.23.png

インストールすると、テンプレートが更新されるので、上記の「Blazor WebAssembly App」が表示されるようになるかと思います。プロジェクトを作成しましょう。

作成が完了すると、ソリューションの構成はこのようになっているはずです。
Image 2020-02-16 13.02.50.png

特に何もせず、実行する。
Image 2020-02-16 13.08.39.png

すると、ブラウザが起動してサンプルページが表示されるはずです。
Image 2020-02-16 13.08.07.png

おわりに

BlazorはC#でWebアプリの開発思想でサーバサイドやクライアントサイドはもちろん、PCのネイティブアプリやスマホアプリなども全部できるようにしようぜ!っていうものみたいですね
JavaScriptにトランスパイルするわけでもなく、全部C#で完結するっているのが楽しそうです。
まだASP.Netとかも全然知らないので、覚えることいっぱいですが、色々期待したいと思います。

Let's Enjoy Blazor!

参考

https://docs.microsoft.com/ja-jp/aspnet/core/blazor/?view=aspnetcore-3.1
https://www.publickey1.jp/blog/20/blazor_webassembly5blazorpwa.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows10でゼロから始めるC#

インストール

Windows10で始める人は、インストール 不要。
C#は、Microsft開発の言語であり、
Windows10であればC#に必要なモジュールはプリインストールされています。

準備

C#は、cs拡張子のプログラムファイルにコードを記載します。
csファイルを、コンパイルして、exe拡張子の実行ファイルを生成します。
コンパイルは、windows環境であれば csc というコマンドを実行します。

*.cs
↓ cscコマンド
*.exe

まずは、cscコマンド にパスが通っているか以下のコマンドで確認しましょう。

where csc 

パスが設定されていなければ、以下の実行したバージョンのフォルダにcsc.exeファイルあることを確認しましょう。

C:\Windows\Microsoft.NET\Framework64\{version}\
C:\Windows\Microsoft.NET\Framework\{version}\

csc.exeファイルを見つけたらシステム環境変数のPathに追加してあげます。追加するパスは、任意のひとつでよいです。

プログラミング

まずは、最初の第1歩、HelloWorld
プログラム作成から、実行までを簡単に記載します。

プログラム作成

Hello Worldサンプル

HelloWorld.cs
using System;

class HelloWorld {
    static void Main() {
        Console.WriteLine("Hello world!");
    }
}

コンパイル実行

cscコマンドでコンパイルを実行。

csc HelloWorld.cs 

成功すれば、exeファイルが同じフォルダに生成されます。

プログラム実行

生成されたexeファイルを実行。

>HelloWorld.exe
Hello world!

できました。

インストール2

しかし、先に通したcsc.exe、プリインストールのモジュールは古いバージョンであり、
最新バージョンで問題ないコードの記法が、コンパイルエラーになったりします。
最新版のC#のモジュールを使用するためには、やっぱり追加モジュールのインストールが必要
visual studio 2019をインストールしましょう。
https://visualstudio.microsoft.com/ja/downloads/?utm_medium=microsoft&utm_source=docs.microsoft.com&utm_campaign=button+cta&utm_content=download+vs2019&rr=https%3A%2F%2Fdocs.microsoft.com%2Fja-jp%2Fvisualstudio%2Finstall%2Finstall-visual-studio%3Fview%3Dvs-2019

準備2

インストールができたら、cscでcsファイルのコンパイルができるように、システム環境変数のパスを更新しましょう。

visual studio 2019 community をダウンロードした環境では、以下のようなパスにcsc.exeがあります。

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

C#でSTLのバイナリを読み込む

某言語のライブラリじゃないやつ。

ソースコード

static Vector3f[][] LoadStlFile(Stream stream)
{
    byte[] buff = new byte[84];

    stream.Read(buff, 0, 84);
    string anyText = Encoding.ASCII.GetString(buff, 0, 80);
    int numOfPolygon = BitConverter.ToInt32(buff, 80);

    Vector3f[][] polygons = new Vector3f[numOfPolygon][];

    for (int i = 0; i < numOfPolygon; i++)
    {
        stream.Read(buff, 0, 50);

        polygons[i] = new Vector3f[3]
        {
            new Vector3f(
                BitConverter.ToSingle(buff, 4 * 3),
                BitConverter.ToSingle(buff, 4 * 4),
                BitConverter.ToSingle(buff, 4 * 5)),
            new Vector3f(
                BitConverter.ToSingle(buff, 4 * 6),
                BitConverter.ToSingle(buff, 4 * 7),
                BitConverter.ToSingle(buff, 4 * 8)),
            new Vector3f(
                BitConverter.ToSingle(buff, 4 * 9),
                BitConverter.ToSingle(buff, 4 * 10),
                BitConverter.ToSingle(buff, 4 * 11)),
        };
    }

    return (polygons);
}

static Vector3f[][] LoadStlFile(string path)
{
    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        return (LoadStlFile(fs));
    }
}

任意の文字列法線ベクトルは読み捨ててます。
戻り値は頂点のジャグ配列ですが、環境に合わせて煮るなり焼くなり好きにしろ。
エラーチェックとか一切やってないので気をつけてね。

参考

STLファイルフォーマット

感想

なにゆえ1ポリ50バイト? 48ポリのほうがスッキリする気がする。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む