Skip to main content
πŸŽ„ Advent of Code 08일차
  1. Posts/

πŸŽ„ Advent of Code 08일차

·1552 words·4 mins·
AdventOfCode Korean Article
May Meow
Author
May Meow
MayMeowλŠ” 개발자이자 사이버 λ³΄μ•ˆ μ• ν˜Έκ°€λ‘œ μ•”ν˜Έν™”, DevSecOps, μ˜€ν”ˆμ†ŒμŠ€ 기여에 λŒ€ν•œ 열정을 가지고 μžˆμŠ΅λ‹ˆλ‹€. 디지털 λ³΄μ•ˆμ„ κ°•ν™”ν•˜λŠ” 도ꡬλ₯Ό λ§Œλ“€κ³ , μ°½μ˜μ„±κ³Ό κΈ°μˆ μ„ κ²°ν•©ν•˜μ—¬ PHP 및 .NETκ³Ό 같은 λΆ„μ•Όμ—μ„œ ν˜μ‹ μ„ μ΄λ£¨λŠ” 것을 μ¦κΉλ‹ˆλ‹€. 항상 기술의 μƒˆλ‘œμš΄ μ˜μ—­μ„ νƒκ΅¬ν•˜λŠ” MayMeowλŠ” 디지털 ν™˜κ²½μ„ λ³΄ν˜Έν•˜λŠ” 데 μ „λ…ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.
Table of Contents

였늘의 ν€˜μŠ€νŠΈλŠ” 유령의 ν™©λ¬΄μ§€μž…λ‹ˆλ‹€. 낙타λ₯Ό 타고 무인도λ₯Ό κ°€λ‘œμ§€λ₯΄κ³  μžˆμŠ΅λ‹ˆλ‹€. λ‚™νƒ€μ˜ κ°€λ°©μ—μ„œ 지도λ₯Ό λ°œκ²¬ν–ˆμŠ΅λ‹ˆλ‹€. μ§€λ„μ—λŠ” 사막을 ν†΅κ³Όν•˜λŠ” 방법에 λŒ€ν•œ 지침과 맀듭이 μ—¬λŸ¬ 개 μžˆμŠ΅λ‹ˆλ‹€. μ§€λ„λŠ” λ‹€μŒκ³Ό 같이 λ³΄μž…λ‹ˆλ‹€.

RL

AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
EEE = (EEE, EEE)
GGG = (GGG, GGG)
ZZZ = (ZZZ, ZZZ)

λ…Έλ“œ AAAμ—μ„œ μ‹œμž‘ν•˜μ—¬ λ…Έλ“œ ZZZZ에 도달해야 ν•©λ‹ˆλ‹€. 그리고 λ…Έλ“œ ZZZ에 λ„λ‹¬ν•˜λŠ” 데 λͺ‡ 단계가 ν•„μš”ν•œμ§€ μ•Œμ•„μ•Ό ν•©λ‹ˆλ‹€.

파트 1
#

맡을 λ°°μ—΄λ‘œ ꡬ문 λΆ„μ„ν•˜λŠ” 것은 μ‰¬μ› μŠ΅λ‹ˆλ‹€.

$map = array_slice($map, 1);
$map = array_map(function ($value) {
Β  Β  [$point, $lr] = explode(' = ', str_replace(['(', ')'], '', str_replace(['(', ')'], '', $value)));
Β  Β  [$L, $R] = explode(', ', $lr);
Β  Β  return compact('point', 'L', 'R');
}, $map);

κ²°κ΅­ 지도λ₯Ό 가지고 μžˆμ—ˆμ–΄

[
	point => AAA,
	L => XXX,
	R =? BBB,
]

