현재 진행 중인 프로젝트를 vercel에 배포한 후 계속 500 에러가 발생했습니다. 임시 데이터로 진행할 때 500에러가 발생하지 않았지만 호출한 데이터를 사용하도록 코드를 변경하면 계속 500 에러가 발생했습니다.

 

500 에러의 경우 서버에서 발생한 것이기 때문에 페이지 콘솔에서는 아무것도 확인할 수 없었습니다. 이 경우 vercel의 로그를 확인해야합니다. 로그를 확인하고 500 에러를 해결하는 과정을 작성할 예정입니다.

 

맨 밑에 결론이 있습니다. 어떻게 해결하면 되는지 궁금하신 분은 바로 결론 봐주시면 됩니당 :)

 

 

1. Details 접속

생각보다 간단합니다. vercel에 배포한 상태에서 github에 push하고 pr을 진행할 때, 아래 사진과 같이
Details를 확인할 수 있습니다.

클릭하여 Deployment 옆에 있는 Logs를 클릭하여 어떤 오류가 발생했는지 확인하고 해결하면 됩니다.

 

 

 

2. 로그 확인을 통한 에러 발생 원인 파악

 

⨯ Error: Could not load the "sharp" module using the linux-x64 runtime

 

이렇게 어디 부분에서 문제가 발생했는지 알 수 있습니다. 필자의 경우는 linux-x64 환경에서 sharp 모듈을 로드할 수 없어 발생한 문제였습니다. 이는 linux-x64 환경에서 모듈을 사용할 수 있도록 

옵션 의존성 설치나 플랫폼을 지정하여 설치해주면 된다고 합니다.

 

 

옵션 의존성 설치

먼저 옵션 의존성 설치를 진행한 후 다시 배포하여 오류가 해결되는지 확인해 보겠습니다.

위 명령어를 입력하여 설치한 후 github에 push 했습니다.

 

해당 오류가 발생했습니다. 사실 이건 이전에도 발생했던 오류입니다. 그 이유는 sharp 라이브러리는 0.33.2 이상 버전부터 vercel 배포 환경에서 오류를 발생시키더라고요. 그렇기에 위에서 옵션 의존성 설치를 진행할 때 버전을 0.33.1 버전으로 설치해줘야합니다. 

 

다시 설치를 진행하고 배포를 진행해보겠습니다.

설치 후 다시 확인해 봤는데 RangeError는 발생하지 않지만 여전히 같은 에러가 발생했습니다.

 

 

플랫폼 지정 설치

설치 후 다시 push 진행했는데도 같은 에러가 발생하네요..ㅠㅠㅠ

 

 

Vercel only: 0.33.0: error Could not load the "sharp" module using the linux-x64 runtime · Issue #3870 · lovell/sharp

Possible bug Is this a possible bug in a feature of sharp, unrelated to installation? Running npm install sharp completes without error. Running node -e "require('sharp')" completes without error. ...

github.com

해결하기 위해 찾아본 결과 sharp 버전 문제인 것 같아서 버전을 한단계 더 낮춰 옵션 의존성 설치를 진행한 후 다시 배포해보겠습니다.

 

똑같이 에러가 발생하여 버전을 0.32.6으로 낮추어 다시 배포해 보겠습니다.

 

한가지 간과한 점이 npm uninstall sharp를 하지 않고 덮어써서 문제가 발생한 것 같습니다. 
uninstall을 진행한 후 0.33.1로 재설치 해보겠습니다.

 

여전히 같은 에러가 발생하네요..ㅠㅠ 0.32.6으로 버전을 낮춰 다시 배포해 보겠습니다.

 

 

결론

 

sharp 0.32.x 버전으로 다운 그레이드 하자

 

드디어 해결했습니다! 생각보다 너무 가벼운(?) 해결방법이라 허무했습니다..ㅠㅠ
AWS Lambda 환경에서 0.32.6 이상의 sharp 라이브러리가 작동하지 않는 것 같습니다. 버전을 0.32.6으로 낮추고 실행하니 500 에러가 더이상 발생하지 않습니다. 좀 더 공부하여 버전을 낮추는 해결 방법이 아닌 최신 라이브러리를 사용하더라도 오류를 해결할 수 있는 방법을 찾아보겠습니다 이상입니다. 긴 글 읽어주셔서 감사합니다.

