Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
rahon6000 committed Sep 19, 2023
2 parents 9911fe4 + 9b6c7b3 commit dbad1bb
Show file tree
Hide file tree
Showing 10 changed files with 402 additions and 93 deletions.
61 changes: 47 additions & 14 deletions PF/ColorSense/color-sense.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
</script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="Permissions-Policy" content="interest-cohort=()">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
</head>
Expand All @@ -27,28 +28,60 @@ <h1>Test your<br><span class="rainbow">color</span> sense</h1>
<hr>
<div id="midDiv" class="carousel">
<ol>
<li class="myCarousel" style="display: block;"> <!-- default-->
<p>이 색깔을 기억하세요!</p>
<li class="myCarousel" id="defaultShown"> <!-- default-->
<p>이 색깔을 잘 기억해보세요!<br>
Remember this color!</p>
<div id = "randColorBox"></div>
</li>
<li class="myCarousel">
<p>기억해둔 색을 만들어 보세요!</p>
<p>기억해둔 색을 만들어 보세요!<br>
Recreate previous color!</p>
<div id = "yourColorBox"></div>
<hr>
<div class="sliderContainer">
<input type = "range" class="colorSliders" min ="0" max = "255" onchange="adjustingSlider(0)">
<br>
<span class="fineTune"><a onclick="fineTune(0,-1)"></a>R<a onclick="fineTune(0,1)"></a></span>
<label for="redSlider">
<span class="fineTune">
<a onclick="fineTune(0,-1)"
onmousedown="fineTuneStart(0,-1)"
onmouseout="fineTuneEnd()"
onmouseup="fineTuneEnd()"></a>
R
<a onclick="fineTune(0,1)"
onmousedown="fineTuneStart(0,1)"
onmouseout="fineTuneEnd()"
onmouseup="fineTuneEnd()"></a></span>
</label>
<input id="redSlider" type = "range" class="colorSliders" min ="0" max = "255" onchange="adjustingSlider(0)">
</div>
<div class="sliderContainer">
<input type = "range" class="colorSliders" min ="0" max = "255" onchange="adjustingSlider(1)">
<br>
<span class="fineTune"><a onclick="fineTune(1,-1)"></a>G<a onclick="fineTune(1,1)"></a></span>
<label for="greenSlider">
<span class="fineTune">
<a onclick="fineTune(1,-1)"
onmousedown="fineTuneStart(1,-1)"
onmouseout="fineTuneEnd()"
onmouseup="fineTuneEnd()"></a>
G
<a onclick="fineTune(1,1)"
onmousedown="fineTuneStart(1,1)"
onmouseout="fineTuneEnd()"
onmouseup="fineTuneEnd()"></a></span>
</label>
<input id="greenSlider" type = "range" class="colorSliders" min ="0" max = "255" onchange="adjustingSlider(1)">
</div>
<div class="sliderContainer">
<input type = "range" class="colorSliders" min ="0" max = "255" onchange="adjustingSlider(2)">
<br>
<span class="fineTune"><a onclick="fineTune(2,-1)"></a>B<a onclick="fineTune(2,1)"></a></span>
<label for="blueSlider">
<span class="fineTune">
<a onclick="fineTune(2,-1)"
onmousedown="fineTuneStart(2,-1)"
onmouseout="fineTuneEnd()"
onmouseup="fineTuneEnd()"></a>
B
<a onclick="fineTune(2,1)"
onmousedown="fineTuneStart(2,1)"
onmouseout="fineTuneEnd()"
onmouseup="fineTuneEnd()"></a></span>
</label>
<input id="blueSlider" type = "range" class="colorSliders" min ="0" max = "255" onchange="adjustingSlider(2)">
</div>
<br>

Expand All @@ -60,14 +93,14 @@ <h1>Test your<br><span class="rainbow">color</span> sense</h1>
<div id = "resultYours">your color</div>
<hr>
<p>Your score is <span id="result">xx</span>!</p>
<p>BTW, average score is <span th:text="${data}">77</span>.</p>
<p><span id="averageShow">dummy text.</span></p>
</li>