이제 λ‚΄κ°€ ν•΄μ•Ό ν•  일은 λͺ¨λ“  지침을 μ‚΄νŽ΄λ³΄κ³  μ™Όμͺ½μœΌλ‘œ κ°€μ•Ό ν•˜λŠ”μ§€ 였λ₯Έμͺ½μœΌλ‘œ κ°€μ•Ό ν•˜λŠ”μ§€ ν™•μΈν•˜λŠ” κ²ƒλΏμ΄μ—ˆμŠ΅λ‹ˆλ‹€.

while ($currentPoint != 'ZZZ') {
Β  Β  $currentPoint = move($currentPoint, $map, $leftRight[$i]);
Β  Β  $i++;
Β  Β  if ($i >= strlen($leftRight) ) {
Β  Β  Β  Β  $i = 0;
Β  Β  }

Β  Β  $steps++;
}

지도 κ°€μ΄λ“œμ—λŠ” μ–΄λŠ μͺ½μ„ 선택해야 ν•˜λŠ”μ§€ μ•ˆλ‚΄κ°€ λκΉŒμ§€ κ°€λ©΄ μ²˜μŒλΆ€ν„° λκΉŒμ§€ λ°˜λ³΅ν•΄μ•Ό ν•œλ‹€κ³  λ‚˜μ™€ μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 보μž₯ν•˜κΈ° μœ„ν•΄ 지침이 λλ‚˜λ©΄ μΉ΄μš΄ν„°λ₯Ό μž¬μ„€μ •ν•˜κΈ°λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.

if ($i >= strlen($leftRight) ) {
	$i = 0;
}

λ‹€μŒ 지점을 찾으렀면 array_searchλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

function move($startpoint, $map, $leftRight)
{
Β  Β  $point = array_search($startpoint, array_column($map, 'point'));
Β  Β  return $map[$point][$leftRight];
}

이 뢀뢄은 비ꡐ적 μ‰¬μš΄ λΆ€λΆ„μ΄μ—ˆμŠ΅λ‹ˆλ‹€. 적어도 3μΌμ°¨λ³΄λ‹€λŠ” 쉬웠고 μ†”λ£¨μ…˜μ— λ§Œμ‘±ν•©λ‹ˆλ‹€.

파트 2
#

이것은 (항상 κ·Έλ ‡λ“―) 첫 번째 것보닀 더 μ–΄λ €μ› μŠ΅λ‹ˆλ‹€. 이제 μ—¬λŸ¬ 경둜λ₯Ό 따라야 ν•©λ‹ˆλ‹€. μ‹œμž‘ λ…Έλ“œλŠ” λ§ˆμ§€λ§‰ λ¬Έμžκ°€ A 인 λ…Έλ“œμ΄κ³  λ§ˆμ°¬κ°€μ§€λ‘œ λŒ€μƒ λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ λ¬ΈμžλŠ” Z μž…λ‹ˆλ‹€. μ‹œμž‘ λ…Έλ“œμ™€ 끝 λ…Έλ“œμ˜ λ²ˆν˜ΈλŠ” κ°™μŠ΅λ‹ˆλ‹€. 전섀에 λ”°λ₯΄λ©΄ μ§€λ„λŠ” 인간을 μœ„ν•΄ λ§Œλ“€μ–΄μ§„ 것이 μ•„λ‹ˆλΌ μœ λ Ήμ„ μœ„ν•΄ λ§Œλ“€μ–΄μ§„ 것일 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. 무섭닀 πŸ‘»

버전 1
#

To find all start nodes I used following function

$startPoints = array_values(array_map(function ($value) {
Β  Β  return $value;
}, array_filter($map, function ($value) {
Β  Β  return substr($value['point'], -1) == 'A';
})));

λ…Έλ“œλ₯Ό ν†΅κ³Όν•˜κΈ° μœ„ν•΄ 파트 1μ—μ„œμ™€ μœ μ‚¬ν•œ while 루프λ₯Ό μ‚¬μš©ν•˜μ§€λ§Œ, 따라야 ν•˜λŠ” 각 λ…Έλ“œ(μœ„μ—μ„œλΆ€ν„°)λ₯Ό ν†΅κ³Όν•˜κΈ° μœ„ν•΄ λ‹€λ₯Έ 사이클을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