시맨틱 태그란 무엇일까?

시맨틱(semantic)이라는 것은 '의미의', '의미론적인'이라는 뜻을 까진 형용사입니다.
즉, div 태그에 의미를 부여하여 문서의 가독성을 높이기 위해 만들어진 태그입니다.

HTML5에서 처음 등장 했으며 <header>, <nav>, <article>, <section>, <footer>, <main> 으로 직관적인 문서 설계가 가능합니다.

 

 

시맨틱 태그를 사용해 얻을 수 있는 이점

  • 유지 보수성이 증가합니다. : HTML 문서의 가독성과 유지 보수가 쉬워집니다.
  • 웹 접근성이 높아집니다. : 웹 브라우저가 HTML만 보고도 상단(header), 본문(main), 하단(footer), 사이드(aside) 등 어느 영역인지 쉽게 알 수 있습니다. 이를 통해 시각 장애인들이 사이트를 사용할 때 이용하는 스크린 리더기에서 유용하게 사용될 수 있습니다.
  • SEO 측면에서 유리합니다. : 검색 엔진은 웹페이지의 여러 정보들을 수집해서 검색 키워드에 알맞게 노출시킵니다. 이 때 시맨틱 태그로 작성할 경우 검색 엔진에 노출되기 좋아집니다.

 

시맨틱 태그에 대해 알아봅시다!

다양한 방식으로 구현 될 수 있습니다. 우선 레이아웃 예시들을 보고 각 태그들에 대해 설명하겠습니다.

<예시 1 : main에 article, aside, section을 모두 포함>
<예시 2 : main과 aside를 분리>

main에 포함과 분리 뿐만 아니라

article로 콘텐츠를 분리하고 section을 나누기도 하고,

section으로 콘텐츠를 분리하고 article로 나누기도 하는데

이는 각 태그에 대해 알면 어떻게 사용할지 감을 잡을 수 있습니다. 

 

header

  • hearder는 웹 사이트의 상단에 위치하는 태그이며, 로고나 검색 로그인 등의 글로벌 링크가 위치합니다.

nav

  • nav는 페이지의 특정 콘텐츠나 다른 페이지로 이동할 수 있는 버튼 등을 모아둔 메뉴 영역입니다.
  • 네비게이션의 약자이며, 본문의 위치에 영향을 받지 않고 어디서든지 독립적으로 사용가능합니다,

main

  • 본문 내용을 나타내는 태그이며 IE ( Internet Explorer ) 환경에서는 지원하지 않습니다.
  • 웹 페이지에서 단 한 번만 사용해야 합니다.
  • 내부에서 article과 section을 이용헤 구조적인 웹사이트를 구성하는 것이 좋습니다.

aside

  • 전체 내용과 연관성이 있지만, 주 콘텐츠와 분리되어 직접적인 상관이 없는 부가적인 내용을 담습니다.
  • 주로 사이드바에 적용되며 세로로 따로 배치됩니다.

(저는 main 태그와 분리하는게 더 적절하다고 생각합니다.)

 

article

  • 독립적인 내용을 나타낼 때 사용합니다.
  • 즉, <main>안에 있는 다른 내용들과 전혀 상관없이 독립적으로 고유한 정보를 나타낼때 사용합니다.
  • 일반적으로 제목 태그를 포함시켜 사용합니다.
  • article이나 section을 자식으로 포함해도 문제되지 않습니다.

section

  • 주 내용에서 흐름을 나눠주는 태그입니다. 책에서의 챕터 역할이라고 생각하면 편합니다.
  • 연관있는 내용들을 묶어주고 싶을 때 사용합니다.
  • 일반적으로 제목 태그를 포함시켜 사용합니다.
  • main 안에서 연관있는 내용들을 묶어주기 위해 사용되기도하고,
    article 안에서 연관있는 내용들을 묶어주기 위해 사용되기도 합니다.

