#레오폴드 #750RBT

https://m.leopold.co.kr/article/%EC%9E%90%EB%A3%8C%EC%8B%A4/7/3819/

750RBT 블루투스 연결 방법 & LED indicator 자료실 - 레오폴드

Download

leopold.co.kr

if 함수

values.yaml

dev:
  env: dev
  log: info
qa:
  env: qa
  log: info
prod:
  env: prod
  log:

templates 내의 특정 yaml

{{- if eq .Values.dev.env "dev" }}
  log: debug
{{- else if .Values.dev.env }}
  log: {{ .Values.dev.log }}
{{- else }}
  log: error
{{- end }}

------------------------------ Result
log: debug

print / ternary / indent 함수

values.yaml

print:
  a: "1"
  b: "2"
  
ternary:
  case1: true
  case2: false
 
data:
  - a
  - b
  - c

templates 내의 특정 yaml

print: {{ print "Hard cording" }}                            # print: Hard Cording
printf: {{ printf "%s-%s" .Values.print.a .Values.print.b }} # printf: 1-2

case1: {{ .Values.ternary.case1 | ternary "1" "2" }} # case1: "1"
case2: {{ .Values.ternary.case2 | ternary "1" "2" }} # case2: "2"

data:
  indent:
  {{- .Values.data | toYaml | nindent 4 }}
  
----------------------------------------- Result
data:
  indent:
    - a
    - b
    - c

typels, coalesce 함수

values.yaml

typels1: "text"
typels2: true

data1:
data2:
data3: "text3"

templates 내의 yaml

{{- if typels "string" .Values.typels1 }}
typels1: {{ .Values.typels1 }} # typels1: "text"
{{- end }}

{{- if typels "bool" .Values.typels2 }}
typels2: {{ .Values.typels2 }} # typels2:  true
{{- end }}

coalesce1: {{ coalesce .Values.data1 .Values.data2 "text1" }} # coalesce1: "text1"
coalesce2: {{ coalesce .Values.data1 "text2" .Values.data3 }} # coalesce2: "text2"

dict, include 함수

_helpers.tpl

{{- define "mychart.include" -}}
key: {{ .key1 }}
dict: {{ get . "key1" }}
{{- end }}

values. yaml

include: "value2"

templates내 yaml

{{- $myDict := dict "key1" "value1" }}
  dict: {{ get $myDict "key1" }} # dict: "value1"
  
include1: {{- include "mychart.include" (dict "key1" "value1") | indent 4 }}
# include1:
#     key: value1
#     dict: value1

include2: {{- include "mychart.include" (dict "key1" .Values.include) | indent 4 }}
# include2
#     key: value2
#     dict: value2

With 함수

values.yaml

dev:
  env: dev
  log: info
qa:
  env: qa
  log: info
prod:
  env: prod
  log:

templates 내의 특정 yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: variables-with
data:
  dev:
  {{- $relname := .Release.Name -}}
  {{- with .Values.dev }}
    env: {{ .env }}
    release: {{ $relname }}
    log: {{ .log }}
  {{- end }}
  
-------------------------------- Result
dev:
  env: dev
  release: mychart
  log: info

 


tpl 함수

values.yaml

defaultLevel: info
dev:
  env: dev
  log: "{{ .Values.defaultLevel }}"
qa:
  env: qa
  log: "{{ .Values.defaultLevel }}"

templates 내 yaml

normal: "{{ .Values.dev.log }}"  # normal: "{{ .Values.defaultLevel }}"
tpl: "{{ tpl .Values.dev.log }}" # tpl: "info"

Range 함수

(Case1) values.yaml 

list:
  - a
  - b
  - c

(Case1) templates 내의 yaml 파일

apiVersion: v1
kind: configMap
metadata:
  name: variables-range
data:
  index:
  {{- range $index, $value := .Values.list }}
    {{ $index }}: {{ $value }}
  {{- end }}
  
---------------------------------------- Result
index:
  0: a
  1: b
  2: c

(Case2) values.yaml 

map:
  env: dev
  log: info

