AtCoderの過去問を解くシリーズです。まだまだBeginnerなので、ABC問題を解いています。今回の問題はこちら↓
atcoder.jp

辞書順という概念の定義を改まって書かれるとちょっと戸惑ってしまいますが、よく読んでみると普通のことを言ってますね。

解くにあたってC#での文字列の扱い方を覚えていなかったので、ここで整理したいと思います。

文字列の文字をソートするためにはchar型の配列に分解しないといけません。そのメソッドがこちら

str.ToCharArray();

,
charに分解したあと、Sort, Reverseをつかって並び替えます。
並び替えたあとの文字列を比較するときに、Compare()メソッドが使えそうです。
char型をToString()して、Compare()メソッドに入れたいですがそれだとうまくいきません。char型配列をToString()しても、"System.Char[]"が返ってくるだけです。
ここは以下のようにしました。stringのコンストラクタをつかってnewします。

char[] chars = s.ToCharArray(s);
// なんらかの処理
.
.
string str = new string( chars );

newして作ったstring型をCompare()に放り込んでやれば、その結果で辞書順を判定できます。

以下、回答です。

using System;
class Program
{
	static void Main(string[] args)
	{
		char[] s = Console.ReadLine().ToCharArray();
      		char[] t = Console.ReadLine().ToCharArray();
      
      		Array.Sort(s);
      		Array.Sort(t);
      		Array.Reverse(t);
      
      		Console.WriteLine( string.Compare( new string(s), new string(t) ) < 0 ? "Yes" : "No" );
	}
}

TPS, FPSのようにマウスでカメラ操作をする

マウスでカメラをグリグリ動かす方法についてちょっとつまずいたのでメモ。

今回は球面座標を使ったやり方を書いていきます。

まずネットで探してみると以下のページが参考になりました。

qiita.com

これをそのまま使うと、ゲーム開始時のカメラの初期位置が変な場所になる。初期位置はキャラクターの後ろに固定したい。そこで改良を加えていきます。
まず準備。

最初にキャラクターの向き(Y軸周りの角度)をeulerAnglesで取得する。それをmouse.x (上記リンクのコードを参照)に代入。

mouse.x = target.rotation.eulerAngles.y;

eulerAnglesの単位はdegreeだが、ここでのmouse.x, mouse.yは球面座標の変換式の引数に入るので、下記のようにradianに変換する。

pos.x = Mathf.Sin(mouse.y * Mathf.Deg2Rad) * Mathf.Cos(mouse.x * Mathf.Deg2Rad) ;
pos.y = Mathf.Cos(mouse.y * Mathf.Deg2Rad) ;
pos.z = Mathf.Sin(mouse.y * Mathf.Deg2Rad) * Mathf.Sin(mouse.x * Mathf.Deg2Rad) ;


ここでちょっと実行して様子を見てみる。下記が実行スクリプト

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

public class MouseCameraController : MonoBehaviour {
	public Transform target;
	public float spinSpeed = 100.0f;

	private Vector3 nowPos;
	private Vector3 pos = Vector3.zero;
	private Vector2 mouse = Vector2.zero;

	public float radius;

	// Use this for initialization
	void Start () {


		if(target == null)
		{
			target = GameObject.FindWithTag("Sphere").transform;
			Debug.Log("player didn't setting. Auto search 'Player' tag.");
		}

		mouse.x = target.rotation.eulerAngles.y;
		mouse.y = 0;

	}
		
	// Update is called once per frame
	void Update () {
		// Get MouseMove

		mouse += new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")) * Time.deltaTime * spinSpeed;

		// sphere coordinates
		pos.x = Mathf.Sin(mouse.y * Mathf.Deg2Rad) * Mathf.Cos(mouse.x * Mathf.Deg2Rad) ;
		pos.y = Mathf.Cos(mouse.y * Mathf.Deg2Rad) ;
		pos.z = Mathf.Sin(mouse.y * Mathf.Deg2Rad) * Mathf.Sin(mouse.x * Mathf.Deg2Rad) ;

		pos *= radius;

		transform.position = pos + target.position;
		transform.LookAt(target.position);
	}
}

ここではわかりやすくするために、下記のようなモデルを作ってみた。赤、緑、青の棒がそれぞれキャラクターのx, y, z軸でここでは軸が交わる場所がキャラクターの位置としている。そして赤玉がカメラの位置を表す。


f:id:ytak008844:20180912165055p:plain


この場合、カメラの初期位置はキャラクターの真上になっている。ここからmouse.x とmouse.yの位置を調整すれば良さそうだ。mouse.xは経度、mouse.yは緯度を表すので、まず緯度をあわせる。mouse.yに90を代入する。

mouse.y = 90;


f:id:ytak008844:20180912170224p:plain


赤道上にカメラが来るのがわかるが、なぜキャラクターの真横に来るんだろうか?EulerAngleがどう影響して真横に来ているのかが理解できてない。ただ、ここまでくればカメラを後ろに持ってくればいいだけ。