※ aeticle과 section

둘은 약간 헷갈릴 수 있는 내용이라고 생각되어 사용 예시를 들어 정리하고자 합니다.

<main>
   <article>
    	독립적인 내용이며 다른 내용과 연관이 없음
    	<secttion>
        	연관 있는 내용들끼리 묶어줌
    	</secttion>
    </article>
    
    <secttion>
    	연관 있는 내용들
        <article></article>
    </secttion>
    
    <secttion>
    	연관있는 내용들
    </secttion>
</main>

위와 같이 

- artcle로 콘텐츠를 나눈 후 section으로 묶어둬도 되고, (그 안에 또 article을 사용하는 것도 가능)

- section으로 관련 내용끼리 분할한 후 article로 나누어도 됩니다. (article 안에서 또 section으로 내용을 나누어줘도 됨)

위의 두개를 모두 합쳐서 사용해도 되지만 ,

헷갈리지 않기 위해선 자신만의 기준을 잘 잡아놓고 나누는 것이 좋을 것 같습니다.

 

figure, figcaption

  • figure는 이미지 영역을 나타내는 태그입니다. img와 figcaption을 자식으로 포함시켜 사용합니다.
  • figcaption은 이미지에 대한 설명을 나타매고 반드시 figure을 부모로 두어야합니다.
  • 여기서 중요한 점은 figcaption 태그의 내용은 alt와는 구별되어야 합니다.
  • 동일한 내용이 들어가면 스크린 리더기는 중복된 내용을 출력할 것이기 때문입니다. 이미지에 대한 설명, 또는 사진과 관련 있는 설명은 figcaption에 포함시키고, alt에는 이미지 자체를 표현할 수 있는 단어나 문장을 포함시키면 됩니다.

footer

  • 최하단에 위치합니다. 저작권, 사업자정보, 전화번호, 주소 등
    웹사이트나 기업의 정보를 표시하는 공간으로 활용합니다.

details, summary

  • details은 사용자가 보거나 숨실 수 있는 추가 세부 정보를 정의하는 태그입니다.
  • 사용자는 버튼을 통해 열고 닫을 수 있습니다.
  • 기본적으로 닫은 상태에 있고 클리하면 내용이 보이며 확장되는 성질을 가집니다.
  • 여기서 summary 태그가 사용되는데 details에서 보이는 부분을 담당합니다.
  • summary 태그는 details태그의 첫번째 하위 항복이어야합니다.

 

스크린 리더 읽힐 때 차이가 나는 태그들도 몇개 알아보고 가면 좋을 것 같습니다.

 

<i> VS <em>

<i> : 이탤릭체를 시각적으로만 사용하고 싶을 때 사용

<em> : 이탤릭체를 강조하고 싶을 때 사용

 

<b> VS <strong>

<b> : 시각적으로만 볼드체를 사용하고 싶을 때

<strong> : 강조하는 볼드테에 사용

 

이상입니다. 읽어주셔서 감사합니당 :)

 

웹 표준이란?

웹 표준은 웹에서 사용되는 기술들의 표준화를 의미합니다.
즉, 웹사이트를 구성할 때 사용하는 HTML, CSS, JavaScript등을 표준화된 방식으로 작성되어야 한다는 것입니다.
이러한 웹표준을 지켜 웹사이트를 만든다면 어떤 브라우저나 기기를 사용하더라도
홈페이지 화면을 동일하게 볼 수 있습니다. 그렇기에 우리는 개발을 할 때 웹 표준을 고려해야 하는 것입니다.

웹 표준을 준수할 경우 얻을 수 있는 이점

  1. 웹 페이지가 모든 브라우저에서 일관적으로 표시되며, 모든 사용자에게 동일한 사용자 경험을 제공할 수 있습니다.
  2. 검색 엔진 최적화에 유리합니다.
  3. 유지 보수 밒 확작성이 좋아지고 보장됩니다.
  4. 웹 접근성 또한 향상됩니다.

 