</ol>
</div>
<hr>
<form>
<button type ="button" onclick="nextCarousel(1)">Next</button>
<button label="nextButton" type ="button" onclick="nextCarousel(1)">Next</button>
<!-- type = "button" prevents refreshing page. -->
</form>
<hr>
Expand Down
8 changes: 8 additions & 0 deletions PF/ColorSense/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ h1, h2, h3 {
animation-name: rainbow;
animation-duration: 30s;
animation-iteration-count: infinite;
text-shadow: 2px 2px 3px black;
}

#colorBox {
Expand Down Expand Up @@ -119,6 +120,10 @@ ol {
background-color: gray;
}

#defaultShown {
display: block;
}

.sliderContainer {
display: inline-block;
width: 30%;
Expand All @@ -130,6 +135,9 @@ ol {

.fineTune {
cursor: pointer;
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none; /* Standard syntax */
}

button {
Expand Down
24 changes: 19 additions & 5 deletions PF/ColorSense/js/generateColor.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ let sliders = document.getElementsByClassName("colorSliders");
let myColor = [127,127,127];
let myColorBox = document.getElementById("yourColorBox");
let initTime = new Date().getTime();
let xHttp;
rndColor();
showColor();
getAverage();
Expand All @@ -24,10 +25,10 @@ function deltaToScore(delta) {
}

function getAverage() {
let xHttp = new XMLHttpRequest();
xHttp = new XMLHttpRequest();
xHttp.onreadystatechange = function() {
if (xHttp.readyState == xHttp.DONE) {
if (xHttp.readyState == 200) { // 200:"OK", 403:"Forbidden", 404:"Not Found"...
if (xHttp.readyState == xHttp.DONE) { // should be 4? Done is 4.
if (xHttp.status == 200) { // 200:"OK", 403:"Forbidden", 404:"Not Found"...
console.log("score data sent.");
} else {console.log("fail to send score.")}
}
Expand All @@ -38,6 +39,8 @@ function getAverage() {
}

function showResult() {
let averageBox = document.getElementById("averageShow");
averageBox.innerText = ("Average score is " + xHttp.responseText + ".");
let finTime = new Date().getTime();
let delta = Math.sqrt((myColor[0] -r)**2 + (myColor[1] -g)**2 + (myColor[2] -b)**2);
let score = deltaToScore(delta);
Expand All @@ -51,7 +54,7 @@ function showResult() {
let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == xmlHttp.DONE) {
if (xmlHttp.readyState == 200) { // 200:"OK", 403:"Forbidden", 404:"Not Found"...
if (xmlHttp.status == 200) { // 200:"OK", 403:"Forbidden", 404:"Not Found"...
console.log("score data sent.");
} else {console.log("fail to send score.")}
}
Expand All @@ -67,7 +70,18 @@ function adjustingSlider(sidx) {
showYourColor(myColor);
}

function fineTune(slider, incre) {
let mousedownTimer;
function fineTuneStart(slider, incre) {
mousedownTimer = setInterval(
function() {
fineTune(slider, incre);
}, 200);
}
function fineTuneEnd() {
clearInterval(mousedownTimer);
}

function fineTune(slider, incre) {
sliders[slider].value = myColor[slider] + parseInt(incre);
adjustingSlider(slider);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ title: "Portfolio - Color Sense"
date: 2023-09-04 15:51:00 +0900
# toc: true
# toc_sticky: true
tags: dev portfolio color-sense
tags: dev side-project color-sense
---
첫 번째 포트폴리오입니다. 자신의 색감 테스트하는 간단한 게임 형식 웹 어플리케이션입니다.
첫 번째 사이드 프로젝트입니다. 자신의 색감 테스트하는 간단한 게임 형식 웹 어플리케이션입니다.


[웹 어플리케이션 링크](/PF/ColorSense/color-sense.html)

나름 첫 결과물이라 저에겐 의미가 깊네요. 테스트 하면서 몇가지 개선점이 떠올랐는데, 천천히 생각나면 업데이트 해 볼 생각이에요. 제작 동기나 만들면서 배운 것들은 따로 작성할 생각이에요!

☑️ 다크모드에서 색 표현에 문제가 발생하고 있으니 주의바랍니다!
- [ ] 특정 브라우저 다크모드에서 색 표현에 문제가 발생하고 있으니 주의바랍니다!
- [ ] 다른 사람들의 점수 평균을 볼 수 있게 했습니다.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ title: "Portfolio - Japaness word quiz"
date: 2023-09-06 21:27:00 +0900
# toc: true
# toc_sticky: true
tags: dev portfolio jpn-quiz
tags: dev side-project jpn-quiz
---
두 번째 포트폴리오입니다. 몇달 전 일본어 단어 외우다가 들었던 생각으로 부터 만들었습니다.
두 번째 사이드 프로젝트입니다. 몇달 전 일본어 단어 외우다가 들었던 생각으로 부터 만들었습니다.


[웹 어플리케이션 링크](/PF/JpnQuiz/jpn-quiz.html)
Expand Down
File renamed without changes.
139 changes: 139 additions & 0 deletions _posts/2023-09-19-Problem_Taxi.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
layout: single
title: "Programmers - 합승 택시 요금"
date: 2023-09-19 11:26:00 +0900
toc: true
toc_sticky: true
tags: Java Coding-problem Graph
---
Programmers 의 합승 택시 요금 문제 풀이


---

# 문제
![합승 택시 요금](https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/715ff493-d1a0-44d8-9273-a785280b3f1e/2021_kakao_taxi_01.png)
지점의 개수 `n`, 출발지점을 나타내는 `s`, A의 도착지점을 나타내는 `a`, B의 도착지점을 나타내는 `b`, 지점 사이의 예상 택시요금을 나타내는 `fares`가 매개변수로 주어집니다. 이때, A, B 두 사람이 s에서 출발해서 각각의 도착 지점까지 택시를 타고 간다고 가정할 때, 최저 예상 택시요금을 계산해서 return 하도록 solution 함수를 완성해 주세요.
만약, 아예 합승을 하지 않고 각자 이동하는 경우의 예상 택시요금이 더 낮다면, 합승을 하지 않아도 됩니다.
- 지점갯수 n은 3 이상 200 이하인 자연수입니다.
- 지점 s, a, b는 1 이상 n 이하인 자연수이며, 각기 서로 다른 값입니다.
- 즉, 출발지점, A의 도착지점, B의 도착지점은 서로 겹치지 않습니다.
- fares는 2차원 정수 배열입니다.
- fares 배열의 크기는 2 이상 n x (n-1) / 2 이하입니다.
- 예를들어, n = 6이라면 fares 배열의 크기는 2 이상 15 이하입니다. (6 x 5 / 2 = 15)
- fares 배열의 각 행은 [c, d, f] 형태입니다.
- c지점과 d지점 사이의 예상 택시요금이 f원이라는 뜻입니다.
- 지점 c, d는 1 이상 n 이하인 자연수이며, 각기 서로 다른 값입니다.
- 요금 f는 1 이상 100,000 이하인 자연수입니다.
- fares 배열에 두 지점 간 예상 택시요금은 1개만 주어집니다. 즉, [c, d, f]가 있다면 [d, c, f]는 주어지지 않습니다.
- 출발지점 s에서 도착지점 a와 b로 가는 경로가 존재하는 경우만 입력으로 주어집니다.

# 해결
그래프 관련 구현은 경험이 거의 없어서 푸는 데 시간이 꽤 걸렸습니다. 다행히 예전에 유니티로 A* algorithm 구현해 본 기억하고, 대학원생 때 후배 S 가 했던 발표 내용 중에 Dijkstra algorithm 이 기억에 있었습니다. ~~S 가 발표를 엄청 잘하는 친구여서 기억에 남아있었다~~

두 가지 시행 착오가 있었습니다.
- 체크해야 할 노드를 어떻게 관리해야 하는지 몰랐어서, 코드도 복잡해지고 상당히 헤멨습니다. Queue 를 쓰면 딱 좋은 상황이란 걸 뒤늦게 알았습니다.
- 노드의 초기 cost 를 설정할 때, 적당히 높은 값을 줘야 했는데 너무 작게 줘서 몇몇 case 에서 실패한 적이 있습니다.
- 저 같은 경우엔 `int cost = Integer.MAX_VALUE;` 로 해결했습니다.
- 문제 조건에서 max 조건인 `n=200`, `f=100,000` 을 잘 생각해보면 최소한 둘을 곱한 값을 써야 한다는 걸 알 수 있습니다.
- 아니면 `int cost = -1;` 같이 사용되지 않는 범위에 적당히 두고, `setCost()` 메서드에서 해당 경우를 처리해 줘도 되었겠습니다.

아래 코드는 programmer에 제출한 것이 아니라, 다른 에디터에서 작성해 둔 것입니다.
```java
import java.util.*;

public class Programmers {
public static void main(String[] args) {
int print = solution(
6, 4, 6, 2,
new int[][] {
{4, 1, 10}, {3, 5, 24}, {5, 6, 2},
{3, 1, 41}, {5, 1, 24}, {4, 6, 50},
{2, 4, 66}, {2, 3, 22}, {1, 6, 25}}
);

System.out.println(print);
}

// 여기부터 제출
public static int solution(int n, int s, int a, int b, int[][] fares) {
ArrayList<Node> graph = initialize(n, fares); // initialize 도 dijkstra 안에 넣는게 나았겠네요.
int[] resultN = dijkstra(graph, n, s);
graph = initialize(n, fares);
int[] resultA = dijkstra(graph, n, a);
graph = initialize(n, fares);
int[] resultB = dijkstra(graph, n, b);

int answer = Integer.MAX_VALUE;
for(int i = 0; i < n; i++) {
int trial = resultN[i] + resultA[i] + resultB[i];
if(trial == 0) continue;
answer = (answer > trial)? trial:answer;
}
return answer;
}

private static int[] dijkstra(ArrayList<Node> graph, int n, int s) {
int[] result = new int[n];
Node start = graph.get(s-1);
start.cost = 0;
LinkedList<Node> que = new LinkedList<Node>(); // Queue 로 처리해야 할 노드를 관리
que.add(start);
while(!que.isEmpty()) {
Node checkNode = que.pollFirst();
ArrayList<Node> neig = checkNode.neigbours;
int neigSize= neig.size();
for(int i = 0; i < neigSize; i++) {
if(neig.get(i).setCost(checkNode.cost +
checkNode.weights.get(i))) {
que.add(neig.get(i)); // 노드의 cost 를 갱신했다면, 그 노드의 이웃 노드는 다시 계산해 볼 필요가 생깁니다.
result[neig.get(i).idx-1] = checkNode.cost +
checkNode.weights.get(i);
}
}
}
return result;
}

private static ArrayList<Node> initialize(int n, int[][] fares) {
ArrayList<Node> list = new ArrayList<Node>();
for(int i = 0; i<n; i++) {
list.add(new Node(i+1));
}
for(int[] i : fares) {
list.get(i[0]-1).setGraph(list.get(i[1]-1), i[2]);
}
return list;
}
}

class Node{
int idx;
int cost = Integer.MAX_VALUE; // 이 값이 너무 낮게 설정되어 실패 케이스가 있었다...
// 생각해보면 요금이 100,000 이 최대고 n이 200 이하니까 최소한 둘 곱한 것은 되어야 했음.
// 이런 스케일을 미리 생각할 수 있으면 도움 될듯...
ArrayList<Node> neigbours = new ArrayList<>();
ArrayList<Integer> weights = new ArrayList<>();
Node(int idx){
this.idx = idx;
}
boolean setCost(int cost) {
if(this.cost > cost) { // 사실 이 부분이 dijkstra algorithm 의 일부라서, 여기 있는게 그리 좋아보이진 않네요.
this.cost = cost;
return true;
}
return false;
}
void setGraph(Node other, int weight) {
this.neigbours.add(other);
other.neigbours.add(this);
this.weights.add(weight);
other.weights.add(weight);
}
@Override
public String toString() { // 디버깅용 메서드라 실제 제출할 땐 뺐습니다.
return "Node:" + idx + " Cost:" + cost + "\n";
}
}
```

Loading

0 comments on commit dbad1bb

Please sign in to comment.