mouse.x = target.rotation.eulerAngles.y - 90;


f:id:ytak008844:20180912170737p:plain


よく原理は理解しきれてないけど、とりあえずできたみたいだが・・・。ここで、キャラクターの向きを変えてみる。


f:id:ytak008844:20180912172352p:plain


z軸からずれる~。いろいろ数字を入れて調べたところ、UnityのInspecterで表示される角度とEulerAngleの角度の回転の向きが逆になってるようだ。
ということは逆回転すればいいので、EulerAngleにマイナスをつける。

mouse.x = - target.rotation.eulerAngles.y - 90;


f:id:ytak008844:20180912173227p:plain


無事、キャラクターの回転に応じてカメラの初期位置を変えることができました。

Python言語によるプログラミングイントロダクション 読書メモ

普段はWEB開発の勉強をしているんですが、そればかりだと飽きるので気分転換に下記の本を読んでみます。それの個人的読書メモです。

第一章

宣言的知識、命令的知識

宣言的知識とは事実の陳述で構成されたもの。「xの平方根はy*y=xを満たす数yのことである」事実ではあるが、実際に平方根を求める方法については何も述べていない。命令的知識とは問題を解決するための具体的方法・手順である。例えば平方根の計算方法 開平法 - Wikipedia

文法・静的意味論・意味論の話

プログラミング言語がもつ構成要素
文法
Cat dog boyは正しくない。なぜなら英語は<名詞><名詞><名詞>を許容しないから。それと同様にpythonでは、3.2 + 3.2は文法的に正しいが、3.2 3.2は正しくない
静的意味論
”I runs fast”は<主語><動詞><副詞>の型なので文法的には正しい。しかし実際はrunsは三人称単数にしか使えないので静的意味論的に正しくないと本文にはある。しかし訳注に「(”I runs fast”は)もちろん文法的には正しくない」とあり、よくわからなくなった。本文が言いたかったことは、”I”や”He”, ”She”の区別は文法的にではなくて、その(話者との関係性という)意味においてされるべきで、それゆえ文法ではなく静的意味論の範疇になる、ということなのかもしれない。この直後にPythonは静的意味論において、チェックが脆弱であると書いてある。まだ個人的にはっきりとつかめていないが、例えば変数の型宣言、プログラム実行前にコンパイルが必要かどうかなどが静的意味論のチェックに影響してくるのかもしれない。先の問題も、どの代名詞が一人称か、三人称かと定義すれば文法の問題に帰着するが、それから私は変数の型宣言を連想する。pythonでは3.2 / 'abc'は<リテラル><演算子><リテラル>なので、文法的には正しい。しかし、静的意味論でのエラーにはなる。
意味論
文法的に正しい、かつ静的意味論におけるエラーの無いものを「意味」に関連付ける。

シェル 
OSのユーザーとカーネルサービスとを媒介するインターフェースを提供するソフトウェア。コマンドラインインタプリタもシェルの一種である。GUIもグラフィカルシェルと呼ばれる。

第二章はPythonの基礎知識なので飛ばす

第三章 

P.25 野暮なツッコミかもしれないが、コード3.1の終了する条件はxが整数でなくてもいいと思う。

減少関数
ループを書く際には減少関数を検討する。減少関数の特性とは
・関数はプログラム内の変数の(ある)集合を整数値に写像する。
(コード3.1ではy = abs(x) - ans**3としたとき、x, ans → yという写像になっている。)
・ループに入った際、その値が負ではない。
・値が0以下になる場合、ループが終了する
・ループを通るたびに値が減少する

総当り法
試行錯誤法の一種。総当り法とは、しらみつぶしに数を代入して条件に合う数を見つけ出す方法。総当り法は非効率かも知れないが、理解・実装するのが易しく多くの場合実用的な時間で終了する。昨今のコンピューターは1 nsのレベルで命令を実行している。光が300mm進む時間が約1 ns.

P27の指練習

1つの正の整数をユーザーに入力させた上、2つの整数root, pwrを表示するプログラムを作成せよ。ただし0<pwr<6, root**pwrは入力した整数値と等しい。もしこのペアがない場合は、その旨をメッセージに表示せよ。

総当り法がトピックになっているので、素直に総当りで問題を解いてみる。

x = int(input('Enter an positive integer: '))

pwr = 0
root = 0
noPair = True

while pwr < 6 :
    root = 0
    pwr += 1
    #print("pwr=", pwr)
    while root < x:
        #print("     root=",root)
        if x == root**pwr:
            print("root:", root, "pwr:", pwr)
            noPair = False
        root += 1

if noPair:
    print("no root and pwr pair for ",x)
Enter an positive integer: 16
root: 4 pwr: 2
root: 2 pwr: 4

Enter an positive integer: 25
root: 5 pwr: 2

Enter an positive integer: 59049
root: 243 pwr: 2
root: 9 pwr: 5

Enter an positive integer: 99
no root and pwr pair for  99