웹 표준을 준수하는 방법!

  1. DOCTYPE 선언 :
    웹 페이지의 최상단에 DOCTYPE을 선언하여  웹 페이지가 어떤 버전의 HTML, XHTML을 사용하는지 명시합니다.

  2. 시맨틱 태그 사용 :
    <header>,<nav>,<section>,<footer> 등 웹 페이지의 구조를 명확하게 표한하는 시맨틱 태그를 사용합니다.

  3. css 스타일 시트 사용 :
    css 스타일 시트를 사용해 디자인과 레이아웃을 분리하고 웹 페이지의 내용과 디자인을 분리하여 유지보수와 확장성을 높일 수 있습니다.

  4. 웹 접근성 고려 :
    모든 사용자가 쉽게 접근할 수 있도록 웹을 제작하여야 한다. 예를 들어 시각 장애인이 스크린 리더를 사용하여 웹 페이지를 읽을 수 있도록 alt 속성을 사용한다거나 키보드만으로 모든 기능을 사용할 수 있도록 tabindex 속성을 사용하는 등이 있습니다.

여기서 웹 접근성이란 무엇인지 알아봅시다.

 


 

웹 접근성

 

장애를 가진 사람들도 신체적 환경적 조건에 관계 없이 인터넷을 통해 정보에 접근하고 이용할 수 있도록 하는 것을 말합니다. 이를 통해 인터넷을 인종, 성별, 연령, 장애 유무와 상관 없이 모두가 이용할 수 있는 공간으로 만듭니다.


예를 들자면, 위에서 언급했듯이 시각 장애인이 웹을 사용하기 위해 이용하는 스크린 리더를 고려해 이미지만 쓰는 것이 아닌 이미지를 설명하는 alt를 사용하는 것이 있습니다.



웹 접근성을 준수하기 방법

  1. 시각적 요소 처리 :
    시각 장애인은 이미지, 비디오, 그래픽, 등을 시각적 요소를 인식할 수 없다는 것을 인지해야합니다.
    따라서 대체 텍스트, 색상 대비, 텍스트 크기 등을 고려해 시각적 요소를 처리해야합니다.

  2. 청각적 요소 처리 :
    청각 장애인오디오 콘텐츠를 이해할 수 없습니다.
    때문에 자막, 수화, 오디오 설명 등을 제공하여 청각적 요소를 처리해야합니다.

  3. 키보드 접근성 :
    지체 장애인은 마우스를 사용하지 못하는 경우가 많습니다.
    그렇기에 키보드만으로 웹사이트를 이용할 수 있도록 고려해야합니다.

  4. 웹 접근성 검사 :
    WCAG 준수 여부를 검사하여 웹 접근성을 확보해 봅시다.

 

WCAG란?

웹 콘텐츠 접근성 지침(WCAG)이란 웹 접근성을 확보하기 위한 국제 표준입니다.
4가지 원칙, 13가지 지침, 78가지 성공 기능으로 구성되어 있습니다.

 


 

1. 인식의 용이성

정보와 사용자 인터페이스 요소는 그들이 인지할 수 있도록 사용자에게 표시되어야 한다.
다수의 감각을 사용해 어떤 방식으로든 인지할 수 있어야한다.

 

a. 텍스트가 아닌 콘텐츠에 대체 텍스트를 제공해야한다. (인쇄, 점자, 음성, 기호 등)

 

b. 정보와 구조의 손실 없이 콘텐츠를 표현할 수 있어야 한다.(콘텐츠에 대한 간단한 소개)

 

c. 전경(선택된 정보)과 배경(그 이외의 정보)을 분리하는 등 사용자가 콘텐츠를 보다 쉽게 보고 들을 수 있도록 한다.


 

2. 운용의 용이성 

사용자 인터페이스 요소와 탐색은 운용 가능해야한다. 쉽게 말하면 모든 사용자가 UI 요소들을 컨트롤 할 수 있어야한다. (마우스 → 키보드 || 음성 명령 등)

 

a. 키보드로 모든 기능을 사용할 수 있어야한다.

 