(Case2) templates 내의 yaml 파일

key-value:
{{- range $key, $value := .value.map }}
  {{ $key }}: {{ $value | quota }}
{{- end }}

----------------------------------- Result
key-value:
  env: "dev"
  log: "info"

 

 


Default 함수

values.yaml

default:
  nil:
  list: []
  object: {}
  number: 0
  string: ""
  boolean: false

 

templates 내의 특정 yaml

nil: {{ .Values.default.nil | default "default" }} 
# nil: default

list: {{ .Values.default.list | default (list "default1" "default2") | toYaml | nindent 6 }} 
# list
#   - default 1
#   - default 2

object: {{ .Values.default.object | default "default: 1" | toYaml | nindent 6 }} 
# object:
#   default: 1

number: {{ .Values.default.number | default 1 }}         # number:  1
string: {{ .Values.default.string | default "default" }} # string: default
boolean: {{ .Values.default.boolean | default true }}    # boolean: true

 


기타 함수

trim: {{ trim " hello " }}                     # hello
trimPrefix: {{ trimPrefix "-" "-hello" }}      # hello
trimSuffix: {{ trimSuffix "-" "hello-" }}      # hello
trunc: {{ trunc 5 "hello world" }}             # hello
replace: {{ "hello world" | replace " " "-" }} # hello-world
contains: {{ contains "cat" "catch" }}         # true
b64enc: {{ b64enc "hello" }}                   # aCVsbG8

'잡학IT' 카테고리의 다른 글

SSH 터널링 (포트 포워딩)  (5) 2023.04.10

https://school.programmers.co.kr/learn/courses/30/lessons/12978

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 
- 다익스트라 알고리즘 활용

import java.util.*;

class Solution {
	
	static class Node implements Comparable<Node>{
		int idx, cost;
		Node(int idx, int cost){
			this.idx = idx;
			this.cost = cost;
		}
		
		@Override
		public int compareTo(Node o) {
			if(this.cost < o.cost) return -1;
			if(this.cost > o.cost) return 1;
			return 0;
		}
	}
    public int solution(int N, int[][] road, int K) {
        int answer = 0;

        
        ArrayList<Node>[] al = new ArrayList[N+1]; 
        for(int i=0 ; i<N+1 ; i++)
        	al[i] = new ArrayList<>();
        
        for(int i = 0; i<road.length ; i++) { // <= !!
        	al[road[i][0]].add(new Node(road[i][1], road[i][2]));
        	al[road[i][1]].add(new Node(road[i][0], road[i][2]));
        }
        
        int[] dist = new int[N+1];
        for(int i=0; i<N+1 ; i++) {
        	dist[i] = Integer.MAX_VALUE;
        }
        dist[1] = 0;
        
        PriorityQueue<Node> q = new PriorityQueue<>();
        q.add(new Node(1, 0));
        
        while(!q.isEmpty()) {
        	Node now = q.remove();
        	int nowIdx = now.idx;
        	int nowCost = now.cost;
        	       	
        	for(int i=0 ; i<al[nowIdx].size() ; i++) {
        		Node next = al[nowIdx].get(i);
        		int nextIdx = next.idx;
        		int nextCost = next.cost;
        		
        		if(dist[nextIdx] >  dist[nowIdx] + nextCost) {
        			dist[nextIdx] = dist[nowIdx] + nextCost;
        			q.add(new Node(nextIdx, dist[nextIdx]));
        		}
        	}
        }
        
        for(int i=1 ; i<N+1 ; i++) {
        	if(dist[i]<= K)
        		answer++;
        }

        return answer;
    }
}

https://www.acmicpc.net/problem/1504

 

1504번: 특정한 최단 경로

첫째 줄에 정점의 개수 N과 간선의 개수 E가 주어진다. (2 ≤ N ≤ 800, 0 ≤ E ≤ 200,000) 둘째 줄부터 E개의 줄에 걸쳐서 세 개의 정수 a, b, c가 주어지는데, a번 정점에서 b번 정점까지 양방향 길이 존

www.acmicpc.net

 

입력

