주기율표 코드 골프

다른 날 나는이 트윗을 발견했습니다.





컴퓨터 과학


@compscifact






코드 골프 챌린지: 원자 번호를 받아 주기율표에서 해당 행과 열을 반환하는 프로그램을 작성하세요. 예를 들어, 입력이 29이면 출력은 (4, 11)입니다. 트윗에 맞는 글을 쓸 수 있나요?


오후 14:50 - 2022년 6월 16일









일부 프로그래밍 항목을 해결하고 새로 고칠 수 있는 좋은 도전이라고 생각하여 편집기를 열고 솔루션 코딩을 시작했습니다 🤓

문제 이해



Wikipedia에서 주기율표에 대해 읽으면서 그것을 표시하는 한 가지 방법보다 more이 있다는 것을 발견했습니다. 트윗의 예를 고려하여 표준 형식이라고 가정하겠습니다.

테이블을 살펴보면 가장 먼저 눈에 띄는 것은 테이블에서 요소가 배치되는 방식입니다.



보시다시피 일반 테이블이지만 몇 가지 예외가 있습니다. 예를 들어, 원자 번호가 2인 헬륨은 그룹 2에서 시작해야 하지만 그렇지 않습니다(이유를 알고 싶으면 this 확인). 따라서 이러한 특수한 경우를 추적해야 합니다. 총 3개의 예외가 있습니다( He , BAl ).

고려해야 할 또 다른 특별한 경우가 있습니다: 란타노이드와 악티노이드. 단순함을 위해 우리는 이 문제에 대해서는 고려하지 않을 것입니다.

이제 모든 것이 명확해졌으니 시작하겠습니다!

1단계 - 1D에서 2D로



첫 번째 작업은 원자 번호를 테이블의 행과 열에 매핑하는 방법을 찾는 것입니다. 우리는 원자 번호가 1에서 118까지 순차적이며 주기율표에도 18개의 그룹이 있다는 것을 알고 있습니다. 일반 테이블을 고려하면 다음을 수행할 수 있습니다.

function getElementPosition(atomicNumber) {
  const groups = 18
  const index = atomicNumber - 1;
  const row = Math.trunc(index / groups)
  const column = index % groups

  return [row + 1, column + 1]
}


여기서는 1차원 인덱스를 2차원 인덱스로 변환합니다. 좋은 출발점이지만 특별한 경우를 고려해야 합니다.

2단계 - 특별한 경우



특별한 경우에 배열을 사용하여 시작할 때 저장하고 적용해야 하는 오프셋을 저장할 수 있습니다.

function getElementPosition(atomicNumber) {
  let groups = 18
  let index = atomicNumber - 1;
  let specialNumbers = [
    [2, 16], 
    [5, 10],
    [13, 10],
  ]

  for (let [number, offset] of specialNumbers) {
    if (number <= atomicNumber) {
      index += offset
    }
  }

  let row = Math.trunc(index / groups)
  let column = index % groups

  return [row + 1, column + 1]
}


이 경우 특수 번호(He, B 및 Al)를 기반으로 필요한 오프셋을 추가합니다. 이제 getElementPosition(2)를 수행하면 [1, 18] 💪가 반환됩니다.

하지만 잠깐만요, 금은 어떻게 될까요? getElementPosition(79)를 호출하면 [7, 7]가 반환됩니다. 아니요, 확실히 작동하지 않는 것이 있습니다.

3단계 - 란타노이드 및 악티노이드



좋아, 우리는 란타노이드와 악티노이드를 생각하지 않았다. 특별한 경우 배열로 수정해 보겠습니다.

function getElementPosition(atomicNumber) {
  let groups = 18
  let index = atomicNumber - 1;
  let specialNumbers = [
    [2, 16], 
    [5, 10],
    [13, 10],
    [71, -14],
    [103, -14],
  ]

  for (let [number, offset] of specialNumbers) {
    if (number <= atomicNumber) {
      index += offset
    }
  }

  let row = Math.trunc(index / groups)
  let column = index % groups

  return [row + 1, column + 1]
}


이 경우 확장(양수 오프셋) 대신 축소(음수 오프셋)합니다. 예, 이제 작동하며 getElementPosition(79)를 호출하면 [6, 11] 🙂이 반환됩니다.

거의 다 왔어, 마지막 단계로 가자

4단계 - 축소



minification service을 사용한 후 코드는 다음과 같습니다.

function getElementPosition(t){let e=t-1,n=[[2,16],[5,10],[13,10],[71,-14],[103,-14]];for(let[o,r]of n)o<=t&&(e+=r);return[Math.trunc(e/18)+1,e%18+1]}


총 150바이트 문자(트윗의 경우 280바이트보다 훨씬 적음). 나쁘지는 않지만 여전히 약간 짧게 할 수 있습니다.

g=(e=>{let r=e-1,t=[[2,16],[5,10],[13,10],[71,-14],[103,-14]];for(let[f,l]of t)f<=e&&(r+=l);return[~~(r/18)+1,r%18+1]});


화살표 함수 구문을 사용하고 Math.trunc~~로 변경하여 120자로 줄였습니다!

결론



이것은 큰 도전이었고, 너무 어렵지는 않았지만 우리의 두뇌를 훈련시키기에 충분히 어려웠습니다. 그리고 우리는 이 유명한 테이블에 대해 흥미로운 사실도 배웠습니다 👨‍🔬

표지 이미지 출처https://www.flickr.com/photos/mindfrieze/258644767

좋은 웹페이지 즐겨찾기