b. 읽기 및 콘텐츠를 사용하는 사용자에게 충분한 시간을 제공해야한다.

 

c. 사용자가 콘텐츠를 탐색하는 방법그들이 어디에 위치하고 있는지를 알 수 있는 방법제공해야한다.


 

3. 이해의 용이성 

정보와 사용자 인터페이스 운용은 이해할 수 있어야한다.

 

a. 텍스트 콘텐츠를 판독하고 이해할 수 있도록 만들어야 한다.

 

b. 웹 페이지의 탑재와 운용을 예측 가능한 방법으로 제작해야한다.

 

c. 사용자의 실수을 방지하고 수정할 수 있도록 도와야한다


 

4. 내구성

콘텐츠는 각기 다른 브라우저에서 현재와 미래에 모두 동작할 수 있도록 웹 표준을 준수해 개발하여야 한다. 즉 호환성을 최대로 높여야한다.


 

위의 내용은 WCAG 2.0 기준입니다.

현재는 WCAG 2.1을 채택해 사용하고 있다고 합니다.

먼저 WCAG 2.0을 충족하고 단계적으로 2.1을 적용할 예정입니다.

 

WCAG 2.1

  • 시각 (Visual)
  • 청각 (Auditory)
  • 지체 (Physical)
  • 음성 (Speech)
  • 인지 (Cognitive): WCAG 2.1 추가 항목
  • 언어 (Language)
  • 학습 (learning): WCAG 2.1 추가 항목
  • 신경 (Neurological)

참고 블로그

 

🌐 웹 표준 & 웹 접근성 이란?

웹 표준 (Web Standards) 웹 표준은 웹에서 사용되는 기술들의 표준화를 의미한다. 즉, 웹 사이트를 구성하는 HTML, CSS, JavaScript 등의 언어들이 표준화된 방식으로 작성되어야 한다는 것이다. 쉽게 말

inpa.tistory.com

 

 

[HTML] 웹 콘텐츠 접근성 가이드라인 WCAG 2.1

웹 콘텐츠 접근성 가이드라인(이하 WCAG)은 Web Content Accessibility Guidelined의 약자로, 어떠한 장애유형에 영향을 받지 않고 모든 사람이 웹 콘텐츠에 보다 쉽게 접근할 수 있게 만들기 위해 발표된 W3C

velog.io

 

 

웹 컨텐츠 접근성 지침 이해하기 - 접근성 | MDN

이 문서에서는 W3C 웹 컨텐츠 접근성 지침 2.0 또는 2.1(이 글에서는 WCAG)에 설명된 권장 사항들을 준수하기 위한 단계들을 이해하는 데에 도움이 되는 간략한 설명을 제공합니다.

developer.mozilla.org

 

|| 문제 설명 ||

1 x 1 크기의 칸들로 이루어진 직사각형 격자 형태의 미로에서 탈출하려고 합니다. 각 칸은 통로 또는 벽으로 구성되어 있으며, 벽으로 된 칸은 지나갈 수 없고 통로로 된 칸으로만 이동할 수 있습니다. 통로들 중 한 칸에는 미로를 빠져나가는 문이 있는데, 이 문은 레버를 당겨서만 열 수 있습니다. 레버 또한 통로들 중 한 칸에 있습니다. 따라서, 출발 지점에서 먼저 레버가 있는 칸으로 이동하여 레버를 당긴 후 미로를 빠져나가는 문이 있는 칸으로 이동하면 됩니다. 이때 아직 레버를 당기지 않았더라도 출구가 있는 칸을 지나갈 수 있습니다. 미로에서 한 칸을 이동하는데 1초가 걸린다고 할 때, 최대한 빠르게 미로를 빠져나가는데 걸리는 시간을 구하려 합니다.

미로를 나타낸 문자열 배열 maps가 매개변수로 주어질 때, 미로를 탈출하는데 필요한 최소 시간을 return 하는 solution 함수를 완성해주세요. 만약, 탈출할 수 없다면 -1을 return 해주세요.