while(!isEverythingAtEnd($currentPoints, $startPointsCount)) {
Β  Β  foreach ($currentPoints as &$point) {
Β  Β  Β  Β  $point = move($point[$leftRight[$i]], $map);
Β  Β  Β  Β  array_values($currentPoints);
Β  Β  } Β  Β 
  Β  $i++;

Β  Β  if ($i >= strlen($leftRight) ) {
Β  Β  Β  Β  $i = 0;
Β  Β  } Β  Β 
Β  Β  $steps ++;
}

λ˜ν•œ λ…Έλ“œ μ΄λ¦„λ§Œ λ°˜ν™˜ν•˜λŠ” 것이 μ•„λ‹ˆλΌ 전체 지점(λ…Έλ“œ)을 λ°˜ν™˜ν•˜λ„λ‘ move ν•¨μˆ˜λ₯Ό μ—…λ°μ΄νŠΈν–ˆμŠ΅λ‹ˆλ‹€.

function move($to, $map)
{
Β  Β  $point = array_search($to, array_column($map, 'point'));
Β  Β  return $map[$point];
}

λͺ©μ μ§€μ— λ„μ°©ν–ˆλŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•΄ (λ‚΄κ°€ μžˆλŠ” λ…Έλ“œμ—μ„œ) λ§ˆμ§€λ§‰ κΈ€μžκ°€ Z인 λ…Έλ“œκ°€ λͺ‡ 개 μžˆλŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€. μ„€λͺ…μ—μ„œ Aκ°€ μžˆλŠ” λ…Έλ“œμ™€ 같은 μˆ˜λΌλŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ κ²°κ΅­ A와 Zκ°€ λͺ¨λ‘ 같은 μˆ˜μ—¬μ•Ό ν•©λ‹ˆλ‹€.

function isEverythingAtEnd($currentPoints, $startPointsCount) {
Β  Β  $atTheEnd = array_filter($currentPoints, function ($value) {
Β  Β  Β  Β  return substr($value['point'], -1) == 'Z';
Β  Β  });

Β  Β  if (count($atTheEnd) == $startPointsCount) {
Β  Β  Β  Β  return true;
Β  Β  }

Β  Β  return false;
}

그게 λ‹€μž…λ‹ˆλ‹€. 이 μ†”λ£¨μ…˜μ€ λ§Žμ€ μ–‘μ˜ λ°μ΄ν„°μ—μ„œλŠ” μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. (λͺ‡ λΆ„ λ™μ•ˆ μ—¬λŸ¬ 단계λ₯Ό 거쳐도 아직 λκΉŒμ§€ λ„λ‹¬ν•˜μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€).

버전 2
#

λ‹€μŒμœΌλ‘œ μƒκ°ν•œ 것은 νŠΈλ¦¬μ™€ 넓이 μš°μ„  검색 μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ—¬ μ²˜μŒλΆ€ν„° λκΉŒμ§€ 경둜λ₯Ό μ°ΎλŠ” κ²ƒμ΄μ—ˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ λ‹€μŒκ³Ό 같이 트리 ꡬ쑰λ₯Ό λ§Œλ“€μ—ˆμŠ΅λ‹ˆλ‹€.

$tree = [];
foreach ($map as $value) {
Β  Β  $tree[$value['point']] = [
Β  Β  Β  Β  'L' => $value['L'],
Β  Β  Β  Β  'R' => $value['R'],
Β  Β  ];
}

λ‹€μŒμœΌλ‘œ, μ‹œμž‘ λ…Έλ“œμ™€ λͺ©μ μ§€ λ…Έλ“œλ₯Ό λͺ¨λ‘ μ°Ύμ•˜μŠ΅λ‹ˆλ‹€.

$startNodes = array_filter(array_keys($tree), function($node) { return substr($node, -1) == 'A'; });

