おサラミログ

パズルの話とか、メモとか

(Java)スタックとキュー

競技プログラミング幅優先探索をやりたく、キューを実装しようとした。
C++だとStackもQueueもpushとpopで操作できるっぽいから、
Javaでも同じようにpushとpopを使ったらキューがスタックとして動作して死んだ。
Javaではキューの操作はaddとremove

System.out.println("\nQueue");
Queue<Integer> que = new ArrayDeque<>();
for(int i=0; i<10; i++){
	que.add(i);
}
while(!que.isEmpty()){
	System.out.print(que.remove()+" ");
}
//Queue
//0 1 2 3 4 5 6 7 8 9 
		
System.out.println("\nDeque as Stack");		
Deque<Integer> deque = new ArrayDeque<>();
for(int i=0; i<10; i++){
	deque.push(i);
}
while(!deque.isEmpty()){
	System.out.print(deque.pop()+" ");
}
//Deque as Stack
//9 8 7 6 5 4 3 2 1 0 
		
System.out.println("\nDeque as queue");

for(int i=0; i<10; i++){
	deque.add(i);
}
while(!deque.isEmpty()){
	System.out.print(deque.remove()+" ");
}
//Deque as queue
//0 1 2 3 4 5 6 7 8 9 


Stackクラスも用意されているけど、両端キューであるDeque(デック)を使うことを推奨されている。

(Java)Arrays#fillで二次元配列を初期化したら大失敗した話

しょーもないミスをしたけれど、戒めを込めて書く。

JavaではArrays#fillを用いることで、
配列のすべての要素に同じ値を代入することができる。

int[] zero = new int[3];
Arrays.fill(zero, 0);
for(int val : zero){
	System.out.print(val+" ");
}
//出力
//0 0 0 

競技プログラミングの問題を解いているとき、
二次元配列のすべての要素を同じ値にしたい場面に出会った。

Arrays#fillを2回使えばいいじゃないかと考えた

int[][] hogehoge = new int[3][3];
int[] zero = new int[3];
Arrays.fill(zero, 0);
Arrays.fill(hogehoge, zero);
for(int[] line : hogehoge){
	for(int val : line){
		System.out.print(val+" ");
	}
	System.out.println();
}
//出力
//0 0 0 
//0 0 0 
//0 0 0 

事件はここから

hogehogeの対角要素を1にしたかった

for(int i=0; i<3; i++){
	hogehoge[i][i] = 1;
}
for(int[] line : hogehoge){
	for(int val : line){
		System.out.print(val+" ");
	}
	System.out.println();
}
//出力
//1 1 1 
//1 1 1 
//1 1 1 

あーもうめちゃくちゃだよ

少し考えれば理由は明らか。

Arrays.fill(hogehoge, zero);

ここで二次元配列hogehogeの各要素*1は配列zeroが代入されている。
配列zeroは参照型であるため、hogehoge[0][X], hogehoge[1][X], hogehoge[2][X]は同じデータを参照していることになる。
そのため、対角要素だけ1を代入しようとしてすべての要素が1になってしまった。

競技プログラミングの問題が解けずにうんうん唸っていたけれど、
原因がこういう超・超基本的なところだとまだまだ勉強が足りないなと思う。
頑張ろう。

*1:ここでいう各要素とは、hogehoge[0], hogehoge[1], hogehoge[2]のこと

Haskellで.ghciファイルを編集しても反映されなかった件

Haskellインストール

$ stack ghc -- --version
The Glorious Glasgow Haskell Compilation System, version 8.6.3

下記を参考にHaskellお触り中
employment.en-japan.com

日本語化対応の手順で戸惑ったのでメモ

環境:CentOS7
~/.ghciファイルが見当たらなかったので、新規作成し、記事の通り.ghciファイルに記載

import qualified Text.Show.Unicode
:set -interactive-print=Text.Show.Unicode.uprint

しかし、日本語を入力しても日本語が出力されない。

GHCiを起動時に下記のようなメッセージがでている。

[vagrant@localhost ~]$ stack ghci
(中略)
Configuring GHCi with the following packages:
GHCi, version 8.6.3: http://www.haskell.org/ghc/  :? for help
*** WARNING: .ghci is writable by someone else, IGNORING!
Suggested fix: execute 'chmod go-w .ghci'
*** WARNING: /home/vagrant/.ghci is writable by someone else, IGNORING!
Suggested fix: execute 'chmod go-w /home/vagrant/.ghci'
Loaded GHCi configuration from /tmp/haskell-stack-ghci/2a3bbd58/ghci-script

なのでとりあえず「chmod go-w /home/vagrant/.ghci」を実行したところ、日本語出力ができた。
※chmod go-wは、自分以外が書き込めないようにするコマンド。

書き込み権限の問題っぽい

vagrantの共有フォルダにファイルをぶちこんでも共有できなかった件

vagrantでCentOS7環境を作った。

共有フォルダ(Vagrantfileがあるローカルのディレクトリ)にファイルを配置したが、

vagrant sshでログインし、/vagrantの中身を見ても反映されない。

 

結論、仮想マシン再起動で解決。

vagrant reload

競技プログラミング入力メモ(Java)

友達の影響で競技プログラミングにちょっとばかりハマっている
Javaで挑むに当たり入力でよく戸惑うのでメモ(随時更新)

入力

原則nextを用いて、パースする。
nextIntとかよりnextからのパースのほうが早い。

Int

Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc.next());

char[](文字列を1文字ずつ分割)

Scanner sc = new Scanner(System.in);
char[] c = sc.next().toCharArray();

Scannerは実行速度が遅いらしいが、
今のレベルでscannerがボトルネックになるような問題には出くわしていない。
自作で入力用ライブラリを作成するのが一番早いが、
そこまでガチ勢じゃないのでそういう問題に出くわしたら、またちゃんと勉強する。

参考:
入出力 - てきとーな日記
↑の記事を少し噛み砕いた記事
Javaで競技プログラミングをするときの罠とテク - Qiita

なお、Scannerをよくcloseし忘れるので、入力の最後にちゃんとcloseする

sc.close(); 

ぼやき

競技プログラミングの問題がうまく解けないとき、
アルゴリズムの問題だったら納得できるんだけど、
こういう初歩的な技術要素による問題だともったいない気がする。
そういうのを少なくしていきたい。

localhostでつながらない?

Dockerを体験しようと思い導入。

wdpressの記事をもとにDocker上のコンテナでApacheを起動、

ブラウザからアクセスしようとするとつながらない

 

試しに172.0.0.1でつなげると違うエラーが出る

 

 

まったくわからん。

 

 

 

Vagrantfileを編集しIPアドレスを明示的に設定してみる。

config.vm.network "private_network", ip: "192.168.33.10" 

 vagrant再起動

vagrant reload 

 

あらためてdockerコンテナのプロセスを起動し、

指定した192.168.33.10でアクセス。

 

 

 

できた。

 

何が原因でこうなっているのかさっぱりわからん。

こういうのが解析できるような技術者になるべきなんだろうけど。

 

 

Vagrant上でroot権限を持ちたい等

仮想化マシンの自動作成・管理ツールであるVagrantを体験中

詰まったところをメモしていく

 

Vagrant上でroot権限を持ちたい

Vagrant上のsu実行に関するメモ

上記サイトを参考

# sudo su 

 

Vagrantとローカルでファイル共有したい

/vagrant/がローカルのvagrantフォルダ(vagrant up とかするディレクトリ)とリンクしている