제한사항
  • 5 ≤ maps의 길이 ≤ 100
    • 5 ≤ maps[i]의 길이 ≤ 100
    • maps[i]는 다음 5개의 문자들로만 이루어져 있습니다.
      • S : 시작 지점
      • E : 출구
      • L : 레버
      • O : 통로
      • X : 벽
    • 시작 지점과 출구, 레버는 항상 다른 곳에 존재하며 한 개씩만 존재합니다.
    • 출구는 레버가 당겨지지 않아도 지나갈 수 있으며, 모든 통로, 출구, 레버, 시작점은 여러 번 지나갈 수 있습니다.

입출력 예mapsresult
["SOOOL","XXXXO","OOOOO","OXXXX","OOOOE"] 16
["LOOXS","OOOOX","OOOOO","OOOOO","EOOOO"] -1

입출력 예 설명

입출력 예 #1

주어진 문자열은 다음과 같은 미로이며

다음과 같이 이동하면 가장 빠른 시간에 탈출할 수 있습니다.

4번 이동하여 레버를 당기고 출구까지 이동하면 총 16초의 시간이 걸립니다. 따라서 16을 반환합니다.

입출력 예 #2

주어진 문자열은 다음과 같은 미로입니다.

시작 지점에서 이동할 수 있는 공간이 없어서 탈출할 수 없습니다. 따라서 -1을 반환합니다.

 

 

 

틀린풀이 1

계속 이상하게 문제를 풀어서 이 문제만 3시간은 잡고 있었던거 같다ㅠㅠ

일단 처음에 했던 방식은 아래와 같다

from collections import deque

def solution(maps):
    answer = 0
    n = len(maps)
    m = len(maps[0])
    dh = [1, -1, 0, 0]
    dw = [0, 0, 1, -1]
    vis = []
    visForE = []
    dis = []

    s = []
    e = [] 

    # visit 만들기
    for i in range(n):
        arr = []
        for j in range(m):
            arr.append(0)
        vis.append(arr)
        visForE.append(arr)
        dis.append(arr)



    # 시작점 찾기
    for i in range(n):
        for j in range(m):
            if maps[i][j] == "S":
                s.append(i)
                s.append(j)

    # 탈출점 찾기
    for i in range(n):
        for j in range(m):
            if maps[i][j] == "E":
                e.append(i)
                e.append(j)            


    # 레버까지의 최단거리 + 레버 -> 탈출구 까지의 최단거리
    time = 0
    queue = deque()
    queue.append(s)

    equeue = deque()

    while queue:
        h, w = queue.popleft()
        vis[h][w] = 1 # 방문 처리

        if maps[h][w] == "L":
            equeue.append((h, w, 0))
            break

        for i in range(4):
            nh = h + dh[i]
            nw = w + dw[i]

            if nh < 0 or nh >= n or nw < 0 or nw >= m:
                continue

            if maps[nh][nw] == "X":
                continue

            if vis[nh][nw] == 1:
                continue

            if vis[nh][nw] == 0:
                queue.append((nh, nw))
                time += 1

    print(time)
    print(queue)
    print(equeue)

이렇게 레버까지의 걸린 시간을 구한 후에 레버에서 탈출구까지 걸리는 시간을 구할려고 했다. 하지만 이 방식은 탐색을 진행할 때마다 전역 변수인 time에 +1을 해주기 때문에 탐색하는 모든 시간을 구하므로 옳지 않다.

 

그래서 큐에 비용까지 포함해서 다시 코드를 작성했다.

 

틀린 풀이 2

 

from collections import deque