4 6
1 2 3
2 3 3
3 4 1
1 3 5
2 4 5
1 4 4
2 3

출력

7

 

JAVA 코드

import java.io.*;
import java.util.*;

public class Main {
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;
    static ArrayList<Node>[] al;
    static int N,E;
    static int INF = 1000*200000; 
    
    static class Node implements Comparable<Node>{
    	int idx, cost;
    	Node(int idx, int cost){
    		this.idx = idx;
    		this.cost = cost;
    	}
    	
    	@Override
    	public int compareTo(Node o) {
    		if(this.cost < o.cost) return -1;
    		if(this.cost > o.cost) return 1;
    		return 0;
    	}
    }

    public static void main(String[] args) throws IOException{
    	st = new StringTokenizer(br.readLine());
    	N = Integer.parseInt(st.nextToken());
    	E = Integer.parseInt(st.nextToken());
    	
    	al = new ArrayList[N+1];
    	for(int i=1 ; i<N+1 ; i++) {
    		al[i] = new ArrayList<Node>();
    	}

    	for(int i=0 ; i<E ; i++) {
    		st = new StringTokenizer(br.readLine());
    		int s = Integer.parseInt(st.nextToken());
    		int e = Integer.parseInt(st.nextToken());
    		int c = Integer.parseInt(st.nextToken());
    		al[s].add(new Node(e,c));
    		al[e].add(new Node(s,c));
    	}
    	
    	st = new StringTokenizer(br.readLine());
		int mid1 = Integer.parseInt(st.nextToken());
		int mid2 = Integer.parseInt(st.nextToken());
		
		//1 -> mid1 -> mid2 -> N
		//1 -> mid2 -> mid1 -> N
		
		int init1 = dij(1,mid1);
		int MID = dij(mid1,mid2);
		int final1 = dij(mid2,N);
		
		int init2 = dij(1,mid2);
		int final2 = dij(mid1,N);
		
		int case1 = init1+MID+final1;
		int case2 = init2+MID+final2;
		
		if(case1 >= INF && case2 > INF)
			System.out.println(-1);
		else
			System.out.println(Math.min(case1, case2));
    }
    
    public static int dij (int start, int end) {
    	int[] cost = new int[N+1];
    	for(int i = 0 ; i<N+1 ; i++)
    		cost[i] = INF;
    	cost[start] = 0;
    	
    	PriorityQueue<Node> q = new PriorityQueue<>();
    	q.add(new Node(start,0));
    	
    	while(!q.isEmpty()) {
    		Node now = q.remove();
    		for(int i=0 ; i<al[now.idx].size(); i++) {
    			Node next = al[now.idx].get(i);
    			
    			if(cost[next.idx] > cost[now.idx] + next.cost) {
    				cost[next.idx] = cost[now.idx] + next.cost;
    				q.add(new Node(next.idx, cost[next.idx]));
    			}
    		}
    	}
    	return cost[end];
    }
}

다익스트라 코드 요약

int visited[] = new int[V+1];
visited[start] = 1;

int dist[] = new int[V+1];
for(int k=0 ; k<V+1 ; k++) {
    dist[k] = Integer.MAX_VALUE;
}
dist[start] = 0;

PriorityQueue<Node> q = new PriorityQueue<Main.Node>();
q.add(new Node(start, 0));
        
while(!q.isEmpty()) {
	Node now = q.remove();
	for(int i=0 ; i<al[now.idx].size() ; i++ ) {
		Node next = al[now.idx].get(i);
			
		if(visited[next.idx] != 0)
			continue;
		if(dist[next.idx] > dist[now.idx] + next.cost)
			dist[next.idx] = dist[now.idx] + next.cost;
				
		q.add(new Node(next.idx, dist[next.idx]));
		visited[next.idx] = 1;
	}
}


static class Node implements Comparable<Node>{
	int idx, cost;
	Node(int idx, int cost){
		this.idx = idx;
		this.cost = cost;
	}
		
	@Override
	public int compareTo(Node o) {
		if(this.cost < o.cost) return -1;
		if(this.cost > o.cost) return 1;
		return 0;
	}
}

 

 

 

