さくらvpsの一番安いやつに入れていきます。
続きを読むGoでスライスの任意のインデックスに挿入
ちなみに「任意のインデックスを削除」はこれでやってます。
実装
package main import "fmt" func main(){ n := []int{1, 2, 3,} incert_target := 9999 intint := make([][]int, 0) for i:=0; i<len(n)+1; i++{ intint = append(intint, incert(i, incert_target, n)) } fmt.Println(intint) } func incert(index int, x int, origin []int)(ret []int){ ret = append([]int{}, origin...) ret = append(ret[:index], append([]int{x}, ret[index:]...)...) return }
Goのスライスの応用的な使い方はこれを一通りみればいいです
ちなみにdelete
はmapの組み込み関数なので注意。
Goで順列を辞書順で
スライスのポインタで渡すところとスライスのコピーとスライスの任意のインデックスの要素を消すっていう実装が頭まわりませんでした…
実装
package main import "fmt" func main(){ test := []int{1, 2, 3, 4} perms := permuration(test, 3) fmt.Println("1から4の中から3つ取る順列") fmt.Println(perms) // int以外の場合でもどうせインデックスを返すので数列を渡せばいい aquars := []string{"千歌", "梨子", "曜", "ダイヤ", "果南", "鞠莉", "善子", "花丸", "ルビィ"} indices := make([]int, len(aquars)) for i := 0; i<len(aquars); i++{ indices[i] = i } coupling := permuration(indices, 3) for _, c := range coupling{ for i, v := range c{ fmt.Print(aquars[v]) if i<2{ fmt.Print(" x ") } } fmt.Println() } } func permuration(target []int, limit int)([][]int){ if limit<1 || len(target)<limit{ return nil } ret := make([][]int, 0) gen_perm(make([]int, 0), target, &ret, limit) return ret } func gen_perm(perm []int, rest []int, lis *[][]int, n int){ if n==0{ *lis = append(*lis, perm) }else{ // 探索 for i, r := range rest{ next_rest := make([]int, 0) next_rest = append(next_rest, rest...) next_perm := make([]int, 0) next_perm = append(next_perm, perm...) next_rest = deleteIndex(next_rest, i) next_perm = append(next_perm, r) gen_perm(next_perm, next_rest, lis, n-1) } } } func deleteIndex(in []int, index int)[]int{ out := make([]int, 0) out = append(out, in...) if index<0 || len(in)<index{ fmt.Println("delete index mis") return nil } out = append(out[:index], out[index+1:]...) return out }
gen_perm
は最初無名関数でやってたんですが無名関数の再帰ってできないんですね(当然)
参考
Go のスライスでハマッたところ - Block Rockin’ Codes
Goで「文字列のa番目からb番目までを反転」をやる
そういう問題があったので。
Transformation | Aizu Online Judge
func Reverse(s string, a int, b int) string { r := []rune(s) for i, j := a, b; i < (a+b)/2+1; i, j = i+1, j-1 { r[i], r[j] = r[j], r[i] } return string(r) }
(a+b)/2+1
でちゃんと+1しないといけない。
Goで二次元スライスの宣言をグローバルでやってローカルで初期化
日本語あってるかわかりませんが。
main
の外で二次元スライスを作っておき、中でmake
でcap/lenを設定して初期化するといいです。
package main import "fmt" var multislice [][]string func main(){ multislice = make([][]string, 4) s := []string{"ドバイ", "インド", "ドイツ", "味噌汁"} for i:=0; i<len(multislice); i++{ multislice[i] = make([]string, 3) for j:=0; j<len(multislice[0]); j++{ multislice[i][j] = string([]rune(s[i])[j]) } } fmt.Println(multislice) }
出力
[[ド バ イ] [イ ン ド] [ド イ ツ] [味 噌 汁]]
競プロでたとえば入力であとからHeight, Widthを与えられる問題なんかのときにどうすりゃいいかわからんかったので。
2次元配列のリストの中に特定の2次元配列が含まれているかどうかをいい感じに高速に判定するにはどうすればいいですか
むかし書いたやつが発掘されたので供養というか。すっかりC#忘れてるので読解に苦労しました。むかしの自分すげぇな
using System; using System.Linq; using System.Collections.Generic; public class Program{ public static void Main(){ //はじめに var test1 = new int[,]{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; var test2 = test1.Clone() as int[,]; //test1と同値をもつ2次元配列 var set1 = new HashSet<int[,]>(); set1.Add(test1); Console.WriteLine(set1.Contains(test2)); //test1とtest2はそもそも別オブジェクトなので当然 var unziped1 = UnZip(test1); //一次元配列に展開 var unziped2 = UnZip(test2); //同じく var set2 = new HashSet<int[]>(); set2.Add(unziped1); Console.WriteLine(set2.Contains(unziped2)); //当然 /////////////////////////////////////////////////// //解法1 //値型に何らかの形で直してやるパターン //文字列 var str1 = ToStr(test1); var str2 = ToStr(test2); var set3 = new HashSet<string>(); set3.Add(str1); Console.WriteLine(set3.Contains(str2)); //文字列に直せばいいけどstringへの変換がクソ遅い //longとかそのへん var longed1 = ToLong(test1); var longed2 = ToLong(test2); var set4 = new HashSet<long>(); set4.Add(longed1); Console.WriteLine(set4.Contains(longed2)); //文字列よりはマシだけど一桁ずつに情報をもたせているので9種類しか持てないし限定的すぎる(1と11が含まれていたらもう復元できない・0が先頭になることはない) //あるいは数値とインデックスでHashCode的なのをうまく一意に生成できれば可能っぽいけど ////////////////////////////////////////////////// //解法2 //愚直に舐めていくパターン set1.Clear(); bool flag; var _any1 = new int[,]{{2, 3, 4}, {5, 6, 7}, {8, 9, 1}}; var _any2 = new int[,]{{3, 4, 5}, {6, 7, 8}, {9, 1, 2}}; var _any3 = new int[,]{{9, 8, 7}, {6, 5, 4}, {3, 2, 1}}; //...このあと_any1000000000くらいまで続くと想定 set1.Add(_any1); set1.Add(_any2); set1.Add(_any3); //...このあと_any1000000000くらいまで続く想定 set1.Add(test1); //set1にtest2と同じ要素をもつものが含まれているかどうか調べたい var b = false; foreach(var s in set1){ if(Check(s, test2)){ b = true; break; } } Console.WriteLine(b ? "ありました" : "ねぇよ帰れクソが"); //この方法だと見つけたいターゲットがリストの最後のほうにあったときに探索に時間がかかる。Linqもゴテゴテなのでたぶん遅い } public static int[] UnZip(int[,] moto){ return moto.Cast<int>().ToArray(); var h = moto.GetLength(0); var w = moto.GetLength(1); var len = h*w; var ret = new int[len]; for(int i=0; i<h; i++){ for(int j=0; j<w; j++){ ret[i*w+j] = moto[i,j]; } } return ret; } public static string ToStr(int[,] moto){ var h = moto.GetLength(0); var w = moto.GetLength(1); var sb = new System.Text.StringBuilder(); for(int i=0; i<h; i++){ for(int j=0; j<w; j++){ sb.Append(moto[i,j].ToString()); } } return sb.ToString(); } public static long ToLong(int[,] moto){ var h = moto.GetLength(0); var w = moto.GetLength(1); long ret = default(long); for(int i=0; i<h; i++){ for(int j=0; j<w; j++){ var count = i*h+j; ret+=moto[i,j]*(long)Math.Pow(10, h*w-count-1); } } return ret; } public static bool Check(int[,] me, int[,] target){ //meとtargetが同じ次元数かつ同じ要素数であるか var unko = me.Rank==target.Rank&&Enumerable.Range(0, me.Rank).All(dim=>me.GetLength(dim)==target.GetLength(dim)); if(!unko) return false; return me.Cast<int>().SequenceEqual(target.Cast<int>()); } }
Debian環境をつくる さくらVPS編
結局さくらで構築することになった。。以前やったこれとまったく同じことをやります
導入
VPS(仮想専用サーバー)|さくらインターネット - 無料お試し実施中 一番安いプラン。クレジットカードがあれば二週間無料で使えるらしい。
OSインストール
さくらVPSの設定ページからサーバ情報 -> 各種設定 -> OSインストール -> カスタムOSでDebian9を選択。自前でイメージを用意する必要すらないので楽。用意ができたらシリアルコンソールで設定。VNCコンソールは頻繁にフリーズするし画面移動もできないし使いにくい。
Config
だいたい今までと同じ。いちおう流れをおさらいすると
apt-get update
apt-get install
でsudo
、ssh
、vim
なんかうまくいかなくなってた?adduser
でユーザー追加、そのユーザーにsudo
権限を与えておく。adduser <username> sudo
とかでいけるuseradd <username>
したあとにgpasswd -a <username> wheel
してsudo権限を与えて、passwd <username>
でパスワードを作ってみた。- Mac側でssh公開鍵/秘密鍵のペア作成。
ssh-keygen -t rsa -b 4096 -f .ssh/{file_name_of_key}
とかでいい いちいちscp
とかssh-copy-id
とか好きな方法で公開鍵を送る。ssh-copy-idを使う場合はssh-copy-id -i .ssh/{file_name_of_key} -p {port number} {target_name}@{target_host}
とかにする。Permission Denied
とか言われる場合はホストの/etc/ssh/sshd_config
の設定を疑う。最初に接続する場合はもちろんPasswordAuthentication
をyes
にしないと鍵すら送れない。送ったらちゃんとno
にしておく。あとポート番号もちゃんとしといたほうがいい。いじったあとはservice sshd restart
。たとえばOSを入れ直して再度設定しているときなどはローカル側の.ssh/knwon_hosts
に既に設定されている場合があるので消しておく。PasswordAuthentication
をいじらねばならんのめんどくさいのでむしろvim ~.ssh/authorized_keys
して公開鍵をコピペできる環境ならそっちのほうが楽そう- ssh接続できたら
/etc/ssh/sshd_config
のセキュリティたらへんをアレしておく。ポート番号が22でないか、rootには入れないか、パスワード認証で入れないか、など - クライアントの
~/.ssh/config
をいじってsshやるときいろいろ省略できるようにしておく
くらいです。このあとmysqlとnginxをいれてVirtualHostやる予定。