$endNodes = array_filter(array_keys($tree), function($node) { return substr($node, -1) == 'Z'; });

λͺ¨λ“  경둜λ₯Ό λ‚˜μ—΄ν•˜κ³  μ½”λ“œλ‘œ 걸음 수λ₯Ό κ³„μ‚°ν•˜μ„Έμš”.

$pathSizes = [];
foreach ($startNodes as $start) {
Β  Β  foreach ($endNodes as $end) {
Β  Β  Β  Β  $path = bfs($start, $end, $tree);
Β  Β  Β  Β  if ($path !== null) {
Β  Β  Β  Β  Β  Β  $pathSizes[] = count($path) - 1;
Β  Β  Β  Β  Β  Β  echo "Path from $start to $end: " . implode(' -> ', $path) . "\n";
Β  Β  Β  Β  }
Β  Β  }
}

λ‹€μŒκ³Ό 같은 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€. (각 경둜의 첫 λ²ˆμ§ΈλŠ” μ‹œμž‘ λ…Έλ“œ κ²½λ‘œλ‹Ή 곡동 λ‹¨κ³„λŠ” μš”μ†Œ 수 -1)

Path from 11A to 11Z: 11A -> 11B -> 11Z
Path from 22A to 22Z: 22A -> 22B -> 22C -> 22Z
Steps per path: [2, 3]
LCM: 6

μ €λŠ” μˆ˜ν•™μ— λŠ₯μˆ™ν•˜μ§€ μ•Šμ§€λ§Œ λͺ¨λ“  κ²½λ‘œκ°€ 같은 μ§€μ μ—μ„œ λλ‚˜λŠ” μ‹œμ μ„ κ³„μ‚°ν•˜λŠ” 방법을 AIμ—κ²Œ λ¬Όμ–΄λ΄€μŠ΅λ‹ˆλ‹€. 그러자 LCM 방법을 μ‚¬μš©ν•  것을 μΆ”μ²œν–ˆμŠ΅λ‹ˆλ‹€. 이 방법은 ν…ŒμŠ€νŠΈ μž…λ ₯κ³Ό κ°œμΈν™”λœ μž…λ ₯에 λŒ€ν•΄ μ‹œκ°„ 간격을 두고 μž‘λ™ν•˜μ§€λ§Œ, LCM은 이에 λŒ€ν•œ 해닡이 μ•„λ‹Œ 것 κ°™μŠ΅λ‹ˆλ‹€.

λ‚΄ μ†”λ£¨μ…˜μ˜ λ¬Έμ œμ μ€ λͺ¨λ“  λ…Έλ“œκ°€ λ™μΌν•œ 수의 단계에 μžˆλŠ” λ…Έλ“œλ₯Ό κ³ λ €ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. λͺ¨λ“  λ…Έλ“œμ˜ λ§ˆμ§€λ§‰ κΈ€μžκ°€ Z인지 μ—¬λΆ€λŠ” κ³ λ €ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 단지 λ…Έλ“œκ°€ 같은 κΈΈμ΄μ—μžˆλŠ” 첫 번째 μž₯μ†Œλ₯Ό μ°Ύκ³  그게 λ‹€μž…λ‹ˆλ‹€.

μ•„λ§ˆλ„ μœ„μ˜ v1 μ½”λ“œλŠ” μ •ν™•ν•œ μˆ«μžμ— 도달 ν•  수 μžˆμ§€λ§Œ 훨씬 더 λΉ λ₯Έ 컴퓨터 λ‚˜ 훨씬 더 λ§Žμ€ μ‹œκ°„μ΄ ν•„μš”ν•  κ²ƒμž…λ‹ˆλ‹€. λ˜λŠ” λ‹€λ₯Έ ν•΄κ²°μ±….

λ‚΄ μ†ŒμŠ€ μ½”λ“œλŠ” λ‹€μŒμ—μ„œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. GitHub.

Reply by Email