https://www.acmicpc.net/problem/1753

 

1753번: 최단경로

첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가

www.acmicpc.net

 

입력1

5 6
1
5 1 1
1 2 2
1 3 3
2 3 4
2 4 5
3 4 6

출력1

0
2
3
7
INF

 


코드

import java.io.*;
import java.util.*;

public class Main {
	
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
	static class  Node implements Comparable<Node>{
		int idx;
		int cost;
		Node(int idx, int cost){
			this.idx  = idx;
			this.cost = cost;
		}
		
		@Override
		public int compareTo(Node o) {
			if(this.cost < o.cost) return -1;
			if(this.cost > o.cost) return 1;
			return 0;
		}
		
	}
	
	public static void main(String[] args) throws Exception {

		st = new StringTokenizer(br.readLine());
		int V = Integer.parseInt(st.nextToken());
		int E = Integer.parseInt(st.nextToken());
		
		int start = Integer.parseInt(br.readLine());
		
		ArrayList<Node>[] al = new ArrayList[V+1];
		for(int i=0 ; i<V+1 ; i++) {
			al[i] = new ArrayList<Main.Node>();
		}
		
		for(int j=0 ; j<E ; j++) {
			st = new StringTokenizer(br.readLine());
		    int s = Integer.parseInt(st.nextToken()); // start
		    int e = Integer.parseInt(st.nextToken()); // end
		    int c = Integer.parseInt(st.nextToken()); // cost
		    
		    al[s].add(new Node(e,c));
		}
		
		//다익스트라 시작
		int dist[] = new int[V+1];
		for(int k = 0 ; k<V+1 ; k++) {
			dist[k] = Integer.MAX_VALUE; // 무한대로 초기화
		}
		dist[start] = 0; // 자기자신은 0 만큼 갈 수 있음
		
		int visited[] = new int[V+1];
		visited[start] = 1;
        
		PriorityQueue<Node> q = new PriorityQueue<>();
		q.add(new Node(start, 0));
		
		
		while(!q.isEmpty()) {
			Node now = q.remove();
			for(int i = 0; i <al[now.idx].size() ; i++) {
				Node next = al[now.idx].get(i);
				if(visited[next.idx] != 0)
					continue;

				// 거리 확인후, 갱신
				if(dist[next.idx] > dist[now.idx] + next.cost) {
					dist[next.idx] = dist[now.idx] + next.cost;
				}
					
				// 큐 등록하고 방문처리
				q.add(new Node(next.idx, dist[next.idx]));
				visited[next.idx] = 1;
			}
		}

		for(int i=1 ; i <V+1 ; i++) {
			if(dist[i] == Integer.MAX_VALUE)
				System.out.println("INF");
			else System.out.println(dist[i]);
		}
		
		
	}
}

 

DFS는 한 놈만 패는 방식으로, 하위 레벨 노드를 쭉 탐색한 다음에 다른 옆 분기로 넘어가면서 텀색하는 방식이다.

BFS보다 느린 편이고, 스택 또는 재귀 방식으로 구현할 수 있다.

DFS는 경로의 특징(비용, 거리)등을 저장해야 하는 경우에 사용하며, BFS는 특징을 저장할 수 없다.


그림으로 DFS 이해하기

다음의 그래프를 통해서 DFS 방식을 이해하도록 한다.

1. 오름 차순으로 탐색한다고 가정하면, 1번 노드를 먼저 방문처리하고 출력한다.

그리고 1번과 연결된 2,5,8 노드 중에서 2번 노드, 한놈만 파도록 한다.

2. 2번 노드를 방문처리하고 출력한다. 그리고 2번 노드와 연결된 노드인 6,8번 노드 중에서 작은 노드인 6번를 먼저 탐색한다.

3. 6번 노드를 방문처리 하고 출력한다. 6번 노드와 연결된 노드 중에서 방문한 노드는 없다.