def solution(maps):
    answer = 0
    n = len(maps)
    m = len(maps[0])
    dh = [1, -1, 0, 0]
    dw = [0, 0, 1, -1]
    lastcost = 0
    
    vis = []
    visForE = []
    
    s = []
    
    # visit 만들기
    for i in range(n):
        arr = []
        for j in range(m):
            arr.append(0)
        vis.append(arr)
        visForE.append(arr)
    
    # 시작점 찾기
    for i in range(n):
        for j in range(m):
            if maps[i][j] == "S":
                s.append(i)
                s.append(j) 
    
    # 레버까지의 최단시간 구하기
    h, w = s
    vis[h][w] = 1
    queue = deque()
    queue.append((h, w, 0))
    
    
    while queue:
        h, w, cost = queue.popleft()
        
        if maps[h][w] == "L":
            queue.append((h, w, cost))
            break
        
        for i in range(4):
            nh = h + dh[i]
            nw = w + dw[i]
            
            if nh < 0 or nh >= n or nw < 0 or nw >= m:
                continue
            
            if maps[nh][nw] == "X":
                continue
            
            if vis[nh][nw] == 1:
                continue
            
            if vis[nh][nw] == 0:
                queue.append((nh, nw, cost + 1))
                vis[nh][nw] = 1
    
    # 레버에서 탈출점까지의 최단 시간 구하기
    
    while queue:
        x, y, cost = queue.popleft()
        
        if maps[x][y] == "E":
            return cost
            break
        
        for i in range(4):
            nh = x + dh[i]
            nw = y + dw[i]
            
            if nh < 0 or nh >= n or nw < 0 or nw >= m:
                continue
            
            if maps[nh][nw] == "X":
                continue
            
            if vis[nh][nw] == 1:
                continue
            
            if vis[nh][nw] == 0:
                queue.append((nh, nw, cost + 1))
                vis[nh][nw] = 1
    
    ## 비용으로 생각해서 풀자 전역적으로 time을 지정해서
    ## 풀려고 하니까 최단 거리가 아니라
    ## 모든 지점을 탐색하는데 걸린 시간이 출력되어서 계속 못 풀었다
    
    return -1

이 경우는 무조건 레버를 찾을 수 있다는 가정하에 다음 단계로 넘어가기 때문에 정답을 맞히지 못한건 같다 그래서 bfs 함수를 따로 만들어서 (시작점, 목표점, maps)를 입력해 cost 값을 받는 방식으로 바꿔보기로 했다.

 

옳은 풀이

from collections import deque

def bfs(start, end, maps):
    h, w = start
    eh, ew = end
    
    dh = [1, -1, 0, 0]
    dw = [0, 0, 1, -1]
    n = len(maps)
    m = len(maps[0])
    
    visit = []
    for i in range(n):
        arr = []
        for j in range(m):
            arr.append(0)
        visit.append(arr)
    
    que = deque()
    que.append((h, w, 0))
    visit[h][w] = 1
    
    while que:
        h, w, cost = que.popleft()
        
        if h == eh and w == ew:
            return cost
        
        for i in range(4):
            nh = h + dh[i]
            nw = w + dw[i]
            
            if nh < 0 or nh >= n or nw < 0 or nw >= m:
                continue
            
            if maps[nh][nw] == "X":
                continue
            
            if visit[nh][nw] == 1:
                continue
            
            if visit[nh][nw] == 0:
                que.append((nh, nw, cost + 1))
                visit[nh][nw] = 1
    
    return -1
    
def solution(maps):
    s = []
    e = []
    l = []
    
    n = len(maps)
    m = len(maps[0])
    
    for i in range(n):
        for j in range(m):
            if maps[i][j] == "S":
                s.append(i)
                s.append(j)
    
    for i in range(n):
        for j in range(m):
            if maps[i][j] == "L":
                l.append(i)
                l.append(j) 
    
    for i in range(n):
        for j in range(m):
            if maps[i][j] == "E":
                e.append(i)
                e.append(j)
    
    path1 = bfs(s, l, maps)
    path2 = bfs(l, e, maps)
    
    if path1 != -1 and path2 != -1:
        return path1 + path2
    
    return -1

 

함수를 따로 만들어서 시작점과 끝점을 정하고 각각 따로 bfs를 돌려서 각 비용을 계산하고 둘다 찾아진다면 두 비용을 합친 것을 리턴하고 아니라면 -1을 리턴해 마무리 해준다.

 

항상 차분하게 문제를 보고 신중하게 생각하자

+ Recent posts