따라서 다시 다시 2번 노드의 연결된 노드 중에서 방문하지 않은 노드인 8번 노드를 탐색한다. 8번 노드를 방문처리하고 출력한다. 8번 노드와 연결된 노드 중에서 방문처리되지 않은 노드는 없으니, 다시 1번 노드로 올라와서 방문하지 않는 노드를 찾는다.

4. 1번 노드와 연결된 노드 중에서 방문하지 않은 노드는 3번 노드 뿐이다. 3번 노드를 방문처리하고 출력한다. 그리고 3번 노드와 연결된 노드 중에서 방문하지 않는 노드를 탐색한다.

5. 3번 노드와 연결된 노드 중에서 방문하지 않는 노드인 5번을 탐색한다. 5번 노드를 방문처리하고 출력한다. 

그리고 5번와 연결된 노드 중에서 방문하지 않는 노드들을 탐색한다.

6. 5번와 연결된 노드 중에서 방문하지 않은 노드는 4,7번 노드이다. 이 중에서 작은 번호인 4번 노드를 방문처리하고 출력한다. 그리고 4번 노드와 연결된 노드 중에서 방문하지 않는 노드는 없으므로, 7번 노드를 탐색한다. 7번 노드를 방문처리하고 출력한다.

이제 더 이상 방문하지 않는 노드는 없다.

이 같은 방식은 재귀방식을 활용해서 DFS를 수행한 예시이다.


JAVA로 구현한 DFS (재귀방식)예시

public class dfs_recursion {

//	방문 처리에 사용할 visited 배열 선언
	static boolean[] visited = new boolean[9]; // 9개 노드 가정
	
//	인덱스가 노드 번호 의미
//	0번 인덱스는 아무것도 없음
//	1번 노드는 2,3,8 노드과 연결되어 있고, 2번 노드는 1,6,8 노드와 연결되어 있음을 의미함
	static int[][] graph = {{}, {2,3,8}, {1,6,8}, {1,5}, {5,7}, {3,4,7}, {2}, {4,5}, {1,2}};
	
	public static void main(String[] args) {
		dfs(1);
	}
	
	static void dfs(int start) {
		// dfs 함수 접근하자마자, 방문 처리
		visited[start]=true;
		
		// 방문 처리한 노드는 출력
		System.out.print(start + " -> ");
		
		// 방문한 노드와 연결된 노드 중에서 방문하지 않은 노드를 탐색하도록 함
		for (int i : graph[start]) { // 방금 방문 처리한 노드와 연결된 노드들만 대상으로 탐색함
			if(!visited[i]) // 연결된 노드가 방문한 적이 없다면, dfs함수를 수행한다.
				dfs(i);     // 재귀방식으로 방문 처리하고, 해당 노드의 하위로 더 파보자!
		}
	}
}

재귀방식으로 수행한 DFS의 결과는 다음과 같다.

1 -> 2 -> 6 -> 8 -> 3 -> 5 -> 4 -> 7 ->

 


JAVA로 구현한 DFS (Stack 방식)예시

import java.util.Stack;

public class dfs_stack {

	// 방문처리 목적의 배열
	static boolean visited[] = new boolean[9];
	static int graph[][] = {{}, {2,3,8}, {1,6,8}, {1,5}, {5,7}, {3,4,7}, {2}, {4,5}, {1,2}};
	
	// DFS에 사용할 스택 
	static Stack<Integer> stack= new Stack<>();
	
	public static void main(String[] args) {

		// 시작 노드 입력
		stack.push(1);
		
		// 시작 노드 방문처리
		visited[1] = true;
		
		// 스택에 값이 없을 때까지 반복
		while(!stack.isEmpty()) {
			// 스택에서 값 1개 꺼내기
			int node_out = stack.pop();
			
			//방문노드 출력
			System.out.print(node_out + "->");
			
			// 인접노드 탐색
			for(int i : graph[node_out]) {
				if(!visited[i]) { // 방문한 적이 없다면
					stack.push(i);
					visited[i] = true;
				}
			}
		}
	}
}

스택을 통해 DFS를 수행한 결과는 다음과 같습니다.

1->8->3->5->7->4->2->6->

+ Recent posts